app-coupon-pick.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <view class="app-coupon-pick">
  3. <view class="coupon-tab dir-left-nowrap cross-center" @touchmove.stop="true">
  4. <view @click="couponType=1"
  5. class="box-grow-1"
  6. :style="{'color': couponType==1 && !is_gift ? theme.background : ''}"
  7. :class="couponType==1 && is_gift ? theme + '-color ' + theme : ''">可用优惠券
  8. <template v-if="list">({{list.length}})</template>
  9. <view class="active-block"
  10. :style="{'background-color': is_gift ? '' : theme.background,'display': couponType==1 ? 'block':'none'}"
  11. :class="is_gift ? theme + '-background ' + theme : ''"></view>
  12. </view>
  13. <view class="box-grow-0 split"></view>
  14. <view @click="couponType=0"
  15. class="box-grow-1"
  16. :style="{'color': couponType==0 && !is_gift ? theme.background : ''}"
  17. :class="couponType==0 && is_gift ? theme + '-color ' + theme : ''">不可用优惠券
  18. <template v-if="cantUseList">({{cantUseList.length}})</template>
  19. <view class="active-block"
  20. :style="{'background-color': is_gift ? '' : theme.background,'display': couponType==0 ? 'block':'none'}"
  21. :class="is_gift ? theme + '-background ' + theme : ''"></view>
  22. </view>
  23. </view>
  24. <scroll-view scroll-y="true" class="list-scroll">
  25. <view class="coupon-list" v-if="couponType == 1">
  26. <view v-if="list === null" style="padding: 50rpx; text-align: center; color: #999;">加载中</view>
  27. <template v-else>
  28. <view v-if="!list.length" style="padding: 128rpx; text-align: center;">
  29. <image src="/static/image/no-goods.png"
  30. style="width: 240rpx;height: 240rpx;margin-bottom: 36rpx;"></image>
  31. <view style="color: #999999;">暂无可用优惠券</view>
  32. </view>
  33. <template v-else>
  34. <view v-for="(item,index) in list"
  35. :key="index"
  36. class="item">
  37. <view class="dir-left-nowrap cross-center top"
  38. :style="{
  39. backgroundImage: `url(${appImg.order_submit.coupon_bg})`,
  40. }">
  41. <view class="box-grow-0 mr-32">
  42. <view v-if="item.type==1" class="dir-left-nowrap cross-bottom">
  43. <view style="font-size: 72rpx;line-height: 1;">{{item.discount}}</view>
  44. <view style="line-height: 1.75">折</view>
  45. </view>
  46. <view v-else class="dir-left-nowrap cross-bottom">
  47. <view style="line-height: 1.75">¥</view>
  48. <view style="font-size: 72rpx;line-height: 1;">{{item.sub_price}}</view>
  49. </view>
  50. </view>
  51. <view class="box-grow-1" style="font-size: 24rpx;">
  52. <view class="desc-row">{{item.coupon_data.name}}</view>
  53. <view class="desc-row">满{{item.coupon_min_price}}元可用</view>
  54. <view v-if="item.discount_limit" class="desc-row">
  55. 优惠上限:¥{{item.discount_limit}}
  56. </view>
  57. </view>
  58. <app-submit-checkbox
  59. :round="true"
  60. v-model="item.checked"
  61. :theme="theme"
  62. border-color="#999999"
  63. @input="handleCouponChange"
  64. :sign="index"></app-submit-checkbox>
  65. </view>
  66. <view class="bottom">
  67. <view style="margin-bottom: 12rpx;">有效日期:{{item.start_time}}-{{item.end_time}}</view>
  68. <view>适用范围:{{item.coupon_data.appoint_type == 3 ? '全场通用' : item.coupon_data.appoint_type == 5?'礼品卡' : '限品类'}}</view>
  69. </view>
  70. </view>
  71. </template>
  72. </template>
  73. </view>
  74. <view class="coupon-list" v-else>
  75. <view v-if="cantUseList === null" style="padding: 50rpx; text-align: center; color: #999;">加载中</view>
  76. <template v-else>
  77. <view v-if="!cantUseList.length" style="padding-top: 128rpx; text-align: center;">
  78. <image src="/static/image/no-goods.png"
  79. style="width: 240rpx;height: 240rpx;margin-bottom: 36rpx;"></image>
  80. <view style="color: #999999;">暂无不可用优惠券</view>
  81. </view>
  82. <template v-else>
  83. <view v-for="(item,index) in cantUseList"
  84. :key="index"
  85. class="item">
  86. <view class="dir-left-nowrap cross-center top"
  87. :style="{
  88. backgroundImage: `url(${appImg.order_submit.coupon_bg_disable})`,
  89. }">
  90. <view class="box-grow-0 mr-32">
  91. <view v-if="item.type==1" class="dir-left-nowrap cross-bottom">
  92. <view style="font-size: 72rpx;line-height: 1;">{{item.discount}}</view>
  93. <view style="line-height: 1.75">折</view>
  94. </view>
  95. <view v-else class="dir-left-nowrap cross-bottom">
  96. <view style="line-height: 1.75">¥</view>
  97. <view style="font-size: 72rpx;line-height: 1;">{{item.sub_price}}</view>
  98. </view>
  99. </view>
  100. <view class="box-grow-1" style="font-size: 24rpx;">
  101. <view class="desc-row">{{item.coupon_data.name}}</view>
  102. <view class="desc-row">满{{item.coupon_min_price}}元可用</view>
  103. <view v-if="item.discount_limit" class="desc-row">
  104. 优惠上限:¥{{item.discount_limit}}
  105. </view>
  106. </view>
  107. </view>
  108. <view class="bottom">
  109. <view style="margin-bottom: 12rpx;">有效日期:{{item.start_time}}-{{item.end_time}}</view>
  110. <view>适用范围:{{item.coupon_data.appoint_type == 3 ? '全场通用' : '限品类'}}</view>
  111. </view>
  112. </view>
  113. </template>
  114. </template>
  115. </view>
  116. </scroll-view>
  117. </view>
  118. </template>
  119. <script>
  120. import {mapState} from 'vuex';
  121. import AppSubmitCheckbox from "./app-submit-checkbox.vue";
  122. export default {
  123. name: "app-coupon-pick",
  124. components: {
  125. AppSubmitCheckbox
  126. },
  127. props: {
  128. theme: {
  129. type: [String,Object],
  130. },
  131. plugin: String,
  132. mchIndex: {
  133. type: Number,
  134. default: 0
  135. },
  136. noCoupons: {
  137. type: Boolean,
  138. default: false
  139. },
  140. },
  141. data() {
  142. return {
  143. couponType: 1,
  144. loading: false,
  145. list: null,
  146. is_gift: false,
  147. cantUseList: null
  148. }
  149. },
  150. computed: {
  151. ...mapState({
  152. appImg: state => state.mallConfig.__wxapp_img
  153. }),
  154. },
  155. created() {
  156. this.$store.commit('orderSubmit/mutSetMchNoCouponStatusList', []);
  157. this.is_gift = typeof(this.theme) == 'string' && this.theme.indexOf('gift') >= 0 ? true : false;
  158. this.loadData();
  159. this.loadData(true);
  160. },
  161. methods: {
  162. loadData(loadCantUse = false) {
  163. this.loading = true;
  164. this.$request({
  165. url: this.$api.order.usable_coupon_list,
  166. method: 'post',
  167. data: {
  168. form_data: JSON.stringify(this.$store.state.orderSubmit.formData.list[this.mchIndex]),
  169. is_cant_use_list: loadCantUse ? 1 : 0,
  170. sign: this.plugin
  171. }
  172. }).then(response => {
  173. this.loading = false;
  174. if (response.code === 0) {
  175. if (loadCantUse) {
  176. this.cantUseList = response.data.list;
  177. } else {
  178. for (let i in response.data.list) {
  179. response.data.list[i].checked = false;
  180. }
  181. this.list = response.data.list;
  182. const mchNoCouponStatusList = this.$store.getters['orderSubmit/getMchNoCouponStatusList'];
  183. let noCoupons = this.$validation.isEmpty(this.list);
  184. this.$emit('update:noCoupons', noCoupons);
  185. mchNoCouponStatusList[this.mchIndex] = noCoupons;
  186. this.$store.commit('orderSubmit/mutSetMchNoCouponStatusList', mchNoCouponStatusList);
  187. }
  188. } else {
  189. }
  190. }).catch(() => {
  191. this.loading = false;
  192. });
  193. },
  194. handleCouponChange({v, index}) {
  195. if (v) {
  196. this.setData(this.list[index].id, index);
  197. } else {
  198. this.setData(0, index);
  199. }
  200. },
  201. setData(data, index) {
  202. if (parseInt(data) === 0) {
  203. this.list[index].checked = false;
  204. } else {
  205. for (let i in this.list) {
  206. this.list[i].checked = parseInt(index) === parseInt(i);
  207. }
  208. }
  209. const formData = this.$store.state.orderSubmit.formData;
  210. formData.list[this.mchIndex].user_coupon_id = data;
  211. this.$store.commit('orderSubmit/mutSetFormData', formData);
  212. this.$emit('change');
  213. },
  214. },
  215. }
  216. </script>
  217. <style scoped lang="scss">
  218. .app-coupon-pick {
  219. .mr-32 {
  220. margin-right: #{32rpx};
  221. }
  222. .btn {
  223. height: #{56rpx};
  224. line-height: #{56rpx};
  225. padding: 0 #{32rpx};
  226. border-radius: #{1000rpx};
  227. background: #fff;
  228. text-align: center;
  229. border: #{1rpx} solid;
  230. }
  231. .btn:active {
  232. box-shadow: 0 0 #{100rpx} rgba(0, 0, 0, 0.05) inset;
  233. }
  234. .btn.use {
  235. color: #c5a977;
  236. border-color: transparent;
  237. }
  238. .btn.dont-use {
  239. height: #{80rpx};
  240. line-height: #{80rpx};
  241. }
  242. .coupon-tab {
  243. > view {
  244. text-align: center;
  245. padding: #{32rpx};
  246. position: relative;
  247. }
  248. .active {
  249. }
  250. .active-block {
  251. position: absolute;
  252. bottom: 0;
  253. left: 50%;
  254. height: #{4rpx};
  255. width: #{110rpx};
  256. margin-left: -#{60rpx};
  257. display: none;
  258. }
  259. .active {
  260. .active-block {
  261. display: block;
  262. }
  263. }
  264. .split {
  265. width: #{1rpx};
  266. height: #{28rpx};
  267. background: #ddd;
  268. padding: 0;
  269. }
  270. border-bottom: #{1rpx} solid #ddd;
  271. }
  272. .list-scroll {
  273. overflow: hidden;
  274. background: #f7f7f7;
  275. height: #{913rpx};
  276. }
  277. .coupon-list {
  278. box-sizing: border-box;
  279. padding: #{32rpx};
  280. .item {
  281. margin: #{32rpx} 0;
  282. background: #fff;
  283. border-radius: #{16rpx};
  284. box-shadow: 0 0 #{10rpx} rgba(0, 0, 0, .05);
  285. overflow: hidden;
  286. .top {
  287. padding: #{40rpx} #{24rpx};
  288. color: #fff;
  289. background-size: 100% 100%;
  290. .desc-row {
  291. margin: #{6rpx} 0;
  292. overflow: hidden;
  293. text-overflow: ellipsis;
  294. white-space: nowrap;
  295. }
  296. }
  297. .bottom {
  298. padding: #{24rpx} #{24rpx};
  299. font-size: #{24rpx};
  300. }
  301. }
  302. }
  303. }
  304. </style>