index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <template>
  2. <view
  3. class="o-h c-bg-f o-plr-30 singleByeIdx"
  4. >
  5. <view class="o-h l-f l-flex-d l-flex-j-b ">
  6. <view class="l-flex-center o-mt-50 l-flex-3">
  7. <u--image
  8. :width="GETT_miniProduct.includes(GETT_singleBye_shopCarts.imgId) ? '500rpx' : '450rpx'"
  9. :height="GETT_miniProduct.includes(GETT_singleBye_shopCarts.imgId) ? '500rpx' : '450rpx'"
  10. mode="aspectFit"
  11. :lazy-load="true"
  12. :fade="true"
  13. duration="450"
  14. :src="GETT_singleBye_shopCarts.imgUrl"
  15. >
  16. <view slot="error" style="font-size: 24rpx;">加载失败</view>
  17. </u--image>
  18. </view>
  19. <view class="l-f l-flex-d l-flex-center l-flex-1 chgUNumBox">
  20. <u-number-box
  21. button-size="48"
  22. v-model="GETT_singleBye_shopCarts.nums"
  23. @change="
  24. e => {
  25. numsChg(e, GETT_singleBye_shopCarts);
  26. }
  27. "
  28. disabledInput
  29. @minus="
  30. e => {
  31. goodMinus(e, GETT_singleBye_shopCarts);
  32. }
  33. "
  34. @plus="
  35. e => {
  36. goodPlus(e, GETT_singleBye_shopCarts);
  37. }
  38. "
  39. ></u-number-box>
  40. <u-button :customStyle="{marginTop:'20px'}" @click="discountClk" type="primary" shape="circle" text="添加优惠码"></u-button>
  41. </view>
  42. <view class="l-flex-1 l-f l-flex-d l-flex-j-e">
  43. <view class="o-mt-30 l-flex-between">
  44. <u-button @click="toIndex" plain shape="circle" type="primary" text="购买更多"></u-button>
  45. <view style="flex:0 0 120px;">
  46. <view class="c-color-1 c-text-14">
  47. 合计:
  48. <text class="c-text-14 c-color-MR">¥{{ priceList.totalPrice }}</text>
  49. </view>
  50. <view class="c-color-1 c-text-14 o-mr-14">
  51. 已优惠:
  52. <text class="c-text-14 c-color-MR">¥{{ priceList.discountPrices }}</text>
  53. </view>
  54. <!-- 如果优惠券总金额大于0,则显示预估到手价 -->
  55. <view v-if="GETT_home_totalCoupon > 0" class="c-text-12 c-color-f l-flex-RC" style="color:#ff9900;">
  56. <view class="c-text-14">预估到手:</view>
  57. <view class="c-text-14" style="color:#f45632;">
  58. ¥{{ compEstiPrice(priceList.totalPrice) }}
  59. </view>
  60. </view>
  61. <view class=""><u--text @click="amountClk" size="14" type="primary" text="查看明细"></u--text></view>
  62. </view>
  63. <u-button v-if="GETT_loginInfos.phone" @click="toPayPop" throttleTime="2000" type="primary" shape="circle" text="去支付"></u-button>
  64. <!-- :text="`去支付(¥${GETT_singleBye_shopCarts.totalPrice})`" -->
  65. <u-button v-else open-type="getPhoneNumber" @getphonenumber="getPhone" type="primary" shape="circle" text="去支付"></u-button>
  66. </view>
  67. </view>
  68. </view>
  69. <!-- 金额明细弹窗 -->
  70. <k-amountPop ref="kAmountPopRef"></k-amountPop>
  71. <!-- 优惠码弹窗 -->
  72. <k-discountPop ref="kDiscountPopRef"></k-discountPop>
  73. <!-- 支付弹窗 -->
  74. <k-payPop ref="kPayPopRef"></k-payPop>
  75. <!-- 支付提示弹窗 -->
  76. <u-modal @confirm="payShow = false" :show="payShow" title="提示" :content="payContent"></u-modal>
  77. <!-- 优惠券弹窗 -->
  78. <k-coupon ref="kCouponRef"></k-coupon>
  79. </view>
  80. </template>
  81. <script>
  82. // 导入优惠券弹窗
  83. import kCoupon from '@/components/common/k-coupon/index.vue';
  84. // 导入金额明细弹窗
  85. import kAmountPop from '@/components/common/k-amountPop/index.vue';
  86. // 导入优惠码弹窗
  87. import kDiscountPop from '@/components/common/k-discountPop/index.vue';
  88. // 导入支付弹窗
  89. import kPayPop from '@/components/common/k-payPop/index.vue';
  90. // 导入接口
  91. import { API_getPhone,API_setDingYue } from '@/common/api.js';
  92. // 引入辅助函数
  93. import { mapGetters } from 'vuex';
  94. export default {
  95. components: {
  96. kPayPop,
  97. kDiscountPop,
  98. kAmountPop,
  99. kCoupon
  100. },
  101. data() {
  102. return {
  103. // 支付提示弹窗
  104. payShow: false,
  105. payContent: false
  106. };
  107. },
  108. computed: {
  109. // 获取vuex中购物车的数据
  110. $S_tabbar_shopCarts() {
  111. return this.$M_GS('common', '$S_tabbar_shopCarts');
  112. },
  113. // 使用辅助函数
  114. ...mapGetters(['GETT_miniProduct', 'GETT_loginInfos', 'GETT_clientId', 'GETT_singleBye_shopCarts','GETT_home_couponList', 'GETT_home_totalCoupon']),
  115. // 选中的总金额
  116. priceList() {
  117. const item = this.GETT_singleBye_shopCarts;
  118. // 总价格
  119. let totalPrice = 0;
  120. // 总优惠
  121. let discountPrices = 0;
  122. let discountPrice = 0;
  123. // 计算出每件商品的总优惠
  124. if (item.discountList && item.discountList.length > 0) {
  125. discountPrice = item.discountList.reduce((prev, cur) => {
  126. return this.$M_Big(prev)
  127. .add(cur)
  128. .toNumber();
  129. }, 0);
  130. }
  131. // 减去总优惠
  132. totalPrice = this.$M_Big(totalPrice)
  133. .add(item.totalPrice)
  134. .sub(discountPrice)
  135. .toNumber();
  136. // 总优惠是
  137. discountPrices = this.$M_Big(discountPrices)
  138. .add(discountPrice)
  139. .toNumber();
  140. return {
  141. totalPrice,
  142. discountPrices
  143. };
  144. },
  145. // 计算预估到手价
  146. compEstiPrice() {
  147. return function(totalPrice) {
  148. const estiPrice = this.$M_Big(totalPrice)
  149. .sub(this.GETT_home_totalCoupon)
  150. .toNumber();
  151. if (estiPrice <= 0) return 0.01;
  152. return estiPrice;
  153. };
  154. }
  155. },
  156. onLoad() {
  157. uni.setNavigationBarTitle({
  158. title: this.GETT_singleBye_shopCarts.imgName
  159. });
  160. },
  161. methods: {
  162. // 点击商品+
  163. goodPlus(e, row) {
  164. this.handleCar(e, row, 1);
  165. },
  166. // 点击商品-
  167. goodMinus(e, row) {
  168. this.handleCar(e, row, 2);
  169. },
  170. // 点击数量的+-
  171. numsChg(e, row) {
  172. // 增加用户体验
  173. uni.showLoading({
  174. title: '请稍等',
  175. mask: true,
  176. });
  177. setTimeout(() => {
  178. uni.hideLoading();
  179. }, 200);
  180. this.handleCar(e, row, 3);
  181. },
  182. // 处理购物车数据
  183. handleCar(e, row, idx) {
  184. switch (idx) {
  185. // 给优惠码和优惠价的列表添加一个0值
  186. case 1:
  187. row.codeList.push(0);
  188. row.discountList.push(0);
  189. break;
  190. // 去掉优惠码和优惠价的列表的最后一个
  191. case 2:
  192. row.codeList.pop();
  193. row.discountList.pop();
  194. break;
  195. // 找到购物车数据对应商品的,重新计算总价格
  196. case 3:
  197. row.nums = e.value;
  198. row.totalPrice = this.$M_Big(row.goodsPrice)
  199. .mul(row.nums)
  200. .toNumber();
  201. break;
  202. }
  203. this.$M_Cm('MUTA_SINGSHOPCARTS', row);
  204. },
  205. // 点击查看明细
  206. amountClk() {
  207. console.log(this.GETT_singleBye_shopCarts, 'this.GETT_singleBye_shopCarts');
  208. this.$refs.kAmountPopRef.popOpen({}, this.priceList);
  209. },
  210. // 点击优惠码
  211. discountClk() {
  212. this.$refs.kDiscountPopRef.popOpen(this.GETT_singleBye_shopCarts, 2);
  213. },
  214. // 获取手机号
  215. async getPhone(e) {
  216. const { code } = e.detail;
  217. // 如果用户点击允许获取手机号
  218. if (!!code) {
  219. let param = {
  220. code,
  221. id: this.GETT_loginInfos.id
  222. };
  223. // 调用获取手机号的接口
  224. let res = await API_getPhone(param);
  225. // 把手机号信息存到vuex里面
  226. await this.$M_Cm('MUTA_GETOPENID', res);
  227. }
  228. this.toPayPop();
  229. },
  230. // 点击支付按钮
  231. toPayPop() {
  232. //询问是否订阅取餐通知
  233. this.dingyue();
  234. console.log('单个商品', this.GETT_singleBye_shopCarts);
  235. // 如果是一件商品,那么要给优惠码加个0
  236. if(this.GETT_singleBye_shopCarts.nums === 1){
  237. // 如果没有优惠码
  238. if(this.GETT_singleBye_shopCarts.codeList.length===0){
  239. this.GETT_singleBye_shopCarts.codeList = [0];
  240. }
  241. }
  242. // 规定支付的商品数量不能超过5
  243. if (this.GETT_singleBye_shopCarts.nums > 5) {
  244. this.payContent = '支付商品的数量不能超过5件,请减少数量后,重新支付!!!';
  245. this.payShow = true;
  246. return;
  247. }
  248. let shopCarts = {};
  249. shopCarts[this.GETT_singleBye_shopCarts['imgId']] = this.GETT_singleBye_shopCarts;
  250. const payParam = {
  251. shopCarts,
  252. clientId: this.GETT_clientId,
  253. id: this.GETT_loginInfos.id
  254. };
  255. // 如果有优惠券要提醒用户去选择优惠券
  256. if (this.GETT_home_couponList.length > 0) {
  257. uni.showModal({
  258. title: '提示',
  259. confirmText: '去使用',
  260. cancelText: '不使用',
  261. confirmColor: '#3c9cff',
  262. content: `当前可使用优惠券${this.GETT_home_couponList.length}张。`,
  263. success: modelRes => {
  264. if (modelRes.confirm) {
  265. // 打开优惠券弹窗
  266. this.$refs.kCouponRef.popOpen(this.GETT_home_couponList, payParam, 3, this.priceList.totalPrice);
  267. } else {
  268. // 显示支付弹窗
  269. this.$refs.kPayPopRef.popOpen(payParam, 3);
  270. }
  271. }
  272. });
  273. }else{
  274. // 显示支付弹窗
  275. this.$refs.kPayPopRef.popOpen(payParam, 3);
  276. }
  277. },
  278. //询问是否订阅取餐通知
  279. dingyue(){
  280. var that = this;
  281. wx.requestSubscribeMessage({
  282. tmplIds: ['NVmdaK4MwygT63ME830pwM6wZt4eufxhBr6jlQ2XXJ4'],
  283. success(res) {
  284. var status = res.NVmdaK4MwygT63ME830pwM6wZt4eufxhBr6jlQ2XXJ4;
  285. if(status=='accept'){
  286. //通知后台该用户订阅了消息
  287. var id = that.GETT_loginInfos.id;
  288. API_setDingYue( {id:id} ).then(res => {
  289. console.log('res', res);
  290. });
  291. }
  292. console.log('授权成功');
  293. }
  294. })
  295. },
  296. // 加入购物车
  297. addCart() {
  298. let row = this.GETT_singleBye_shopCarts;
  299. // 加入购物车初始状态都是选中状态
  300. row['isCheck'] = true;
  301. // 获取vuxe购物车数据
  302. let shopCarts = this.$S_tabbar_shopCarts;
  303. // 如果不存在imgId这个属性,则创建
  304. if (!shopCarts[row['imgId']]) {
  305. // $M_Big用来计算总数量的方法(具体用法请看common)
  306. row['totalPrice'] = this.$M_Big(row['goodsPrice'])
  307. .mul(row['nums'])
  308. .toNumber();
  309. // 用$M_Extend继承row创建新对象并赋值给shopCarts的属性
  310. shopCarts[row['imgId']] = this.$M_Extend(row, {
  311. nums: row['nums']
  312. });
  313. } else {
  314. shopCarts[row['imgId']]['codeList'] = shopCarts[row['imgId']]['codeList'].concat(row.codeList);
  315. shopCarts[row['imgId']]['discountList'] = shopCarts[row['imgId']]['discountList'].concat(row.discountList);
  316. // 如果存在imgId这个属性,则数量+1,总数totalPrice=价格goodsPrice*数量nums
  317. let nums = shopCarts[row['imgId']]['nums'] + row['nums'];
  318. // $M_Big用来计算总数量的方法(具体用法请看common)
  319. row['totalPrice'] = this.$M_Big(row['goodsPrice'])
  320. .mul(nums)
  321. .toNumber();
  322. shopCarts[row['imgId']] = this.$M_Extend(row, {
  323. nums
  324. });
  325. }
  326. console.log('shopCarts', shopCarts);
  327. // 修改vuex购物车数据
  328. this.$M_Dp('ACTI_SHOPCARTS', shopCarts);
  329. // 处理优惠码集合
  330. this.handleDiscList();
  331. },
  332. handleDiscList() {
  333. // 获取购物车数据
  334. let shopCarts = this.GETT_singleBye_shopCarts;
  335. let codes = [];
  336. // 重新组合优惠码
  337. codes = [...new Set(codes.concat(shopCarts['codeList']))];
  338. // 储存优惠码,用来校验重复问题
  339. this.$M_Cm('MUTA_DISCOUNTCODE', codes);
  340. },
  341. // 去首页
  342. toIndex() {
  343. this.addCart();
  344. this.$M_Back();
  345. }
  346. }
  347. };
  348. </script>
  349. <style lang="scss" scoped>
  350. .singleByeIdx {
  351. padding-bottom: constant(safe-area-inset-bottom);
  352. padding-bottom: env(safe-area-inset-bottom);
  353. }
  354. </style>