index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <view class="">
  3. <u-popup :customStyle="{ backgroundColor: '#f4f4f4' }" :show="popShow" :round="10" mode="bottom" @close="popClose" closeable>
  4. <view class="popCon o-plr-30 o-pt-20 o-pb-40">
  5. <view class="l-flex-center c-text-20">请输入优惠码</view>
  6. <view class="content">
  7. <scroll-view scroll-y="true" style="max-height: 70vh;">
  8. <u--form :model="discountForm" ref="uForm" :rules="rules">
  9. <u-form-item v-for="(item, index) in discountList" labelWidth="0" label=" ">
  10. <view class="itemCon l-flex-between">
  11. <view class="numCicle">{{ index + 1 }}</view>
  12. <u-input
  13. type="number"
  14. @change="
  15. e => {
  16. discountChg(e, item, index);
  17. }
  18. "
  19. clearable
  20. :customStyle="{ backgroundColor: '#fff', border: !!messageList[index] ? '1px solid red !important' : '' }"
  21. v-model="discountForm[item]"
  22. :placeholder="'请输入优惠码' + (index + 1)"
  23. >
  24. <template #suffix>
  25. <view class="l-flex-RC" v-if="!!messageList[index]">
  26. <u--text color="#f43530" text="无效"></u--text>
  27. <u-icon name="info-circle-fill" color="#f43530" size="20"></u-icon>
  28. </view>
  29. </template>
  30. </u-input>
  31. </view>
  32. </u-form-item>
  33. </u--form>
  34. </scroll-view>
  35. <view class="btnCon l-f l-flex-j-a o-mt-20"><u-button type="primary" text="确定" @click="confirmClk"></u-button></view>
  36. </view>
  37. </view>
  38. </u-popup>
  39. </view>
  40. </template>
  41. <script>
  42. /**
  43. * discountPop 优惠码弹窗组件
  44. * @description 本组件主要是优惠码弹窗。
  45. *
  46. * @property {Boolean} popShow 是否展示弹窗
  47. *
  48. */
  49. // 引入辅助函数
  50. import { mapGetters } from 'vuex';
  51. // 导入接口
  52. import { API_getCode } from '@/common/api.js';
  53. export default {
  54. data() {
  55. return {
  56. // isCar:1购物车2单个商品
  57. isCar: 1,
  58. // 定时器
  59. timer: null,
  60. // 是否展示弹窗
  61. popShow: false,
  62. // 优惠的商品
  63. discountParam: {},
  64. // 优惠码组合
  65. discountForm: {
  66. discount1: ''
  67. },
  68. // 优惠码组合参数
  69. discountList: [],
  70. // 错误信息集合
  71. messageList: [],
  72. rules: {}
  73. };
  74. },
  75. onReady() {
  76. //如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。
  77. this.$refs.uForm.setRules(this.rules);
  78. },
  79. computed: {
  80. // 使用辅助函数
  81. ...mapGetters(['GETT_clientId', 'GETT_discountCodeList', 'GETT_singleBye_shopCarts']),
  82. // 获取vuex中购物车的数据
  83. $S_tabbar_shopCarts() {
  84. return this.$M_GS('common', '$S_tabbar_shopCarts');
  85. }
  86. },
  87. methods: {
  88. // 清除错误信息提示
  89. discountChg(e, row, idx) {
  90. this.messageList[idx] = '';
  91. },
  92. // 点击确定按钮
  93. async confirmClk() {
  94. console.log('this.discountForm', this.discountForm);
  95. // 步骤一:首先判断页面填写的优惠码有没有重复
  96. // 获取所有填写的优惠码
  97. let codeList = Object.values(this.discountForm);
  98. console.log('codeList', codeList);
  99. let codeLists = {};
  100. if (codeList.length > 0) {
  101. // 将优惠码以key:优惠码,value:优惠码出现次数存在对象中
  102. codeList.forEach(item => {
  103. if (!codeLists[item]) {
  104. codeLists[item] = 1;
  105. } else {
  106. codeLists[item]++;
  107. }
  108. });
  109. }
  110. // 重复的优惠码
  111. let pageRepeats = [];
  112. for (let key in codeLists) {
  113. if (codeLists[key] > 1) {
  114. pageRepeats.push(key);
  115. }
  116. }
  117. // 判断页面填写的有没有重复
  118. if (pageRepeats[0] && pageRepeats[0] != 0) {
  119. uni.$u.toast(`${pageRepeats.join(',')}优惠码已被使用`, 3000);
  120. return;
  121. }
  122. // 步骤二:判断页面填写的优惠码有没有跟vuex存的优惠码集合重复情况
  123. // 1、如果vuex存在比如123优惠码,当前商品之前没有绑定123优惠码,但是其他商品有绑定123优惠码
  124. // 拿到优惠码集合
  125. let discountCodeList = this.GETT_discountCodeList;
  126. // 重复的优惠码集合
  127. let repeatCode = [];
  128. if (codeList.length > 0) {
  129. codeList.forEach(item => {
  130. if (discountCodeList.length > 0) {
  131. discountCodeList.forEach(item1 => {
  132. if (item === item1) {
  133. repeatCode.push(item);
  134. }
  135. });
  136. }
  137. });
  138. }
  139. // 判断如果当前商品的优惠码集合跟重复的优惠码集合有没有交集
  140. let mixCodeList = [];
  141. if (repeatCode.length > 0) {
  142. repeatCode.forEach(item => {
  143. if (this.discountParam.codeList.length > 0) {
  144. this.discountParam.codeList.forEach(item1 => {
  145. // 2、如果vuex存在123优惠码,当前商品之前有绑定123优惠码
  146. if (item === item1) {
  147. mixCodeList.push(item);
  148. }
  149. });
  150. }
  151. });
  152. }
  153. // 如果当前商品的优惠码集合跟重复的优惠码集合有交集
  154. // 如果存在重复的优惠码集合而且之前没有绑定的,则是重复了
  155. if (repeatCode.length > 0 && mixCodeList.length == 0) {
  156. uni.$u.toast(`${repeatCode.join(',')}优惠码已被使用`, 3000);
  157. return;
  158. }
  159. // 如果有填写了优惠码的,但是请求接口没有找到对应的信息
  160. let isDiscount = this.messageList.some(item => item === '没有找到优惠码' || item === '已使用');
  161. // 如果页面没有报错信息
  162. if (!isDiscount) {
  163. // 判断有没有一个优惠码都没有填写
  164. let hasVal = codeList.some(item => !!item);
  165. if (!hasVal) {
  166. uni.$u.toast('请先填写优惠码!!!');
  167. return;
  168. }
  169. // 储存优惠码接口返回的信息
  170. let dataList = [];
  171. // 遍历优惠码
  172. for (let i = 0; i < codeList.length; i++) {
  173. dataList[i] = {};
  174. if (!!codeList[i]) {
  175. // 调用优惠码接口
  176. let res = await API_getCode(
  177. {
  178. code: codeList[i],
  179. clientId: this.GETT_clientId
  180. },
  181. {
  182. catch: true
  183. }
  184. );
  185. dataList[i] = res;
  186. }
  187. }
  188. // 重新整合优惠码,无效的要变成0
  189. let list = [];
  190. // 整合无效的提示信息
  191. let messageList = [];
  192. dataList.forEach((item, index) => {
  193. messageList[index] = '';
  194. list[index] = 0;
  195. // 如果优惠码有效
  196. if (item.code === '00000') {
  197. list[index] = item.data.code + '';
  198. } else {
  199. messageList[index] = item.message;
  200. }
  201. });
  202. this.messageList = messageList;
  203. // 处理每件商品的优惠价
  204. this.handleGood(list, dataList);
  205. // 如果有填写了优惠码的,但是请求接口没有找到对应的信息
  206. let isDiscount = messageList.some(item => item === '没有找到优惠码' || item === '已使用');
  207. // 如果页面没有报错信息
  208. if (!isDiscount) {
  209. this.init();
  210. this.popShow = false;
  211. }
  212. }
  213. },
  214. // 处理当前商品的优惠码和优惠价集合
  215. handleGood(codeList, dataList) {
  216. let shopCarts;
  217. // 如果是购物车进来的
  218. if (this.isCar === 1) {
  219. // 获取购物车数据
  220. shopCarts = this.$S_tabbar_shopCarts;
  221. // 把优惠码添加到购物车数据里面去
  222. shopCarts[this.discountParam['imgId']]['codeList'] = codeList;
  223. } else {
  224. // 获取购物车数据
  225. shopCarts = this.GETT_singleBye_shopCarts;
  226. // 把优惠码添加到购物车数据里面去
  227. shopCarts['codeList'] = codeList;
  228. }
  229. // 遍历优惠码查询返回的数据,组合优惠价
  230. let discountList = [];
  231. dataList.forEach((item, index) => {
  232. discountList[index] = 0;
  233. if (item.code === '00000') {
  234. let price = 0;
  235. // 如果是折扣价优惠码
  236. if (item.data.type == 1) {
  237. price = item.data.discount;
  238. } else {
  239. // 计算打完折后的价格
  240. let discountPrice = this.$M_Big(item.data.discount)
  241. .mul(0.1)
  242. .mul(this.discountParam.rmbPrice)
  243. .toNumber();
  244. // 实际优惠了多少
  245. price = this.$M_Big(this.discountParam.rmbPrice)
  246. .sub(discountPrice)
  247. .toNumber();
  248. }
  249. discountList[index] = price;
  250. }
  251. });
  252. console.log('discountList',discountList)
  253. // 如果是购物车进来的
  254. if (this.isCar === 1) {
  255. // 把优惠价添加到购物车数据里面去
  256. shopCarts[this.discountParam['imgId']]['discountList'] = discountList;
  257. // 重新保存购物车数据
  258. this.$M_Dp('ACTI_SHOPCARTS', shopCarts);
  259. } else {
  260. // 把优惠价添加到购物车数据里面去
  261. shopCarts['discountList'] = discountList;
  262. // 重新保存购物车数据
  263. this.$M_Cm('MUTA_SINGSHOPCARTS', shopCarts);
  264. }
  265. console.log('shopCarts', shopCarts);
  266. // 处理优惠码集合
  267. this.handleDiscList();
  268. },
  269. // 集合所有的优惠码
  270. handleDiscList() {
  271. let shopCarts = {};
  272. let codes = [];
  273. // 如果是购物车进来的
  274. if (this.isCar === 1) {
  275. // 获取购物车数据
  276. shopCarts = this.$S_tabbar_shopCarts;
  277. // 重新组合优惠码
  278. for (let key in shopCarts) {
  279. codes = [...new Set(codes.concat(shopCarts[key]['codeList']))];
  280. }
  281. }
  282. // 商品详情页面
  283. // 情况1:
  284. // 用户支付用了优惠码,再次使用肯定是重复了
  285. // 情况2:
  286. // 用户查询了优惠码,绑定到了当前商品,但是没有支付,直接加入购物车,再次使用肯定是重复使用了
  287. // 情况3:
  288. // 用户查询了优惠码,绑定到了当前商品,但是没有支付,也没有加入购物车,那再次使用,没有重复使用
  289. // 综上所述,下面这步要放到情况1和2中使用
  290. // else {
  291. // // 获取购物车数据
  292. // shopCarts = this.GETT_singleBye_shopCarts;
  293. // // 重新组合优惠码
  294. // codes = [...new Set(codes.concat(shopCarts['codeList']))];
  295. // }
  296. // 储存优惠码,用来校验重复问题
  297. this.$M_Cm('MUTA_DISCOUNTCODE', codes);
  298. },
  299. // 初始化状态
  300. init() {
  301. // 初始化
  302. this.discountList = [];
  303. this.messageList = [];
  304. this.$refs.uForm.resetFields();
  305. for (let key in this.discountForm) {
  306. this.discountForm[key] = '';
  307. }
  308. },
  309. // 关闭弹窗
  310. popClose() {
  311. this.init();
  312. this.popShow = false;
  313. },
  314. // 开启弹窗
  315. popOpen(discountParam, isCar) {
  316. this.isCar = isCar;
  317. // 一种商品有几件,就有几个优惠码
  318. let discountForm = {};
  319. for (let i = 1; i <= discountParam.nums; i++) {
  320. // 把原来有的优惠码显示在上面
  321. discountForm[`discount${i}`] = discountParam.codeList[i - 1] != 0 ? discountParam.codeList[i - 1] : '';
  322. }
  323. this.discountForm = discountForm;
  324. this.discountList = Object.keys(discountForm);
  325. this.discountParam = discountParam;
  326. this.popShow = true;
  327. }
  328. }
  329. };
  330. </script>
  331. <style lang="scss" scoped>
  332. .popCon {
  333. .content {
  334. .numCicle {
  335. width: 50rpx;
  336. height: 50rpx;
  337. border-radius: 50%;
  338. background-color: #3c9cff;
  339. color: #fff;
  340. text-align: center;
  341. line-height: 50rpx;
  342. margin-right: 20rpx;
  343. }
  344. }
  345. }
  346. </style>