index.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. const app = getApp()
  2. const CONFIG = require('../../config.js')
  3. const WXAPI = require('apifm-wxapi')
  4. const AUTH = require('../../utils/auth')
  5. const wxpay = require('../../utils/pay.js')
  6. Page({
  7. data: {
  8. totalScoreToPay: 0,
  9. goodsList: [],
  10. isNeedLogistics: 0, // 是否需要物流信息
  11. yunPrice: 0,
  12. allGoodsAndYunPrice: 0,
  13. goodsJsonStr: "",
  14. orderType: "", //订单类型,购物车下单或立即支付下单,默认是购物车,
  15. pingtuanOpenId: undefined, //拼团的话记录团号
  16. hasNoCoupons: true,
  17. coupons: [],
  18. couponAmount: 0, //优惠券金额
  19. curCoupon: null, // 当前选择使用的优惠券
  20. curCouponShowText: '请选择使用优惠券', // 当前选择使用的优惠券
  21. peisongType: 'kd', // 配送方式 kd,zq 分别表示快递/到店自取
  22. remark: '',
  23. shopIndex: -1,
  24. pageIsEnd: false,
  25. bindMobileStatus: 0, // 0 未判断 1 已绑定手机号码 2 未绑定手机号码
  26. userScore: 0, // 用户可用积分
  27. deductionScore: '0' // 本次交易抵扣的积分数
  28. },
  29. onShow(){
  30. if (this.data.pageIsEnd) {
  31. return
  32. }
  33. AUTH.checkHasLogined().then(isLogined => {
  34. if (isLogined) {
  35. this.doneShow()
  36. } else {
  37. AUTH.authorize().then(res => {
  38. this.doneShow()
  39. })
  40. }
  41. })
  42. AUTH.wxaCode().then(code => {
  43. this.data.code = code
  44. })
  45. },
  46. async doneShow() {
  47. let goodsList = [];
  48. const token = wx.getStorageSync('token')
  49. //立即购买下单
  50. if ("buyNow" == this.data.orderType) {
  51. var buyNowInfoMem = wx.getStorageSync('buyNowInfo');
  52. this.data.kjId = buyNowInfoMem.kjId;
  53. if (buyNowInfoMem && buyNowInfoMem.shopList) {
  54. goodsList = buyNowInfoMem.shopList
  55. }
  56. } else {
  57. //购物车下单
  58. const res = await WXAPI.shippingCarInfo(token)
  59. if (res.code == 0) {
  60. goodsList = res.data.items.filter(ele => { return ele.selected })
  61. }
  62. }
  63. this.setData({
  64. goodsList,
  65. peisongType: this.data.peisongType
  66. });
  67. this.initShippingAddress()
  68. this.userAmount()
  69. },
  70. onLoad(e) {
  71. let _data = {
  72. isNeedLogistics: 1
  73. }
  74. if (e.orderType) {
  75. _data.orderType = e.orderType
  76. }
  77. if (e.pingtuanOpenId) {
  78. _data.pingtuanOpenId = e.pingtuanOpenId
  79. }
  80. this.setData(_data)
  81. this.getUserApiInfo()
  82. },
  83. async userAmount() {
  84. const res = await WXAPI.userAmount(wx.getStorageSync('token'))
  85. if (res.code == 0) {
  86. this.setData({
  87. balance: res.data.balance,
  88. userScore: res.data.score
  89. })
  90. }
  91. },
  92. getDistrictId: function (obj, aaa) {
  93. if (!obj) {
  94. return "";
  95. }
  96. if (!aaa) {
  97. return "";
  98. }
  99. return aaa;
  100. },
  101. remarkChange(e){
  102. this.data.remark = e.detail.value
  103. },
  104. async goCreateOrder(){
  105. // 检测实名认证状态
  106. if (wx.getStorageSync('needIdCheck') == 1) {
  107. console.log(123);
  108. const res = await WXAPI.userDetail(wx.getStorageSync('token'))
  109. if (res.code == 0 && !res.data.base.isIdcardCheck) {
  110. wx.navigateTo({
  111. url: '/pages/idCheck/index',
  112. })
  113. return
  114. }
  115. }
  116. const subscribe_ids = wx.getStorageSync('subscribe_ids')
  117. if (subscribe_ids) {
  118. wx.requestSubscribeMessage({
  119. tmplIds: subscribe_ids.split(','),
  120. success(res) {
  121. },
  122. fail(e) {
  123. console.error(e)
  124. },
  125. complete: (e) => {
  126. this.createOrder(true)
  127. },
  128. })
  129. } else {
  130. this.createOrder(true)
  131. }
  132. },
  133. createOrder: function (e) {
  134. var that = this;
  135. var loginToken = wx.getStorageSync('token') // 用户登录 token
  136. var remark = this.data.remark; // 备注信息
  137. let postData = {
  138. token: loginToken,
  139. goodsJsonStr: that.data.goodsJsonStr,
  140. remark: remark,
  141. peisongType: that.data.peisongType,
  142. deductionScore: this.data.deductionScore
  143. };
  144. if (that.data.kjId) {
  145. postData.kjid = that.data.kjId
  146. }
  147. if (that.data.pingtuanOpenId) {
  148. postData.pingtuanOpenId = that.data.pingtuanOpenId
  149. }
  150. if (postData.peisongType == 'kd' && that.data.curAddressData && that.data.curAddressData.provinceId) {
  151. postData.provinceId = that.data.curAddressData.provinceId;
  152. }
  153. if (postData.peisongType == 'kd' && that.data.curAddressData && that.data.curAddressData.cityId) {
  154. postData.cityId = that.data.curAddressData.cityId;
  155. }
  156. if (postData.peisongType == 'kd' && that.data.curAddressData && that.data.curAddressData.districtId) {
  157. postData.districtId = that.data.curAddressData.districtId;
  158. }
  159. if (e && that.data.isNeedLogistics > 0 && postData.peisongType == 'kd') {
  160. if (!that.data.curAddressData) {
  161. wx.hideLoading();
  162. wx.showToast({
  163. title: '请设置收货地址',
  164. icon: 'none'
  165. })
  166. return;
  167. }
  168. if (postData.peisongType == 'kd') {
  169. postData.address = that.data.curAddressData.address;
  170. postData.linkMan = that.data.curAddressData.linkMan;
  171. postData.mobile = that.data.curAddressData.mobile;
  172. postData.code = that.data.curAddressData.code;
  173. }
  174. }
  175. if (that.data.curCoupon) {
  176. postData.couponId = that.data.curCoupon.id;
  177. }
  178. if (!e) {
  179. postData.calculate = "true";
  180. } else {
  181. if(postData.peisongType == 'zq' && this.data.shops && this.data.shopIndex == -1) {
  182. wx.showToast({
  183. title: '请选择自提门店',
  184. icon: 'none'
  185. })
  186. return;
  187. }
  188. const extJsonStr = {}
  189. if(postData.peisongType == 'zq') {
  190. if(!this.data.name) {
  191. wx.showToast({
  192. title: '请填写联系人',
  193. icon: 'none'
  194. })
  195. return;
  196. }
  197. if(!this.data.mobile) {
  198. wx.showToast({
  199. title: '请填写联系电话',
  200. icon: 'none'
  201. })
  202. return;
  203. }
  204. extJsonStr['联系人'] = this.data.name
  205. extJsonStr['联系电话'] = this.data.mobile
  206. }
  207. if(postData.peisongType == 'zq' && this.data.shops) {
  208. postData.shopIdZt = this.data.shops[this.data.shopIndex].id
  209. postData.shopNameZt = this.data.shops[this.data.shopIndex].name
  210. }
  211. postData.extJsonStr = JSON.stringify(extJsonStr)
  212. }
  213. WXAPI.orderCreate(postData).then(function (res) {
  214. that.data.pageIsEnd = true
  215. if (res.code != 0) {
  216. that.data.pageIsEnd = false
  217. wx.showModal({
  218. title: '错误',
  219. content: res.msg,
  220. showCancel: false
  221. })
  222. return;
  223. }
  224. if (e && "buyNow" != that.data.orderType) {
  225. // 清空购物车数据
  226. const keyArrays = []
  227. that.data.goodsList.forEach(ele => {
  228. keyArrays.push(ele.key)
  229. })
  230. WXAPI.shippingCarInfoRemoveItem(loginToken, keyArrays.join())
  231. }
  232. if (!e) {
  233. let hasNoCoupons = true
  234. let coupons = null
  235. if (res.data.couponUserList) {
  236. hasNoCoupons = false
  237. res.data.couponUserList.forEach(ele => {
  238. let moneyUnit = '元'
  239. if (ele.moneyType == 1) {
  240. moneyUnit = '%'
  241. }
  242. if (ele.moneyHreshold) {
  243. ele.nameExt = ele.name + ' [消费满' + ele.moneyHreshold + '元可减' + ele.money + moneyUnit +']'
  244. } else {
  245. ele.nameExt = ele.name + ' [减' + ele.money + moneyUnit + ']'
  246. }
  247. })
  248. coupons = res.data.couponUserList
  249. }
  250. // 计算积分抵扣规则 userScore
  251. let scoreDeductionRules = res.data.scoreDeductionRules
  252. if (scoreDeductionRules) {
  253. // 如果可叠加,计算可抵扣的最大积分数
  254. scoreDeductionRules.forEach(ele => {
  255. if (ele.loop) {
  256. let loopTimes = Math.floor(that.data.userScore / ele.score) // 按剩余积分取最大
  257. let loopTimesMax = Math.floor((res.data.amountTotle + res.data.deductionMoney) / ele.money) // 按金额取最大
  258. if (loopTimes > loopTimesMax) {
  259. loopTimes = loopTimesMax
  260. }
  261. ele.score = ele.score * loopTimes
  262. ele.money = ele.money * loopTimes
  263. }
  264. })
  265. // 剔除积分数为0的情况
  266. scoreDeductionRules = scoreDeductionRules.filter(ele => {
  267. return ele.score > 0
  268. })
  269. }
  270. that.setData({
  271. totalScoreToPay: res.data.score,
  272. isNeedLogistics: res.data.isNeedLogistics,
  273. allGoodsAndYunPrice: res.data.amountReal,
  274. yunPrice: res.data.amountLogistics,
  275. hasNoCoupons,
  276. coupons,
  277. deductionMoney: res.data.deductionMoney,
  278. couponAmount: res.data.couponAmount,
  279. scoreDeductionRules
  280. });
  281. that.data.pageIsEnd = false
  282. return;
  283. }
  284. that.processAfterCreateOrder(res)
  285. })
  286. },
  287. async processAfterCreateOrder(res) {
  288. // 直接弹出支付,取消支付的话,去订单列表
  289. const balance = this.data.balance
  290. if (balance || res.data.amountReal*1 == 0) {
  291. // 有余额
  292. const money = (res.data.amountReal * 1 - balance*1).toFixed(2)
  293. if (money <= 0) {
  294. // 余额足够
  295. wx.showModal({
  296. title: '请确认支付',
  297. content: `您当前可用余额¥${balance},使用余额支付¥${res.data.amountReal}?`,
  298. confirmText: "确认支付",
  299. cancelText: "暂不付款",
  300. success: res2 => {
  301. if (res2.confirm) {
  302. // 使用余额支付
  303. WXAPI.orderPay(wx.getStorageSync('token'), res.data.id).then(res3 => {
  304. if (res3.code != 0) {
  305. wx.showToast({
  306. title: res3.msg,
  307. icon: 'none'
  308. })
  309. return
  310. }
  311. wx.redirectTo({
  312. url: "/pages/order-list/index"
  313. })
  314. })
  315. } else {
  316. wx.redirectTo({
  317. url: "/pages/order-list/index"
  318. })
  319. }
  320. }
  321. })
  322. } else {
  323. // 余额不够
  324. wx.showModal({
  325. title: '请确认支付',
  326. content: `您当前可用余额¥${balance},仍需支付¥${money}`,
  327. confirmText: "确认支付",
  328. cancelText: "暂不付款",
  329. success: res2 => {
  330. if (res2.confirm) {
  331. // 使用余额支付
  332. wxpay.wxpay('order', money, res.data.id, "/pages/order-list/index");
  333. } else {
  334. wx.redirectTo({
  335. url: "/pages/order-list/index"
  336. })
  337. }
  338. }
  339. })
  340. }
  341. } else {
  342. // 没余额
  343. wxpay.wxpay('order', res.data.amountReal, res.data.id, "/pages/order-list/index");
  344. }
  345. },
  346. async initShippingAddress() {
  347. const res = await WXAPI.defaultAddress(wx.getStorageSync('token'))
  348. if (res.code == 0) {
  349. this.setData({
  350. curAddressData: res.data.info
  351. });
  352. } else {
  353. this.setData({
  354. curAddressData: null
  355. });
  356. }
  357. this.processYunfei();
  358. },
  359. processYunfei() {
  360. var goodsList = this.data.goodsList
  361. if (goodsList.length == 0) {
  362. return
  363. }
  364. const goodsJsonStr = []
  365. var isNeedLogistics = 0;
  366. let inviter_id = 0;
  367. let inviter_id_storge = wx.getStorageSync('referrer');
  368. if (inviter_id_storge) {
  369. inviter_id = inviter_id_storge;
  370. }
  371. for (let i = 0; i < goodsList.length; i++) {
  372. let carShopBean = goodsList[i];
  373. if (carShopBean.logistics || carShopBean.logisticsId) {
  374. isNeedLogistics = 1;
  375. }
  376. const _goodsJsonStr = {
  377. propertyChildIds: carShopBean.propertyChildIds
  378. }
  379. if (carShopBean.sku && carShopBean.sku.length > 0) {
  380. let propertyChildIds = ''
  381. carShopBean.sku.forEach(option => {
  382. propertyChildIds = propertyChildIds + ',' + option.optionId + ':' + option.optionValueId
  383. })
  384. _goodsJsonStr.propertyChildIds = propertyChildIds
  385. }
  386. if (carShopBean.additions && carShopBean.additions.length > 0) {
  387. let goodsAdditionList = []
  388. carShopBean.additions.forEach(option => {
  389. goodsAdditionList.push({
  390. pid: option.pid,
  391. id: option.id
  392. })
  393. })
  394. _goodsJsonStr.goodsAdditionList = goodsAdditionList
  395. }
  396. _goodsJsonStr.goodsId = carShopBean.goodsId
  397. _goodsJsonStr.number = carShopBean.number
  398. _goodsJsonStr.logisticsType = 0
  399. _goodsJsonStr.inviter_id = inviter_id
  400. goodsJsonStr.push(_goodsJsonStr)
  401. }
  402. this.setData({
  403. isNeedLogistics: isNeedLogistics,
  404. goodsJsonStr: JSON.stringify(goodsJsonStr)
  405. });
  406. this.createOrder();
  407. },
  408. addAddress: function () {
  409. wx.navigateTo({
  410. url: "/pages/address-add/index"
  411. })
  412. },
  413. selectAddress: function () {
  414. wx.navigateTo({
  415. url: "/pages/select-address/index"
  416. })
  417. },
  418. bindChangeCoupon: function (e) {
  419. const selIndex = e.detail.value;
  420. this.setData({
  421. curCoupon: this.data.coupons[selIndex],
  422. curCouponShowText: this.data.coupons[selIndex].nameExt
  423. });
  424. this.processYunfei()
  425. },
  426. radioChange (e) {
  427. this.setData({
  428. peisongType: e.detail.value
  429. })
  430. this.processYunfei()
  431. if (e.detail.value == 'zq') {
  432. this.fetchShops()
  433. }
  434. },
  435. cancelLogin() {
  436. wx.navigateBack()
  437. },
  438. processLogin(e) {
  439. if (!e.detail.userInfo) {
  440. wx.showToast({
  441. title: '已取消',
  442. icon: 'none',
  443. })
  444. return;
  445. }
  446. AUTH.register(this);
  447. },
  448. async fetchShops(){
  449. const res = await WXAPI.fetchShops()
  450. if (res.code == 0) {
  451. let shopIndex = this.data.shopIndex
  452. const shopInfo = wx.getStorageSync('shopInfo')
  453. if (shopInfo) {
  454. shopIndex = res.data.findIndex(ele => {
  455. return ele.id == shopInfo.id
  456. })
  457. }
  458. this.setData({
  459. shops: res.data,
  460. shopIndex
  461. })
  462. }
  463. },
  464. shopSelect(e) {
  465. this.setData({
  466. shopIndex: e.detail.value
  467. })
  468. },
  469. goMap() {
  470. const _this = this
  471. const shop = this.data.shops[this.data.shopIndex]
  472. const latitude = shop.latitude
  473. const longitude = shop.longitude
  474. wx.openLocation({
  475. latitude,
  476. longitude,
  477. scale: 18
  478. })
  479. },
  480. callMobile() {
  481. const shop = this.data.shops[this.data.shopIndex]
  482. wx.makePhoneCall({
  483. phoneNumber: shop.linkPhone,
  484. })
  485. },
  486. async getUserApiInfo() {
  487. const res = await WXAPI.userDetail(wx.getStorageSync('token'))
  488. if (res.code == 0) {
  489. this.setData({
  490. bindMobileStatus: res.data.base.mobile ? 1: 2, // 账户绑定的手机号码状态
  491. mobile: res.data.base.mobile,
  492. })
  493. }
  494. },
  495. async getPhoneNumber(e) {
  496. if (!e.detail.errMsg || e.detail.errMsg != "getPhoneNumber:ok") {
  497. wx.showToast({
  498. title: e.detail.errMsg,
  499. icon: 'none'
  500. })
  501. return;
  502. }
  503. const res = await WXAPI.bindMobileWxapp(wx.getStorageSync('token'), this.data.code, e.detail.encryptedData, e.detail.iv)
  504. AUTH.wxaCode().then(code => {
  505. this.data.code = code
  506. })
  507. if (res.code == 0) {
  508. wx.showToast({
  509. title: '读取成功',
  510. icon: 'success'
  511. })
  512. this.setData({
  513. mobile: res.data,
  514. bindMobileStatus: 1
  515. })
  516. } else {
  517. wx.showToast({
  518. title: res.msg,
  519. icon: 'none'
  520. })
  521. }
  522. },
  523. deductionScoreChange(event) {
  524. this.setData({
  525. deductionScore: event.detail,
  526. })
  527. this.processYunfei()
  528. },
  529. deductionScoreClick(event) {
  530. const { name } = event.currentTarget.dataset;
  531. this.setData({
  532. deductionScore: name,
  533. })
  534. this.processYunfei()
  535. },
  536. })