giftApply.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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">
  15. <view slot="body" class="card-content">
  16. <view class="student-info">
  17. <view style="width: 100%;">
  18. <text class="info-name" style="margin-right: 10px;">{{ site.studentName }}</text>
  19. <text class="info-name">{{ site.venueName }}</text>
  20. </view>
  21. <view class="info-phone">{{ site.className }}</view>
  22. <template v-if="site.giftList.length">
  23. <view class="info-phone" v-for="(iten, index3) in site.giftList" :key="index3">{{ iten.name }}</view>
  24. </template>
  25. <view class="info-phone">{{ getStatus(site.approvalStatus) }}</view>
  26. </view>
  27. </view>
  28. <view slot="foot" style="text-align: right;" v-if="site.giftType == 0 && site.approvalStatus == 2" >
  29. <u-button type="warning" :ripple="true" shape="circle" :custom-style="{...handleCustomStyle, marginRight: '5px'}" size="mini" @click="handleGiveClick(site.id,site.venueId)">赠送</u-button>
  30. <u-button type="warning" :ripple="true" shape="circle" :custom-style="handleCustomStyle" size="mini" @click="handleNoGiveClick(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-popup v-model="giftShow" mode="center" border-radius="30" width="600rpx" height="500px" >
  39. <view class="common-title">礼物</view>
  40. <view class="menber-box" style="overflow-y: auto;height:390px;">
  41. <u-form :model="form" ref="giftForm" label-width="80">
  42. <view style="display:flex;justify-content: space-between;" v-for="(item,index) in formInfo" :key="index">
  43. <u-form-item label="商品" :prop="item.signOne" required right-icon="arrow-right" style="width:44%;" @click.native="handleShowProductClick(index)">
  44. <text>{{ item.signOne }}</text>
  45. </u-form-item>
  46. <u-form-item label="规格" :prop="item.two" required right-icon="arrow-right" style="width:44%;" @click.native="handleShowSpecClick(index)">
  47. <text>{{ item.signTwo }}</text>
  48. </u-form-item>
  49. <u-icon v-if="formInfo.length != 1" name="minus-circle" size="34" @click="handleGiftDelClick(index)"></u-icon>
  50. </view>
  51. <view style="width:100;display:flex;justify-content: flex-end;">
  52. <u-button type="warning" :ripple="true" size="mini" :custom-style="{ backgroundColor: mainColor }" @click="handleGiftAddClick">添加</u-button>
  53. </view>
  54. </u-form>
  55. </view>
  56. <view class="button-box">
  57. <u-button type="warning" shape="circle" :ripple="true" :custom-style="customStyle" @click="handleSubmitClick">确定</u-button>
  58. </view>
  59. </u-popup>
  60. <!-- 商品 -->
  61. <u-picker mode="selector" v-model="productShow" :range="productList" @confirm="handleSetProductClick" title="礼物" range-key="text"></u-picker>
  62. <!-- 规格 -->
  63. <u-picker mode="selector" v-model="specShow" :range="specList" @confirm="handleSetSpecClick" title="规格" range-key="text"></u-picker>
  64. <u-top-tips ref="uTips" z-index="12000"></u-top-tips>
  65. </view>
  66. </template>
  67. <script>
  68. import {
  69. mapGetters
  70. } from 'vuex'
  71. const NET = require('@/utils/request')
  72. const API = require('@/config/api')
  73. export default {
  74. data() {
  75. return {
  76. listId: 0,
  77. venueId: 0,
  78. // filterText: '',
  79. triggered: false,
  80. formInfo: [
  81. {
  82. signOneId: '',
  83. signOne: '',
  84. signTwoId: '',
  85. signTwo: ''
  86. }
  87. ],
  88. tabList: [
  89. {
  90. name: '未赠送',
  91. isOver: false,
  92. pageIndex: 1,
  93. filterText: '',
  94. tableList: [],
  95. }, {
  96. name: '已赠送',
  97. isOver: false,
  98. pageIndex: 1,
  99. filterText: '',
  100. tableList: [],
  101. }, {
  102. name: '不赠送',
  103. isOver: false,
  104. pageIndex: 1,
  105. filterText: '',
  106. tableList: [],
  107. }],
  108. current: 0,
  109. swiperCurrent: 0,
  110. giftIndex: 0,
  111. giftShow: false,
  112. productShow: false,
  113. productList: [],
  114. specShow: false,
  115. specList: [],
  116. }
  117. },
  118. onShow() {
  119. this.getData()
  120. },
  121. computed: {
  122. ...mapGetters([
  123. 'mainColor',
  124. 'customStyle',
  125. 'handleCustomStyle',
  126. 'handleDefaultCustomStyle',
  127. ]),
  128. getStatus() {
  129. return function(index) {
  130. switch (index) {
  131. case 0:
  132. return '待审批'
  133. case 1:
  134. return '审批通过'
  135. case 2:
  136. return '提交'
  137. }
  138. }
  139. }
  140. },
  141. methods: {
  142. getData() {
  143. this.tabList = Object.assign([], this.$options.data().tabList)
  144. this.getTableList(0)
  145. this.getTableList(1)
  146. this.getTableList(2)
  147. },
  148. handleGiveClick(id,venueId) {
  149. this.giftShow = true
  150. this.listId = id
  151. this.venueId = venueId
  152. },
  153. handleShowProductClick(index) {
  154. this.giftIndex = index
  155. NET.request(API.findVenueGiftOneList, {
  156. id: this.venueId
  157. }, 'POST').then(res => {
  158. this.productList = res.data
  159. this.productShow = true
  160. })
  161. },
  162. handleSetProductClick(index) {
  163. this.formInfo[this.giftIndex].signOneId = this.productList[index].id
  164. this.formInfo[this.giftIndex].signOne = this.productList[index].text
  165. },
  166. handleShowSpecClick(index) {
  167. this.giftIndex = index
  168. if(!this.formInfo[this.giftIndex].signOneId) {
  169. this.$refs.uTips.show({
  170. title: '请先选择商品',
  171. type: 'warning',
  172. })
  173. return
  174. }
  175. const giftId = this.formInfo[this.giftIndex].signOneId
  176. const venueId = this.venueId
  177. NET.request(API.findVenueGiftTwoList, {
  178. giftId, venueId
  179. }, 'POST').then(res => {
  180. this.specList = res.data
  181. this.specShow = true
  182. })
  183. },
  184. handleSetSpecClick(index) {
  185. this.formInfo[this.giftIndex].signTwoId = this.specList[index].id
  186. this.formInfo[this.giftIndex].signTwo = this.specList[index].text
  187. },
  188. handleGiftAddClick() {
  189. this.formInfo.push({
  190. signOneId: '',
  191. signOne: '',
  192. signTwoId: '',
  193. signTwo: ''
  194. })
  195. },
  196. handleGiftDelClick(index) {
  197. this.formInfo.splice(index,1)
  198. },
  199. handleSubmitClick() {
  200. let flag = true
  201. this.formInfo.forEach( item => {
  202. if(!item.signOneId) {
  203. this.$refs.uTips.show({
  204. title: '请选择要赠送的礼物',
  205. type: 'warning',
  206. })
  207. flag = false
  208. return
  209. }
  210. if(item.signOneId && !item.signTwoId) {
  211. this.$refs.uTips.show({
  212. title: `请选择商品${item.signOne}的规格`,
  213. type: 'warning',
  214. })
  215. flag = false
  216. return
  217. }
  218. })
  219. if(flag) {
  220. const id = this.listId
  221. const venueId = this.venueId
  222. const giftIds = this.formInfo.filter(item => item.signTwoId != '').map( item => {
  223. return item.signTwoId
  224. })
  225. NET.request(API.giveGiftStudent, {
  226. id, venueId, giftIds
  227. }, 'POST').then(res => {
  228. if(res.status == 10000) {
  229. this.$refs.uTips.show({
  230. title: res.message,
  231. type: 'success',
  232. })
  233. } else {
  234. this.$refs.uTips.show({
  235. title: res.message,
  236. type: 'warning',
  237. })
  238. }
  239. this.getData()
  240. this.giftShow = false
  241. })
  242. }
  243. },
  244. // 不送
  245. handleNoGiveClick(id) {
  246. NET.request(API.giveGiftRefuse, {
  247. id
  248. }, 'POST').then(res => {
  249. if(res.status == 10000) {
  250. this.$refs.uTips.show({
  251. title: res.message,
  252. type: 'success',
  253. })
  254. } else {
  255. this.$refs.uTips.show({
  256. title: res.message,
  257. type: 'warning',
  258. })
  259. }
  260. this.getData()
  261. })
  262. },
  263. // 获取列表数据
  264. getTableList(index) {
  265. NET.request(API.giftStudentPage, {
  266. giftType: index,
  267. name: this.tabList[index].filterText,
  268. page: this.tabList[index].pageIndex,
  269. size: 10,
  270. }, 'POST').then(res => {
  271. this.triggered = false
  272. this.tabList[index].tableList = this.tabList[index].tableList.concat(res.data.row)
  273. this.tabList[index].isOver = res.data.row.length != 10
  274. }).catch(error => {
  275. this.triggered = false
  276. this.$refs.uTips.show({
  277. title: error.msg,
  278. type: 'warning',
  279. })
  280. })
  281. },
  282. // 设置过滤字段
  283. setFilterText(value) {
  284. this.tabList[this.current].filterText = value
  285. this.onRefresh()
  286. },
  287. // tab页面切换
  288. tabsChange(index) {
  289. this.swiperCurrent = index;
  290. },
  291. // swiper-item左右移动,通知tabs的滑块跟随移动
  292. transition(e) {
  293. let dx = e.detail.dx;
  294. this.$refs.uTabs.setDx(dx);
  295. },
  296. // swiper滑动结束,分别设置tabs和swiper的状态
  297. animationfinish(e) {
  298. let current = e.detail.current;
  299. this.$refs.uTabs.setFinishCurrent(current);
  300. this.swiperCurrent = current;
  301. this.current = current;
  302. },
  303. // 下拉刷新
  304. onRefresh() {
  305. if (!this.triggered) {
  306. this.triggered = true
  307. this.tabList[this.current].isOver = false
  308. this.tabList[this.current].pageIndex = 1
  309. this.tabList[this.current].tableList = []
  310. this.getTableList(this.current)
  311. }
  312. },
  313. // 重置下拉刷新状态
  314. onRestore() {
  315. this.triggered = 'restore'
  316. this.triggered = false
  317. },
  318. // 懒加载
  319. handleLoadMore() {
  320. if (!this.tabList[this.current].isOver) {
  321. this.tabList[this.current].pageIndex++
  322. this.getTableList(this.current)
  323. }
  324. }
  325. },
  326. }
  327. </script>
  328. <style>
  329. page {
  330. width: 100%;
  331. height: 100%;
  332. background-color: #f7f7f7;
  333. }
  334. </style>
  335. <style lang="scss" scoped>
  336. @import "@/static/css/themes.scss";
  337. .content {
  338. width: 100%;
  339. float: left;
  340. .filter-box {
  341. height: 48px;
  342. padding: 10px 15px;
  343. background-color: #FFFFFF;
  344. }
  345. .swiper-box {
  346. height: calc(100vh - 82px);
  347. .swiper-item {
  348. height: calc(100vh - 82px);
  349. .scroll-box {
  350. width: 100%;
  351. height: calc(100vh - 82px);
  352. .card-box {
  353. .card-content {
  354. display: flex;
  355. align-items: center;
  356. .student-info {
  357. flex: 1;
  358. .info-name {
  359. // width: 64px;
  360. // float: left;
  361. line-height: 28px;
  362. font-size: 14px;
  363. font-weight: bold;
  364. }
  365. .info-type {
  366. padding: 0 10px;
  367. margin-top: 3px;
  368. border-radius: 20px;
  369. float: left;
  370. line-height: 20px;
  371. font-size: 10px;
  372. color: #FFFFFF;
  373. background-color: #999999;
  374. }
  375. .info-type-active {
  376. background-color: $mainColor;
  377. }
  378. .info-phone {
  379. // float: left;
  380. line-height: 28px;
  381. font-size: 12px;
  382. color: #999999;
  383. }
  384. }
  385. }
  386. }
  387. }
  388. }
  389. }
  390. }
  391. .menber-box {
  392. width: 100%;
  393. // float: left;
  394. padding: 10px 15px;
  395. margin-bottom: 10px;
  396. .menber-col {
  397. width: 100%;
  398. padding: 15px;
  399. margin-bottom: 10px;
  400. display: inline-block;
  401. background-color: #FFFFFF;
  402. border-radius: 15px;
  403. box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);
  404. position: relative;
  405. overflow: hidden;
  406. box-sizing: border-box;
  407. .menber-label {
  408. width: 100%;
  409. margin-bottom: 5px;
  410. float: left;
  411. font-size: 14px;
  412. // line-height: 20px;
  413. }
  414. .menber-num {
  415. width: 100%;
  416. float: left;
  417. font-size: 26px;
  418. line-height: 28px;
  419. color: $mainColor;
  420. }
  421. .menber-icon {
  422. font-size: 100px;
  423. color: $mainColor;
  424. position: absolute;
  425. right: -5px;
  426. bottom: -30px;
  427. opacity: 0.5;
  428. }
  429. }
  430. }
  431. .common-title {
  432. width:100%;
  433. text-align: center;
  434. font-size: 20px;
  435. margin: 10px 0;
  436. }
  437. .fix-add-icon {
  438. position: fixed;
  439. bottom: 15px;
  440. right: 15px;
  441. }
  442. .button-box {
  443. // width: 100%;
  444. padding: 10px 15px;
  445. box-sizing: border-box;
  446. }
  447. </style>