app-exclusive-coupon-two.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. <template>
  2. <view class="app-exclusive-coupon-two" :style="{'background-color': `${noneColor ? '' : background}`}">
  3. <view class="app-bottom" v-if="coupon_list.length > 0">
  4. <scroll-view scroll-x class="app-scroll dir-left-nowrap">
  5. <view v-for="(item, index) in coupon_list"
  6. :key="index"
  7. class="app-item"
  8. :style="[couponBoxStyle(item,index)]"
  9. >
  10. <app-form-id @click="receive(index)">
  11. <view class="coupon-bg">
  12. <img style="height: 100%;width: 100%" :src="couponBgImg" alt="">
  13. </view>
  14. <view v-if="coupon_list.length === 1" class="dir-left-nowrap" style="height: 100%"
  15. :style="{color: textColor}">
  16. <view style="width: 28%;font-size: 32rpx"
  17. class="app-text-top main-center app-number cross-center"
  18. :class="{discount: item.type === `1`, 'app-symbol' : item.type !== `1`}">
  19. {{item.type === `1` ? item.discount : item.sub_price}}
  20. </view>
  21. <view style="width: 71%;font-size: 20rpx" class="app-text-top main-center cross-center">
  22. 满{{item.min_price}}元可用
  23. </view>
  24. <view style="width: 20%" class="app-text-right main-center cross-center">
  25. <text>
  26. {{item.is_receive == 0 ? receiveTip : item.is_receive > 0 ? '已领取' : ''}}
  27. </text>
  28. </view>
  29. </view>
  30. <view v-else class="dir-left-nowrap" style="height:100%" :style="{color: textColor}">
  31. <view style="text-align: center;width: 75%" class="box-grow-0">
  32. <view style="font-size:32rpx;height: 50%;padding-top: 15rpx"
  33. :class="{discount: item.type === `1`, 'app-symbol' : item.type !== `1`}">
  34. {{item.type === `1` ? item.discount : item.sub_price}}
  35. </view>
  36. <view style="height: 50%;font-size: 20rpx;padding-top: 15rpx">
  37. 满{{item.min_price}}元可用
  38. </view>
  39. </view>
  40. <view class="box-grow-1 app-text-right main-center cross-center">
  41. <text>
  42. {{item.is_receive == 0 ? receiveTip : item.is_receive > 0 ? '已领取' : ''}}
  43. </text>
  44. </view>
  45. </view>
  46. </app-form-id>
  47. </view>
  48. </scroll-view>
  49. </view>
  50. </view>
  51. </template>
  52. <script>
  53. export default {
  54. name: 'app-exclusive-coupon-two',
  55. props: {
  56. receiveBg: {
  57. type: String,
  58. default: function() {
  59. return '';
  60. }
  61. },
  62. list: {
  63. type: Array,
  64. default: function() {
  65. return [];
  66. }
  67. },
  68. textColor: {
  69. type: String,
  70. default: function() {
  71. return "#ffffff";
  72. }
  73. },
  74. unclaimedBg: {
  75. type: String,
  76. default: function() {
  77. return ''
  78. }
  79. },
  80. index: {
  81. type: Number,
  82. },
  83. sign: {
  84. type: String,
  85. },
  86. noneColor: {
  87. type: Boolean,
  88. default() {
  89. return false;
  90. }
  91. },
  92. background: String,
  93. page_id: Number,
  94. template_id: Number,
  95. is_required: Boolean,
  96. coupon_req: Boolean,
  97. couponBg: {
  98. type: String,
  99. default: '#D9BC8B',
  100. },
  101. //diy手动添加优惠券标识
  102. addType: String,
  103. couponBgType: {
  104. type: String,
  105. default() {
  106. return '#pure';
  107. }
  108. },
  109. dIndex: {
  110. type: Array,
  111. default() {
  112. return [0, 0];
  113. }
  114. },
  115. mIndex: {
  116. type: Array,
  117. default() {
  118. return [0, 0];
  119. }
  120. },
  121. dType: String,
  122. },
  123. data() {
  124. return {
  125. coupon_list: []
  126. };
  127. },
  128. computed: {
  129. receiveTip() {
  130. let receiveTip = '立即领取';
  131. if (this.sign === 'integral-mall') {
  132. receiveTip = '立即兑换';
  133. }
  134. return receiveTip;
  135. },
  136. couponBgImg() {
  137. //wechat ../../../
  138. switch (this.coupon_list.length) {
  139. case 1:
  140. return '/static/image/diy/bg_coupon_index_1.png';
  141. case 2:
  142. return '/static/image/diy/bg_coupon_index_2.png';
  143. case 3:
  144. return '/static/image/diy/bg_coupon_index_3.png';
  145. default:
  146. return '/static/image/diy/bg_coupon_index_4.png';
  147. }
  148. },
  149. couponBoxStyle() {
  150. return (data, index) => {
  151. let couponList = this.coupon_list;
  152. let width, background;
  153. let screenWidth = uni.getSystemInfoSync().windowWidth;
  154. let p = 750 / screenWidth;
  155. switch (couponList.length) {
  156. case 1:
  157. width = `${parseInt(702 / p)}px`;
  158. break;
  159. case 2:
  160. width = `${parseInt(341 / p)}px`;
  161. break;
  162. case 3:
  163. width = `${parseInt(220 / p)}px`;
  164. break;
  165. default:
  166. width = `${parseInt(274 / p)}px`;
  167. break;
  168. }
  169. let extra = {'margin-left': `${20 / p}px`};
  170. if (index === 0) extra = Object.assign(extra, {'margin-left': `${24 / p}px`});
  171. if (index === this.coupon_list.length - 1) extra = Object.assign(extra, {'margin-right': `${24 / p}px`});
  172. if (data.is_receive > 0) {
  173. background = '#B4B4B4';
  174. } else if (this.couponBgType === 'gradient') {
  175. background = 'linear-gradient(to left, ' + this.couponBg + ',' + this.$utils.colorRgba(this.couponBg, 0.5) + ')';
  176. } else {
  177. background = this.couponBg;
  178. }
  179. return Object.assign(extra, {
  180. background,
  181. 'width': width,
  182. 'min-width': couponList.length > 3 ? width : 'auto'
  183. });
  184. }
  185. }
  186. },
  187. methods: {
  188. flushCache(coupon_list) {
  189. if (this.page_id == 0) {
  190. let storage = this.$storage.getStorageSync('INDEX_MALL');
  191. let dIndex = this.dIndex;
  192. let mIndex = this.mIndex;
  193. if (this.dType === 'module') {
  194. storage.home_pages.navs[mIndex[0]].template.data[mIndex[1]].data.list[dIndex[0]].data[dIndex[1]].data.coupon_list = coupon_list;
  195. } else {
  196. storage.home_pages.navs[dIndex[0]].template.data[dIndex[1]].data.coupon_list = coupon_list;
  197. }
  198. this.$storage.setStorageSync('INDEX_MALL', storage);
  199. }
  200. },
  201. receive(index) {
  202. let list = this.coupon_list;
  203. if (this.sign == 'integral-mall') {
  204. this.$jump({
  205. url: list[index].page_url,
  206. open_type: 'navigate'
  207. });
  208. return;
  209. }
  210. if (list[index].is_receive == 1) {
  211. uni.showToast({
  212. mask: true,
  213. title: '已领取',
  214. icon: 'none'
  215. });
  216. return true;
  217. }
  218. uni.showLoading({
  219. mask: true,
  220. title: '领取中'
  221. });
  222. this.$request({
  223. url: this.$api.coupon.receive,
  224. data: {
  225. coupon_id: list[index].id
  226. }
  227. }).then(e => {
  228. uni.hideLoading();
  229. if (e.code === 0) {
  230. if (e.data.rest == 0) {
  231. this.coupon_list[index].is_receive = '1';
  232. }
  233. let tempList = this.coupon_list;
  234. this.flushCache(tempList);
  235. this.$store.dispatch('page/actionSetCoupon', {
  236. list: [Object.assign(tempList[index], e.data)],
  237. type: 'receive'
  238. });
  239. } else {
  240. uni.showToast({title: e.msg, icon: 'none'});
  241. }
  242. }).catch(() => {
  243. uni.hideLoading();
  244. });
  245. },
  246. loadData() {
  247. this.$request({
  248. url: this.$api.index.extra,
  249. data: {
  250. type: 'mall',
  251. key: 'coupon',
  252. page_id: this.page_id,
  253. index: this.index
  254. }
  255. }).then(e => {
  256. this.coupon_list = e.data;
  257. if (this.page_id === 0) {
  258. let storage = this.$storage.getStorageSync('INDEX_MALL');
  259. storage.home_pages[this.index].list = this.coupon_list;
  260. this.$storage.setStorageSync('INDEX_MALL', storage);
  261. }
  262. })
  263. }
  264. },
  265. mounted() {
  266. if (!this.coupon_req) {
  267. if (this.is_required) {
  268. this.loadData();
  269. } else {
  270. let storage = this.$storage.getStorageSync('INDEX_MALL');
  271. this.coupon_list = storage.home_pages[this.index].list;
  272. }
  273. } else {
  274. this.coupon_list = this.list;
  275. }
  276. },
  277. }
  278. </script>
  279. <style scoped lang="scss">
  280. .app-exclusive-coupon-two {
  281. width: #{750rpx};
  282. .coupon-bg {
  283. position: absolute;
  284. top: 0;
  285. left: 0;
  286. width: 100%;
  287. height: 100%;
  288. }
  289. .app-bottom {
  290. padding: #{16rpx} 0;
  291. height: #{130+16+16rpx};
  292. width: #{750rpx};
  293. .app-scroll {
  294. height: #{130+16+16rpx};
  295. height: 100%;
  296. del-width: #{750-24rpx};
  297. white-space: nowrap;
  298. }
  299. .app-item {
  300. width: #{256rpx};
  301. position: relative;
  302. height: #{130rpx};
  303. display: inline-block;
  304. margin-left: #{20rpx};
  305. background-repeat: no-repeat;
  306. background-size: 100% 100%;
  307. .app-number.app-symbol:before {
  308. content: '¥';
  309. font-size: #{20rpx};
  310. }
  311. app-number {
  312. font-size: #{40rpx};
  313. }
  314. .discount:after {
  315. content: '折';
  316. font-size: 75%;
  317. }
  318. .app-text-left {
  319. width: 75%;
  320. height: #{130rpx};
  321. .app-text-top {
  322. height: 50%;
  323. padding-top: #{1rpx};
  324. overflow: hidden;
  325. text-align: center;
  326. .app-symbol {
  327. display: inline-block;
  328. height: #{78rpx};
  329. font-size: #{20rpx};
  330. }
  331. .app-number {
  332. display: inline-block;
  333. height: 100%;
  334. }
  335. }
  336. .app-text-bottom {
  337. height: 50%;
  338. text-align: center;
  339. font-size: #{20rpx};
  340. display: block;
  341. }
  342. }
  343. .app-text-right {
  344. width: 25%;
  345. height: #{130rpx};
  346. text {
  347. height: #{130rpx};
  348. display: inline-block;
  349. text-align: center;
  350. line-height: #{50rpx};
  351. font-size: #{24rpx};
  352. writing-mode: vertical-rl;
  353. letter-spacing: #{5rpx};
  354. }
  355. }
  356. }
  357. }
  358. }
  359. </style>