index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. });
  176. setTimeout(() => {
  177. uni.hideLoading();
  178. }, 200);
  179. this.handleCar(e, row, 3);
  180. },
  181. // 处理购物车数据
  182. handleCar(e, row, idx) {
  183. switch (idx) {
  184. // 给优惠码和优惠价的列表添加一个0值
  185. case 1:
  186. row.codeList.push(0);
  187. row.discountList.push(0);
  188. break;
  189. // 去掉优惠码和优惠价的列表的最后一个
  190. case 2:
  191. row.codeList.pop();
  192. row.discountList.pop();
  193. break;
  194. // 找到购物车数据对应商品的,重新计算总价格
  195. case 3:
  196. row.nums = e.value;
  197. row.totalPrice = this.$M_Big(row.goodsPrice)
  198. .mul(row.nums)
  199. .toNumber();
  200. break;
  201. }
  202. this.$M_Cm('MUTA_SINGSHOPCARTS', row);
  203. },
  204. // 点击查看明细
  205. amountClk() {
  206. console.log(this.GETT_singleBye_shopCarts, 'this.GETT_singleBye_shopCarts');
  207. this.$refs.kAmountPopRef.popOpen({}, this.priceList);
  208. },
  209. // 点击优惠码
  210. discountClk() {
  211. this.$refs.kDiscountPopRef.popOpen(this.GETT_singleBye_shopCarts, 2);
  212. },
  213. // 获取手机号
  214. async getPhone(e) {
  215. const { code } = e.detail;
  216. // 如果用户点击允许获取手机号
  217. if (!!code) {
  218. let param = {
  219. code,
  220. id: this.GETT_loginInfos.id
  221. };
  222. // 调用获取手机号的接口
  223. let res = await API_getPhone(param);
  224. // 把手机号信息存到vuex里面
  225. await this.$M_Cm('MUTA_GETOPENID', res);
  226. }
  227. this.toPayPop();
  228. },
  229. // 点击支付按钮
  230. toPayPop() {
  231. //询问是否订阅取餐通知
  232. this.dingyue();
  233. console.log('单个商品', this.GETT_singleBye_shopCarts);
  234. // 如果是一件商品,那么要给优惠码加个0
  235. if(this.GETT_singleBye_shopCarts.nums === 1){
  236. // 如果没有优惠码
  237. if(this.GETT_singleBye_shopCarts.codeList.length===0){
  238. this.GETT_singleBye_shopCarts.codeList = [0];
  239. }
  240. }
  241. // 规定支付的商品数量不能超过5
  242. if (this.GETT_singleBye_shopCarts.nums > 5) {
  243. this.payContent = '支付商品的数量不能超过5件,请减少数量后,重新支付!!!';
  244. this.payShow = true;
  245. return;
  246. }
  247. let shopCarts = {};
  248. shopCarts[this.GETT_singleBye_shopCarts['imgId']] = this.GETT_singleBye_shopCarts;
  249. const payParam = {
  250. shopCarts,
  251. clientId: this.GETT_clientId,
  252. id: this.GETT_loginInfos.id
  253. };
  254. // 如果有优惠券要提醒用户去选择优惠券
  255. if (this.GETT_home_couponList.length > 0) {
  256. uni.showModal({
  257. title: '提示',
  258. confirmText: '去使用',
  259. cancelText: '不使用',
  260. confirmColor: '#3c9cff',
  261. content: `当前可使用优惠券${this.GETT_home_couponList.length}张。`,
  262. success: modelRes => {
  263. if (modelRes.confirm) {
  264. // 打开优惠券弹窗
  265. this.$refs.kCouponRef.popOpen(this.GETT_home_couponList, payParam, 3, this.priceList.totalPrice);
  266. } else {
  267. // 显示支付弹窗
  268. this.$refs.kPayPopRef.popOpen(payParam, 3);
  269. }
  270. }
  271. });
  272. }else{
  273. // 显示支付弹窗
  274. this.$refs.kPayPopRef.popOpen(payParam, 3);
  275. }
  276. },
  277. //询问是否订阅取餐通知
  278. dingyue(){
  279. var that = this;
  280. wx.requestSubscribeMessage({
  281. tmplIds: ['NVmdaK4MwygT63ME830pwM6wZt4eufxhBr6jlQ2XXJ4'],
  282. success(res) {
  283. var status = res.NVmdaK4MwygT63ME830pwM6wZt4eufxhBr6jlQ2XXJ4;
  284. if(status=='accept'){
  285. //通知后台该用户订阅了消息
  286. var id = that.GETT_loginInfos.id;
  287. API_setDingYue( {id:id} ).then(res => {
  288. console.log('res', res);
  289. });
  290. }
  291. console.log('授权成功');
  292. }
  293. })
  294. },
  295. // 加入购物车
  296. addCart() {
  297. let row = this.GETT_singleBye_shopCarts;
  298. // 加入购物车初始状态都是选中状态
  299. row['isCheck'] = true;
  300. // 获取vuxe购物车数据
  301. let shopCarts = this.$S_tabbar_shopCarts;
  302. // 如果不存在imgId这个属性,则创建
  303. if (!shopCarts[row['imgId']]) {
  304. // $M_Big用来计算总数量的方法(具体用法请看common)
  305. row['totalPrice'] = this.$M_Big(row['goodsPrice'])
  306. .mul(row['nums'])
  307. .toNumber();
  308. // 用$M_Extend继承row创建新对象并赋值给shopCarts的属性
  309. shopCarts[row['imgId']] = this.$M_Extend(row, {
  310. nums: row['nums']
  311. });
  312. } else {
  313. shopCarts[row['imgId']]['codeList'] = shopCarts[row['imgId']]['codeList'].concat(row.codeList);
  314. shopCarts[row['imgId']]['discountList'] = shopCarts[row['imgId']]['discountList'].concat(row.discountList);
  315. // 如果存在imgId这个属性,则数量+1,总数totalPrice=价格goodsPrice*数量nums
  316. let nums = shopCarts[row['imgId']]['nums'] + row['nums'];
  317. // $M_Big用来计算总数量的方法(具体用法请看common)
  318. row['totalPrice'] = this.$M_Big(row['goodsPrice'])
  319. .mul(nums)
  320. .toNumber();
  321. shopCarts[row['imgId']] = this.$M_Extend(row, {
  322. nums
  323. });
  324. }
  325. console.log('shopCarts', shopCarts);
  326. // 修改vuex购物车数据
  327. this.$M_Dp('ACTI_SHOPCARTS', shopCarts);
  328. // 处理优惠码集合
  329. this.handleDiscList();
  330. },
  331. handleDiscList() {
  332. // 获取购物车数据
  333. let shopCarts = this.GETT_singleBye_shopCarts;
  334. let codes = [];
  335. // 重新组合优惠码
  336. codes = [...new Set(codes.concat(shopCarts['codeList']))];
  337. // 储存优惠码,用来校验重复问题
  338. this.$M_Cm('MUTA_DISCOUNTCODE', codes);
  339. },
  340. // 去首页
  341. toIndex() {
  342. this.addCart();
  343. this.$M_Back();
  344. }
  345. }
  346. };
  347. </script>
  348. <style lang="scss" scoped>
  349. .singleByeIdx {
  350. padding-bottom: constant(safe-area-inset-bottom);
  351. padding-bottom: env(safe-area-inset-bottom);
  352. }
  353. </style>