parkingFeeCoupon.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. import { mapState } from 'vuex';
  2. import uni from '@/utils/uniHooks';
  3. // import { initWxJsSdkConfig } from '@/utils/login';
  4. import { Toast } from 'vant';
  5. import { getPlatform, getAppIdByGroupIdAndMallId, isInWeixinH5 } from '@/utils';
  6. import { initWxJsSdkConfig } from '@/utils/login';
  7. import { compare } from '@/utils/location.js';
  8. import { isArray } from 'lodash';
  9. // import { v4 as uuidv4 } from 'uuid';
  10. export default {
  11. data() {
  12. return {
  13. checkedCouponList: [],
  14. couponList: [],
  15. launchPath: '', // H5跳转CRM微信小程序
  16. envVersion: window.env === 'qa' ? 'trial' : 'release', // 所需跳转的小程序版本,合法值为:正式版release、开发版develop、体验版trial(支持的微信版本:iOS 8.0.18及以上、Android 8.0.19及以上)
  17. platform: getPlatform(),
  18. maxCouponFee: 0, // 计算优惠券已选的总金额
  19. remainPrice: 0, // 剩余可用优惠额度
  20. extraData: {}
  21. };
  22. },
  23. computed: {
  24. ...mapState({
  25. custTypeId: (state) => state.custTypeId,
  26. actualPayFee: (state) => state.order.actualPayFee,
  27. orderDetail: (state) => state.order.orderDetail,
  28. coupons: (state) => state.order.coupons,
  29. maxOneDayDiscountFee: (state) => state.order.maxOneDayDiscountFee, // 深圳单日单次使用上限
  30. usingTotalDiscount: (state) => state.order.usingTotalDiscount, // 当前已使用优惠
  31. availableDiscountFee: (state) => state.order.availableDiscountFee, // 当前已使用优惠
  32. paperDiscountFee: (state) => state.order.paperDiscountFee, // 当前已使用优惠
  33. lbsId: (state) => state.lbsId, // 楼栋ID
  34. groupId: (state) => state.groupId, // 楼盘ID
  35. }),
  36. },
  37. mounted() {
  38. console.log('parkingFeeCoupon.js');
  39. setTimeout(() => {
  40. uni.setNavigationBarTitle({
  41. title: '优惠券',
  42. });
  43. if (isInWeixinH5()) {
  44. initWxJsSdkConfig(['checkJsApi', 'chooseImage'], ['wx-open-launch-weapp']);
  45. this.launchPathInit();
  46. }
  47. }, 300);
  48. this.pageInit();
  49. },
  50. methods: {
  51. pageInit() {
  52. /*
  53. * 电子优惠券初始化逻辑(后端处理)
  54. *
  55. * 1、每次change之后,需要重新计算每个电子优惠券的逻辑
  56. * 2、superposition 叠加使用规则 (1不可叠加,2仅同类型可叠加,3可叠加);
  57. * */
  58. this.couponList = [...this.coupons];
  59. this.remainPrice = this.usingTotalDiscount;
  60. if (this.couponList.length) {
  61. this.couponList = this.couponList.map((elm, index) => {
  62. elm.disabled = true;
  63. const selected = elm.hasOwnProperty('selected') ? elm.selected : elm.defaultSelected;
  64. if (selected) {
  65. this.maxCouponFee = this.maxCouponFee + elm.discountFee;
  66. this.checkedCouponList.push(`coupon${index}`);
  67. elm.disabled = false;
  68. } else {
  69. // elm.disabled = !elm.defaultSelected
  70. }
  71. return elm;
  72. });
  73. if (!this.checkedCouponList.length) {
  74. this.couponList = this.couponList.map((elm) => {
  75. elm.disabled = false;
  76. return elm;
  77. });
  78. }
  79. // 验证剩余优惠券是否可勾选(无需验证:后端已计算可勾选的优惠券)
  80. this.newGroupedCouponData()
  81. }
  82. },
  83. item2Number(i) {
  84. return Number.parseInt(i.replace(/coupon/g, ''));
  85. },
  86. checkboxItemChange(name, index) {
  87. // 取消勾选时
  88. if (this.checkedCouponList.indexOf(name) > -1) {
  89. this.checkedCouponList = this.checkedCouponList.filter((i) => i !== name);
  90. setTimeout(() => {
  91. // console.log(158, this.checkedCouponList);
  92. // this.groupedCouponData();
  93. this.remainPrice = this.remainPrice - this.couponList[index].discountFee
  94. this.newGroupedCouponData()
  95. }, 100)
  96. return;
  97. }
  98. // 如果有选中项
  99. const item = this.couponList[index];
  100. this.remainPrice = this.remainPrice + this.couponList[index].discountFee
  101. if (!item.disabled) {
  102. this.checkedCouponList.push(`coupon${index}`);
  103. setTimeout(() => {
  104. // 根据电子券规则判断是否可选
  105. this.isDisabledByRule(item, index);
  106. }, 100)
  107. }
  108. },
  109. // 对不同类型的优惠券进行汇总统计
  110. /*groupedCouponData() {
  111. const groupedData = {}; // 所有的电子券按照批次分组;
  112. let couponList = [...this.couponList]; // 获取目前用户的电子券
  113. couponList.forEach((elm, index) => {
  114. // 初始化数据
  115. const elmName = `coupon${index}`;
  116. const newElm = { ...elm };
  117. if (!groupedData[elm.name] || !groupedData[elm.name].hasOwnProperty('noSelectedList')) {
  118. groupedData[newElm.name] = {
  119. noSelectedList: [], // 未选择的
  120. selectedList: [], // 已选择的
  121. }
  122. }
  123. newElm.index = index; // 记录每张电子券的顺序
  124. // 所有的电子券按照 已选择 和 未选择的分组,存储到同批次下
  125. if (this.checkedCouponList.indexOf(elmName) > -1) {
  126. newElm.selected = true;
  127. groupedData[newElm.name]['selectedList'].push(newElm)
  128. } else {
  129. newElm.selected = false;
  130. groupedData[newElm.name]['noSelectedList'].push(newElm)
  131. }
  132. })
  133. // 对分好组的优惠券进行不同规则处理
  134. Object.keys(groupedData).forEach(key => {
  135. const { selectedList, noSelectedList } = groupedData[key]; // 取出已选择的和未选择的
  136. const { superposition, limitCountPerOrder = 0 } = selectedList.concat(noSelectedList)[0]; // 获取当前批次兑换的类型和可选上限
  137. switch (superposition) {
  138. case '1': // 不可叠加
  139. couponList = couponList.map((item, index) => {
  140. const elmName = `coupon${index}`;
  141. // 如果是不可叠加的电子优惠券,设置未选中的为不可选择
  142. if (item?.superposition === '1') {
  143. if (selectedList.length) {// 如果存在已选择项,设置未选中的为不可选择
  144. item.disabled = this.checkedCouponList.indexOf(elmName) < 0;
  145. /!*
  146. TODO: 如果不可叠加电子券的选择规则改变为,选中某一项不可叠加券,其他券不可选择,则打开此处注释
  147. if (item.superposition === '2') {
  148. item.disabled = selectedList.length > 0
  149. } *!/
  150. } else {
  151. item.disabled = this.checkedCouponList.length > 0;
  152. }
  153. }
  154. /!*
  155. // TODO: 如果不可叠加电子券的选择规则改变为,选中某一项不可叠加券,其他券不可选择,则打开此处注释
  156. // 如果存在已选的电子优惠券,将其他类型的优惠券设置为不可选中
  157. if ( item.superposition === '2' && selectedList.length) {
  158. item.disabled = true
  159. } *!/
  160. return item
  161. })
  162. break
  163. case '2':
  164. // 统计未选择项是否需要禁用
  165. noSelectedList.forEach(elm => {
  166. const _elm = { ...couponList[elm.index] };
  167. couponList = couponList.map((item, index) => {
  168. if (index === elm.index && limitCountPerOrder > 0) {
  169. // elm.disabled = selectedList.length >= limitCountPerOrder;
  170. _elm.disabled = selectedList.length >= limitCountPerOrder;
  171. return _elm
  172. }
  173. return item
  174. })
  175. })
  176. break
  177. }
  178. })
  179. this.couponList = [...couponList];
  180. },*/
  181. // 对不同类型的优惠券进行汇总统计
  182. newGroupedCouponData() {
  183. let couponList = [...this.couponList]; // 获取目前用户的电子券
  184. if (!this.checkedCouponList.length) {
  185. this.couponList = couponList.map(elm => {
  186. elm.disabled = false
  187. return elm;
  188. })
  189. return
  190. }
  191. const index = this.item2Number(this.checkedCouponList[0])
  192. const item = this.couponList[index];
  193. const { superposition, limitCountPerOrder = 0, name } = item;
  194. switch (superposition) {
  195. case '1': // 不可叠加
  196. couponList = couponList.map((elm, i) => {
  197. elm.disabled = i !== index
  198. return elm;
  199. })
  200. break;
  201. case '2': // 同类型可叠加
  202. couponList = couponList.map((elm, i) => {
  203. elm.disabled = false; // 默认可选
  204. const elmName = `coupon${i}`;
  205. if (elm.superposition === superposition) {
  206. if (elm.limitCountPerOrder > 1) { // 是否存在上限
  207. if (this.checkedCouponList.length >= limitCountPerOrder) {
  208. elm.disabled = this.checkedCouponList.indexOf(elmName) < 0
  209. }
  210. } else {
  211. elm.disabled = this.checkedCouponList.indexOf(elmName) < 0 // 同类型可选的券,如果可选上限是1,就设为不可选择
  212. }
  213. } else {
  214. elm.disabled = true; // 非同批次的优惠券设置为不可选择
  215. }
  216. return elm
  217. })
  218. break;
  219. }
  220. console.log(220, couponList)
  221. this.couponList = [...couponList];
  222. },
  223. // 根据电子券规则判断是否可选
  224. isDisabledByRule(item) {
  225. const { parkMallCode } = this.orderDetail.parkInfo;
  226. // 杭州电子券使用上限(单位: 张)
  227. /*if (this.parkMallCode === 2) {
  228. // 达到上限
  229. if (
  230. this.checkedCouponList.length ===
  231. this.parkFee.parkInfoEntity.useTicketNum -
  232. this.parkFee.parkInfoEntity.couponcodeNum
  233. ) {
  234. this.list.forEach((e, i) => {
  235. if (this.checkedCouponList.findIndex((c) => c == i) === -1) {
  236. e.disabled = true;
  237. } else {
  238. e.checked = true;
  239. }
  240. });
  241. return uni.showToast({
  242. title: `电子券每天最多可使用${this.parkFee.parkInfoEntity.useTicketNum}张`,
  243. icon: "none",
  244. });
  245. } else {
  246. this.list.forEach((e) => {
  247. e.disabled = false;
  248. });
  249. }
  250. }*/
  251. // 浦东每次缴费超限控制、沈阳每日超限控制
  252. if ((parkMallCode === 1 || parkMallCode === 4 || parkMallCode === 5 || parkMallCode === 999 || parkMallCode === 6) && this.crossMessage()) {
  253. this.couponList = this.couponList.map((e, i) => {
  254. if (this.checkedCouponList.findIndex((c) => c === `coupon${i}`) === -1) {
  255. e.disabled = true;
  256. }
  257. return e
  258. });
  259. return;
  260. }
  261. // 选中状态赋值
  262. // this.groupedCouponData();
  263. this.newGroupedCouponData();
  264. },
  265. // 是否选中
  266. isCheck(val) {
  267. return this.checkedCouponList.findIndex((e) => e == val) !== -1;
  268. },
  269. // 超限提示
  270. crossMessage() {
  271. const { parkMallCode } = this.orderDetail.parkInfo;
  272. const { maxOneDayCoupons, maxonedaydiscountFee, remainConsumeTime, hourPrice, availableDiscountFee, maxOneTimeDiscountTime } = this.orderDetail.parkingRule;
  273. const {
  274. usingTotalDiscount, // 使用总抵扣
  275. coupons,
  276. } = this.orderDetail.discountInfo;
  277. const {
  278. // totalFee, // 应缴
  279. actualPayFee, // 应付金额
  280. } = this.orderDetail.parkingRecord;
  281. // 剩余可使用的优惠金额,支持动态计算; 优惠时长,不可能全部使用,不能超过车费减去优惠的金额;不能超过单次的应付金额
  282. let remainPrice = remainConsumeTime * hourPrice;
  283. if (parkMallCode === 5) {
  284. if (remainPrice > actualPayFee) {
  285. remainPrice = actualPayFee;
  286. }
  287. }
  288. // let totalFee = this.parkDiscountTotal.feeCopy;
  289. // totalFee += this.totalFee;
  290. // 电子券优惠金额总计
  291. // 浦东每次优惠上限
  292. /*if (
  293. parkMallCode === 1 &&
  294. totalFee - this.paperCouponFee >= this.maxonetimediscountFee
  295. ) {
  296. // uni.showToast({
  297. // title: `超出抵扣上限,每次最高可抵扣${this.parkFee.parkInfoEntity.maxonetimediscount}小时`,
  298. // icon: 'none',
  299. // });
  300. return Toast({
  301. message: `超出抵扣上限,每次最高可抵扣${this.parkFee.parkInfoEntity.maxonetimediscount}小时`,
  302. icon: 'none',
  303. });
  304. return;
  305. }*/
  306. // 沈阳超限处理(maxonedaydiscountFee 会员、消费、电子券减免)
  307. /*if (
  308. parkMallCode === 4 &&
  309. totalFee - this.paperCouponFee - this.parkDiscountTotal.bonusfee >=
  310. this.maxonedaydiscountFee
  311. ) {
  312. return Toast({
  313. message: `(会员等级、消费、电子券)每日最高可抵扣${this.parkFee.parkInfoEntity.maxOneDayHour}小时`,
  314. icon: 'none',
  315. });
  316. // return uni.showToast({
  317. // title: `(会员等级、消费、电子券)每日最高可抵扣${this.parkFee.parkInfoEntity.maxOneDayHour}小时`,
  318. // icon: 'none',
  319. // });
  320. }*/
  321. // 深圳超限处理
  322. if (parkMallCode === 5 && this.remainPrice >= this.actualPayFee) {
  323. return Toast({
  324. message: `每日最高可抵扣${this.actualPayFee}元`,
  325. icon: 'none',
  326. });
  327. }
  328. // 浦东,单次上限提示, 后续 usingTotalDiscount 再减去 纸质优惠券的金额
  329. if (parkMallCode === 1 && usingTotalDiscount- this.paperDiscountFee >= maxOneTimeDiscountTime) {
  330. return Toast({
  331. message: `超出抵扣上限,每次最高可抵扣${maxOneTimeDiscountTime}小时`,
  332. icon: 'none',
  333. });
  334. }
  335. return false
  336. },
  337. // 确认
  338. confirm() {
  339. // 重新计算兑换券优惠
  340. const checkedCouponList = this.checkedCouponList.map((i) => this.item2Number(i));
  341. console.log(checkedCouponList);
  342. const couponList = this.couponList.map((elm, index) => {
  343. elm.selected = false;
  344. console.log(checkedCouponList, index);
  345. if (this.checkedCouponList.indexOf(`coupon${index}`) > -1) {
  346. elm.selected = true;
  347. }
  348. return elm;
  349. });
  350. this.$store.dispatch('order/saveCouponMath', {
  351. couponList: couponList,
  352. callback: () => {
  353. this.$router.back();
  354. },
  355. });
  356. /*uni.setStorageSync('checkedCouponList', this.checkedCouponList);
  357. uni.setStorageSync('list', this.list);
  358. uni.setStorageSync('couponInfo', {
  359. couponfee: this.totalFee,
  360. couponcode: this.couponCode.join('#'),
  361. });
  362. this.$router.back();*/
  363. },
  364. launchPathInit() {
  365. const groupId = uni.getStorageSync('groupId');
  366. const mallId = uni.getStorageSync('mallId');
  367. const { projectId } = getAppIdByGroupIdAndMallId({
  368. groupId: groupId,
  369. mallId: mallId,
  370. type: 'all',
  371. });
  372. this.launchPath = `?trackSourceType=运营位&trackSourceName=功能球&projectId=${projectId}&groupId=${groupId}&mallId=${mallId}&source=tparkingH5`;
  373. let isLogin = false
  374. const member = uni.getStorageSync('member');
  375. if (member && JSON.stringify(this.member) !== '{}') {
  376. isLogin = true
  377. }
  378. this.extraData = {
  379. brandId: this.groupId,
  380. lbsId: this.lbsId,
  381. isLogin: isLogin,
  382. navigate_time:new Date().getTime()
  383. }
  384. },
  385. // 跳转小程序
  386. navigateToMiniProgram() {
  387. if (this.platform === 'miniprogram') {
  388. window.toWXSendMsg({
  389. type: 'navigateToMiniProgram',
  390. options: {
  391. retailLbsId: this.lbsId,
  392. },
  393. });
  394. // 订阅微信小程序端的回调
  395. window.subscribe('navigateToMiniProgramOver', (options) => {
  396. if (options.navigateToMiniProgramOver === 'ok') {
  397. this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
  398. name: 'parkingFeeDetail',
  399. });
  400. this.$router.go(-2);
  401. }
  402. });
  403. }
  404. if (isInWeixinH5()) {
  405. // this.$wx.chooseWXPay({
  406. // timestamp: params?.timeStamp,
  407. // nonceStr: params?.nonceStr,
  408. // package: params?.package,
  409. // signType: params?.signType,
  410. // paySign: params?.paySign,
  411. // success: function (res) {
  412. // // alert('success: ' + JSON.stringify(res));
  413. // // res: {"errMsg":"chooseWXPay:cancel"}
  414. // if (res.errMsg === 'chooseWXPay:ok') {
  415. // resolve({ errMsg: 'requestPayment:ok' });
  416. // } else {
  417. // reject(res);
  418. // }
  419. // },
  420. // cancel: function (res) {
  421. // // alert('cancel: ' + JSON.stringify(res));
  422. // // res: {"errMsg":"chooseWXPay:cancel"}
  423. // resolve({ errMsg: 'requestPayment:cancel' });
  424. // },
  425. // fail: function (err) {
  426. // // eslint-disable-next-line no-console
  427. // console.error(err);
  428. // reject(err);
  429. // },
  430. // });
  431. }
  432. },
  433. // H5 跳转到小程序
  434. launchFn({ appId, extInfo }) {
  435. console.log(584, JSON.stringify({ appId, extInfo }));
  436. this.$store.commit('cachedViews/DEL_CACHED_VIEW', {
  437. name: 'parkingFeeDetail',
  438. });
  439. this.$router.go(-2);
  440. console.log('H5 跳转到 嘉里中心小程序: success');
  441. },
  442. launchErrorFn({ errMsg, appId, extInfo }) {
  443. console.log('H5 跳转到 嘉里中心小程序: fail', JSON.stringify({ errMsg, appId, extInfo }));
  444. },
  445. onLaunchReady() {
  446. console.log('H5 跳转到 嘉里中心小程序 的标签 渲染了');
  447. },
  448. },
  449. };