customerList.vue 12 KB

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