app-coupon-pick.vue 14 KB

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