customerList.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. <template>
  2. <view class="content">
  3. <view class="filter-box">
  4. <u-search placeholder="请输入关键字" v-model="filterText" @search="setFilterText" @custom="setFilterText"></u-search>
  5. </view>
  6. <u-tabs-swiper ref="uTabs" :active-color="mainColor" :list="tabList" :current="current" @change="tabsChange"
  7. :is-scroll="false"></u-tabs-swiper>
  8. <swiper :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish" class="swiper-box">
  9. <swiper-item class="swiper-item" v-for="(item, index1) in tabList" :key="index1">
  10. <scroll-view scroll-y class="scroll-box" @scrolltolower="handleLoadMore" :refresher-enabled="true"
  11. :refresher-triggered="triggered" :refresher-threshold="100" refresher-background="white" @refresherrefresh="onRefresh"
  12. @refresherrestore="onRestore">
  13. <u-card :show-head="false" :foot-border-top="false" margin="10px 15px" borderRadius="40" :foot-style="{padding: '0 10px 5px 0'}" v-for="(site, index2) in item.tableList"
  14. :key="index2" class="card-box" @click="goToOrderList(site)">
  15. <view slot="body" class="card-content">
  16. <view class="student-info">
  17. <view class="info-name">{{site.studentName}}</view>
  18. <!-- <view class="info-type" :class="site.status == 1 ? 'info-type-active' : ''">{{site.status == 0 ? '未报名' : '已报名'}}</view> -->
  19. <view class="info-name" style="width:100px;">{{site.parentName}}</view>
  20. <view class="info-phone">{{site.parentPhone}}</view>
  21. </view>
  22. <!-- <u-image width="28px" height="28px" :src="site.type == 2 ? iconPath1 : iconPath2"></u-image> -->
  23. </view>
  24. <view class="venue-content" slot="foot" style="text-align: right;">
  25. <u-button style="margin-right:10px" type="warning" :ripple="true" shape="circle" :custom-style="handleCustomStyle" size="mini" @click="checkContract(site.id)">查看合同</u-button>
  26. <u-button v-if="current != 2" type="warning" :ripple="true" shape="circle" :custom-style="handleCustomStyle" size="mini" @click="handleInvalidClick(site.id,0)">无效</u-button>
  27. <u-button v-else type="warning" :ripple="true" shape="circle" :custom-style="handleCustomStyle" size="mini" @click="handleInvalidClick(site.id,1)">有效</u-button>
  28. </view>
  29. <!--<view class="venue-content" slot="foot" style="text-align: right;" v-else>
  30. <u-button type="warning" :ripple="true" shape="circle" :custom-style="handleCustomStyle" size="mini" @click="handleInvalidClick(site.id)">查看合同</u-button>
  31. </view>-->
  32. </u-card>
  33. <u-divider v-if="item.isOver" bg-color="transparent" :style="{paddingTop : item.tableList.length == 0 ? '10px' : ''}">没有更多了</u-divider>
  34. </scroll-view>
  35. </swiper-item>
  36. </swiper>
  37. <!-- 新增客户 -->
  38. <u-icon name="plus-circle-fill" :color="mainColor" size="96" class="fix-add-icon" @click="handleAddApplyClick"></u-icon>
  39. <!-- 无效备注 -->
  40. <u-popup v-model="invalidShow" mode="center" border-radius="30" width="600rpx">
  41. <view class="common-title">备注</view>
  42. <view class="menber-box">
  43. <u-form :model="invalidForm" ref="invalidFormRef" label-width="140">
  44. <u-form-item label="备注" prop="content" required>
  45. <u-input v-model="invalidForm.content" type="text" />
  46. </u-form-item>
  47. </u-form>
  48. <view style="height:20px;"></view>
  49. <u-button type="warning" shape="circle" :ripple="true" :custom-style="customStyle" @click="handleConfirmClick">确定</u-button>
  50. </view>
  51. </u-popup>
  52. <u-popup v-model="contractShow" mode="center" border-radius="30" width="600rpx" height="500px">
  53. <view class="common-title">合同列表</view>
  54. <view class="menber-box" style="overflow-y: auto;height:390px;">
  55. <template v-for="(item, index) in contractUrls">
  56. <div v-if="item.payTime!=null">
  57. <view class="orderNumber">
  58. {{item.orderNumber}}
  59. </view>
  60. <view class="card-item" :key="index0" @click="handleContractShowClick(item0)" v-for="(item0, index0) in item.url">
  61. {{ item0.name }}
  62. </view>
  63. </div>
  64. </template>
  65. </view>
  66. <view class="button-box">
  67. <u-button type="warning" shape="circle" :ripple="true" :custom-style="customStyle" @click="contractShow = false">确定</u-button>
  68. </view>
  69. </u-popup>
  70. <u-top-tips ref="uTips"></u-top-tips>
  71. </view>
  72. </template>
  73. <script>
  74. import {
  75. mapGetters
  76. } from 'vuex'
  77. const NET = require('@/utils/request')
  78. const API = require('@/config/api')
  79. export default {
  80. computed: {
  81. ...mapGetters([
  82. 'mainColor',
  83. 'customStyle',
  84. 'handleCustomStyle',
  85. 'handleDefaultCustomStyle',
  86. ])
  87. },
  88. data() {
  89. return {
  90. contractShow:false,
  91. contractUrls:[
  92. ],
  93. filterText: '',
  94. triggered: false,
  95. tabList: [
  96. {
  97. name: '已报名',
  98. isOver: false,
  99. pageIndex: 1,
  100. filterText: '',
  101. type: 1,
  102. tableList: [],
  103. }, {
  104. name: '已续费',
  105. isOver: false,
  106. pageIndex: 1,
  107. filterText: '',
  108. type: 2,
  109. tableList: [],
  110. }, {
  111. name: '无效',
  112. isOver: false,
  113. pageIndex: 1,
  114. filterText: '',
  115. type: 0,
  116. tableList: [],
  117. }],
  118. current: 0,
  119. swiperCurrent: 0,
  120. iconPath1: API.getServerImg + 'weibaoming.png',
  121. iconPath2: API.getServerImg + 'xianshangkehu.png',
  122. // 无效备注
  123. invalidShow: false,
  124. // 备注
  125. invalidForm: {
  126. customerId: null,
  127. content: '',
  128. joinState: 0
  129. },
  130. // 备注校验规则
  131. invalidRules: {
  132. content: [
  133. {
  134. required: true,
  135. message: '请输入备注',
  136. trigger: 'change'
  137. }],
  138. }
  139. }
  140. },
  141. onShow() {
  142. this.tabList = Object.assign([], this.$options.data().tabList)
  143. this.getTableList(0)
  144. this.getTableList(1)
  145. this.getTableList(2)
  146. },
  147. onReady() {},
  148. methods: {
  149. // 跳转添加信息
  150. handleAddApplyClick() {
  151. uni.navigateTo({
  152. url: '/pagesEnroll/enrolledForm'
  153. });
  154. },
  155. // 备注弹窗显示
  156. handleInvalidClick(id,type) {
  157. this.invalidForm.joinState=type
  158. this.invalidForm.customerId = id
  159. this.$refs.invalidFormRef.setRules(this.invalidRules)
  160. this.invalidShow = true
  161. },
  162. // 无效备注确认
  163. handleConfirmClick(){
  164. this.$refs.invalidFormRef.validate(valid => {
  165. if (valid) {
  166. NET.request(API.updateCustomerState, {...this.invalidForm}, 'POST').then(res => {
  167. if(res.status == 10000) {
  168. this.invalidShow = false
  169. this.tabList = this.$options.data().tabList
  170. this.getTableList(0)
  171. this.getTableList(1)
  172. this.getTableList(2)
  173. } else {
  174. this.invalidShow = false
  175. this.$refs.uTips.show({
  176. title: error.msg,
  177. type: 'warning',
  178. })
  179. }
  180. })
  181. }
  182. })
  183. },
  184. // 设置过滤字段
  185. setFilterText(value) {
  186. this.tabList[this.current].filterText = value
  187. this.onRefresh()
  188. },
  189. // tab页面切换
  190. tabsChange(index) {
  191. this.swiperCurrent = index;
  192. },
  193. // swiper-item左右移动,通知tabs的滑块跟随移动
  194. transition(e) {
  195. let dx = e.detail.dx;
  196. this.$refs.uTabs.setDx(dx);
  197. },
  198. // swiper滑动结束,分别设置tabs和swiper的状态
  199. animationfinish(e) {
  200. let current = e.detail.current;
  201. this.$refs.uTabs.setFinishCurrent(current);
  202. this.swiperCurrent = current;
  203. this.current = current;
  204. },
  205. // 下拉刷新
  206. onRefresh() {
  207. if (!this.triggered) {
  208. this.triggered = true
  209. this.tabList[this.current].isOver = false
  210. this.tabList[this.current].pageIndex = 1
  211. this.tabList[this.current].tableList = []
  212. this.getTableList(this.current, 'refresh')
  213. }
  214. },
  215. // 重置下拉刷新状态
  216. onRestore() {
  217. this.triggered = 'restore'
  218. this.triggered = false
  219. },
  220. // 懒加载
  221. handleLoadMore() {
  222. if (!this.tabList[this.current].isOver) {
  223. this.tabList[this.current].pageIndex++
  224. this.getTableList(this.current)
  225. }
  226. },
  227. // 获取列表数据
  228. getTableList(index) {
  229. NET.request(API.getCustomerList, {
  230. isSignUp: 0,
  231. name: this.tabList[index].filterText,
  232. type: this.tabList[index].type,
  233. page: this.tabList[index].pageIndex,
  234. saleIsMeFlag: true,
  235. size: 10,
  236. }, 'POST').then(res => {
  237. this.triggered = false
  238. this.tabList[index].tableList = this.tabList[index].tableList.concat(res.data.row)
  239. this.tabList[index].isOver = res.data.row.length != 10
  240. }).catch(error => {
  241. this.triggered = false
  242. this.$refs.uTips.show({
  243. title: error.msg,
  244. type: 'warning',
  245. })
  246. })
  247. NET.request(API.getOrderContract, {
  248. customerId: 23185
  249. }, 'GET').then(res => {
  250. }).catch(error => {
  251. this.triggered = false
  252. this.$refs.uTips.show({
  253. title: error.msg,
  254. type: 'warning',
  255. })
  256. })
  257. },
  258. // 跳转到报名详情
  259. goToOrderList(item) {
  260. uni.navigateTo({
  261. url: `/pagesMain/customerInfo?id=${item.id}&title=客户信息`
  262. })
  263. },
  264. checkContract(id) {
  265. this.contractShow = true
  266. this.contractUrls = []
  267. NET.request(API.getOrderContract, {
  268. customerId: id
  269. }, 'GET').then(res => {
  270. this.contractUrls = res.data
  271. }).catch(error => {
  272. this.triggered = false
  273. this.$refs.uTips.show({
  274. title: error.msg,
  275. type: 'warning',
  276. })
  277. })
  278. },
  279. // 查看合同
  280. handleContractShowClick(item) {
  281. console.log(item);
  282. uni.downloadFile({
  283. url: item.url,
  284. success: (res) => {
  285. console.log(res);
  286. uni.openDocument({
  287. filePath: res.tempFilePath,
  288. });
  289. }
  290. })
  291. },
  292. },
  293. }
  294. </script>
  295. <style>
  296. page {
  297. width: 100%;
  298. height: 100%;
  299. background-color: #f7f7f7;
  300. }
  301. </style>
  302. <style lang="scss" scoped>
  303. @import "@/static/css/themes.scss";
  304. .content {
  305. width: 100%;
  306. float: left;
  307. .filter-box {
  308. height: 48px;
  309. padding: 10px 15px;
  310. background-color: #FFFFFF;
  311. }
  312. .swiper-box {
  313. height: calc(100vh - 82px);
  314. .swiper-item {
  315. height: calc(100vh - 82px);
  316. .scroll-box {
  317. width: 100%;
  318. height: calc(100vh - 82px);
  319. .card-box {
  320. .card-content {
  321. display: flex;
  322. align-items: center;
  323. .student-info {
  324. flex: 1;
  325. .info-name {
  326. width: 64px;
  327. float: left;
  328. line-height: 28px;
  329. font-size: 14px;
  330. font-weight: bold;
  331. }
  332. .info-type {
  333. padding: 0 10px;
  334. margin-top: 3px;
  335. border-radius: 20px;
  336. float: left;
  337. line-height: 20px;
  338. font-size: 10px;
  339. color: #FFFFFF;
  340. background-color: #999999;
  341. }
  342. .info-type-active {
  343. background-color: $mainColor;
  344. }
  345. .info-phone {
  346. width: calc(100% - 64px);
  347. float: left;
  348. line-height: 28px;
  349. font-size: 12px;
  350. color: #999999;
  351. }
  352. }
  353. }
  354. }
  355. }
  356. }
  357. }
  358. }
  359. .menber-box {
  360. width: 100%;
  361. // float: left;
  362. padding: 10px 15px;
  363. margin-bottom: 10px;
  364. .menber-col {
  365. width: 100%;
  366. padding: 15px;
  367. margin-bottom: 10px;
  368. display: inline-block;
  369. background-color: #FFFFFF;
  370. border-radius: 15px;
  371. box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);
  372. position: relative;
  373. overflow: hidden;
  374. box-sizing: border-box;
  375. .menber-label {
  376. width: 100%;
  377. margin-bottom: 5px;
  378. float: left;
  379. font-size: 14px;
  380. // line-height: 20px;
  381. }
  382. .menber-num {
  383. width: 100%;
  384. float: left;
  385. font-size: 26px;
  386. line-height: 28px;
  387. color: $mainColor;
  388. }
  389. .menber-icon {
  390. font-size: 100px;
  391. color: $mainColor;
  392. position: absolute;
  393. right: -5px;
  394. bottom: -30px;
  395. opacity: 0.5;
  396. }
  397. }
  398. }
  399. .common-title {
  400. width:100%;
  401. text-align: center;
  402. font-size: 20px;
  403. margin: 10px 0;
  404. }
  405. .fix-add-icon {
  406. position: fixed;
  407. bottom: 15px;
  408. right: 15px;
  409. z-index: 10;
  410. }
  411. .menber-box {
  412. width: 100%;
  413. padding: 10px 15px;
  414. .menber-col {
  415. width: 100%;
  416. padding: 15px;
  417. display: inline-block;
  418. background-color: #FFFFFF;
  419. border-radius: 15px;
  420. box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);
  421. position: relative;
  422. overflow: hidden;
  423. box-sizing: border-box;
  424. .menber-label {
  425. width: 100%;
  426. font-size: 14px;
  427. // line-height: 20px;
  428. }
  429. .menber-num {
  430. width: 100%;
  431. font-size: 26px;
  432. line-height: 28px;
  433. color: $mainColor;
  434. }
  435. }
  436. }
  437. .common-title {
  438. width:100%;
  439. text-align: center;
  440. font-size: 20px;
  441. padding: 10px 0;
  442. }
  443. .card-item {
  444. width: 100%;
  445. padding:8px;
  446. border-radius: 10px;
  447. background-color: #ff6e3e;
  448. margin-bottom: 8px;
  449. color: #fff;
  450. }
  451. .orderNumber{
  452. margin-bottom: 6px;
  453. }
  454. </style>