app-exclusive-coupon-two.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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. <div class="coupon-bg">
  12. <img style="height: 100%;width: 100%" :src="couponBgImg" alt="">
  13. </div>
  14. <div 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. </div>
  30. <div v-else class="dir-left-nowrap" style="height:100%" :style="{color: textColor}">
  31. <div style="text-align: center;width: 75%" class="box-grow-0">
  32. <div 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. </div>
  36. <div style="height: 50%;font-size: 20rpx;padding-top: 15rpx">
  37. 满{{item.min_price}}元可用
  38. </div>
  39. </div>
  40. <div 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. </div>
  45. </div>
  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. switch (this.coupon_list.length) {
  138. case 1:
  139. return '../../../static/image/diy/bg_coupon_index_1.png';
  140. case 2:
  141. return '../../../static/image/diy/bg_coupon_index_2.png';
  142. case 3:
  143. return '../../../static/image/diy/bg_coupon_index_3.png';
  144. default:
  145. return '../../../static/image/diy/bg_coupon_index_4.png';
  146. }
  147. },
  148. couponBoxStyle() {
  149. return (data, index) => {
  150. let couponList = this.coupon_list;
  151. let width, background;
  152. let screenWidth = uni.getSystemInfoSync().windowWidth;
  153. let p = 750 / screenWidth;
  154. switch (couponList.length) {
  155. case 1:
  156. width = `${parseInt(702 / p)}px`;
  157. break;
  158. case 2:
  159. width = `${parseInt(341 / p)}px`;
  160. break;
  161. case 3:
  162. width = `${parseInt(220 / p)}px`;
  163. break;
  164. default:
  165. width = `${parseInt(274 / p)}px`;
  166. break;
  167. }
  168. let extra = {'margin-left': `${20 / p}px`};
  169. if (index === 0) extra = Object.assign(extra, {'margin-left': `${24 / p}px`});
  170. if (index === this.coupon_list.length - 1) extra = Object.assign(extra, {'margin-right': `${24 / p}px`});
  171. if (data.is_receive > 0) {
  172. background = '#B4B4B4';
  173. } else if (this.couponBgType === 'gradient') {
  174. background = 'linear-gradient(to left, ' + this.couponBg + ',' + this.$utils.colorRgba(this.couponBg, 0.5) + ')';
  175. } else {
  176. background = this.couponBg;
  177. }
  178. return Object.assign(extra, {
  179. background,
  180. 'width': width,
  181. 'min-width': couponList.length > 3 ? width : 'auto'
  182. });
  183. }
  184. }
  185. },
  186. methods: {
  187. flushCache(coupon_list) {
  188. if (this.page_id == 0) {
  189. let storage = this.$storage.getStorageSync('INDEX_MALL');
  190. let dIndex = this.dIndex;
  191. let mIndex = this.mIndex;
  192. if (this.dType === 'module') {
  193. storage.home_pages.navs[mIndex[0]].template.data[mIndex[1]].data.list[dIndex[0]].data[dIndex[1]].data.coupon_list = coupon_list;
  194. } else {
  195. storage.home_pages.navs[dIndex[0]].template.data[dIndex[1]].data.coupon_list = coupon_list;
  196. }
  197. this.$storage.setStorageSync('INDEX_MALL', storage);
  198. }
  199. },
  200. receive(index) {
  201. let list = this.coupon_list;
  202. if (this.sign == 'integral-mall') {
  203. this.$jump({
  204. url: list[index].page_url,
  205. open_type: 'navigate'
  206. });
  207. return;
  208. }
  209. if (list[index].is_receive == 1) {
  210. uni.showToast({
  211. mask: true,
  212. title: '已领取',
  213. icon: 'none'
  214. });
  215. return true;
  216. }
  217. uni.showLoading({
  218. mask: true,
  219. title: '领取中'
  220. });
  221. this.$request({
  222. url: this.$api.coupon.receive,
  223. data: {
  224. coupon_id: list[index].id
  225. }
  226. }).then(e => {
  227. uni.hideLoading();
  228. if (e.code === 0) {
  229. if (e.data.rest == 0) {
  230. this.coupon_list[index].is_receive = '1';
  231. }
  232. let tempList = this.coupon_list;
  233. this.flushCache(tempList);
  234. this.$store.dispatch('page/actionSetCoupon', {
  235. list: [Object.assign(tempList[index], e.data)],
  236. type: 'receive'
  237. });
  238. } else {
  239. uni.showToast({title: e.msg, icon: 'none'});
  240. }
  241. }).catch(() => {
  242. uni.hideLoading();
  243. });
  244. },
  245. loadData() {
  246. this.$request({
  247. url: this.$api.index.extra,
  248. data: {
  249. type: 'mall',
  250. key: 'coupon',
  251. page_id: this.page_id,
  252. index: this.index
  253. }
  254. }).then(e => {
  255. this.coupon_list = e.data;
  256. if (this.page_id === 0) {
  257. let storage = this.$storage.getStorageSync('INDEX_MALL');
  258. storage.home_pages[this.index].list = this.coupon_list;
  259. this.$storage.setStorageSync('INDEX_MALL', storage);
  260. }
  261. })
  262. }
  263. },
  264. mounted() {
  265. if (!this.coupon_req) {
  266. if (this.is_required) {
  267. this.loadData();
  268. } else {
  269. let storage = this.$storage.getStorageSync('INDEX_MALL');
  270. this.coupon_list = storage.home_pages[this.index].list;
  271. }
  272. } else {
  273. this.coupon_list = this.list;
  274. }
  275. },
  276. }
  277. </script>
  278. <style scoped lang="scss">
  279. .app-exclusive-coupon-two {
  280. width: #{750rpx};
  281. .coupon-bg {
  282. position: absolute;
  283. top: 0;
  284. left: 0;
  285. width: 100%;
  286. height: 100%;
  287. }
  288. .app-bottom {
  289. padding: #{16rpx} 0;
  290. height: #{130+16+16rpx};
  291. width: #{750rpx};
  292. .app-scroll {
  293. height: #{130+16+16rpx};
  294. height: 100%;
  295. del-width: #{750-24rpx};
  296. white-space: nowrap;
  297. }
  298. .app-item {
  299. width: #{256rpx};
  300. position: relative;
  301. height: #{130rpx};
  302. display: inline-block;
  303. margin-left: #{20rpx};
  304. background-repeat: no-repeat;
  305. background-size: 100% 100%;
  306. > view {
  307. width: #{256rpx};
  308. height: #{130rpx};
  309. }
  310. .app-number.app-symbol:before {
  311. content: '¥';
  312. font-size: #{20rpx};
  313. }
  314. app-number {
  315. font-size: #{40rpx};
  316. }
  317. .discount:after {
  318. content: '折';
  319. font-size: 75%;
  320. }
  321. .app-text-left {
  322. width: 75%;
  323. height: #{130rpx};
  324. .app-text-top {
  325. height: 50%;
  326. padding-top: #{1rpx};
  327. overflow: hidden;
  328. text-align: center;
  329. .app-symbol {
  330. display: inline-block;
  331. height: #{78rpx};
  332. font-size: #{20rpx};
  333. }
  334. .app-number {
  335. display: inline-block;
  336. height: 100%;
  337. }
  338. }
  339. .app-text-bottom {
  340. height: 50%;
  341. text-align: center;
  342. font-size: #{20rpx};
  343. display: block;
  344. }
  345. }
  346. .app-text-right {
  347. width: 25%;
  348. height: #{130rpx};
  349. text {
  350. height: #{130rpx};
  351. display: inline-block;
  352. text-align: center;
  353. line-height: #{50rpx};
  354. font-size: #{24rpx};
  355. writing-mode: vertical-rl;
  356. letter-spacing: #{5rpx};
  357. }
  358. }
  359. }
  360. }
  361. }
  362. </style>