order-detail.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. // pages/orders/order-detail.ts
  2. import { api_executeOrder, api_executePayment, api_queryByParamName, api_userPaymentOrderUnpaid } from "../../api/login";
  3. import { api_sysAreaQueryAllProvince, api_userReceiveAddressPage, api_userReceiveAddressSave } from "../../api/new";
  4. import { formatPrice } from "../../utils/util";
  5. // 获取应用实例
  6. const app = getApp<IAppOption>()
  7. Page({
  8. /**
  9. * 页面的初始数据
  10. */
  11. data: {
  12. status: 'ing',
  13. statusList: {
  14. ing: {
  15. logo: './images/ing.png',
  16. title: '等待付款',
  17. content: '请尽快完成支付,以便我们为您处理订单'
  18. },
  19. },
  20. backParams: null,
  21. addressList: [] as any,
  22. goodsInfo: {} as any,
  23. hasInstrument: false, // 是否有乐器
  24. receiveAddress: '', // 选择的地址信息
  25. receiveAddressInfo: {
  26. addressDetail: '',
  27. name: '',
  28. phoneNumber: ''
  29. },
  30. userBeneficiaryId: '', // 添加购买人信息
  31. paymentType: null as any, // 支付类型
  32. paymentChannel: null as any,
  33. showService: false,
  34. showArea: false,
  35. areaList: [] as any,
  36. currentValues: [] as any,
  37. addressShow: false,
  38. addressAfterLeave: false,
  39. // 添加地址表单信息
  40. id: "",
  41. name: '',
  42. phoneNumber: '',
  43. detailAddress: '',
  44. cityCode: 0,
  45. cityName: "",
  46. provinceCode: 0,
  47. provinceName: "",
  48. regionCode: '',
  49. regionName: "",
  50. },
  51. /**
  52. * 生命周期函数--监听页面加载
  53. */
  54. onLoad(options: any) {
  55. this.queryPayType()
  56. if (options.orderInfo) {
  57. console.log('goods', options)
  58. const goods = JSON.parse(decodeURIComponent(options.orderInfo));
  59. console.log(goods, 'goods', options)
  60. const infos = {
  61. allSalePrice: 0,
  62. allOriginPrice: 0,
  63. allDiscountPrice: '',
  64. discountIntegerPart: '',
  65. discountDecimalPart: '',
  66. integerPart: '',
  67. decimalPart: '',
  68. name: '',
  69. shopId: '',
  70. orderNo: options.orderNo || '',
  71. goodsList: [] as any
  72. }
  73. // 是否有乐器
  74. let hasInstrument = false
  75. for (let i in goods) {
  76. const item = goods[i]
  77. if (item.goodsType === "INSTRUMENTS") {
  78. hasInstrument = true
  79. }
  80. infos.name = infos.name ? infos.name + '+' + item.name : item.name
  81. infos.shopId = item.shopId
  82. const afterPrice: any = formatPrice(item.salePrice)
  83. // console.log(infos.goodsList, 'infos.goodsList')
  84. infos.goodsList.push({
  85. ...item,
  86. typePeriod: this.formatPeriod(item.num, item.period),
  87. ...afterPrice
  88. })
  89. infos.allSalePrice += Number(item.salePrice)
  90. infos.allOriginPrice += Number(item.originalPrice)
  91. }
  92. const allAfterPrice: any = formatPrice(infos.allSalePrice)
  93. // console.log(infos.allOriginPrice, infos.allSalePrice)
  94. infos.allDiscountPrice = formatPrice(infos.allOriginPrice - infos.allSalePrice, 'ALL') as string
  95. const allDiscount: any = formatPrice(infos.allOriginPrice - infos.allSalePrice)
  96. infos.integerPart = allAfterPrice.integerPart
  97. infos.decimalPart = allAfterPrice.decimalPart
  98. infos.discountIntegerPart = allDiscount.integerPart
  99. infos.discountDecimalPart = allDiscount.decimalPart
  100. // console.log(infos, 'infos')
  101. this.setData({
  102. goodsInfo: infos,
  103. userBeneficiaryId: options.userBeneficiaryId,
  104. status: options.status || '',
  105. hasInstrument
  106. });
  107. }
  108. },
  109. // 格式化类型
  110. formatPeriod(num: number, type: string) {
  111. if (!type) return ''
  112. const template: any = {
  113. DAY: "天",
  114. MONTH: "个月",
  115. YEAR: "年"
  116. }
  117. if (type === "YEAR" && num >= 99) {
  118. return '永久'
  119. }
  120. return num + (template[type] || '')
  121. },
  122. // 获取后台配置的支付方式
  123. async queryPayType() {
  124. try {
  125. // wxlite_payment_service_provider
  126. const { data } = await api_queryByParamName({
  127. paramName: app.globalData.appId
  128. });
  129. if (data.code == 200) {
  130. const paramValue = data.data.paramValue ? JSON.parse(data.data.paramValue) : {}
  131. this.setData({
  132. paymentType: paramValue.vendor,
  133. paymentChannel: paramValue.channel
  134. });
  135. }
  136. } catch (error) {
  137. console.log(error, "error");
  138. }
  139. },
  140. /** 添加收货地址 */
  141. onSelectAddress() {
  142. console.log(this.data.addressList.length > 0, this.data.receiveAddress)
  143. if (this.data.addressList.length > 0 || this.data.receiveAddress) {
  144. wx.navigateTo({
  145. url: `../address/index?receiveAddress=${this.data.receiveAddress}`,
  146. })
  147. } else {
  148. this.onShowAddress()
  149. }
  150. },
  151. onPayError(message?: string) {
  152. wx.hideLoading()
  153. wx.showToast({
  154. title: message || '支付取消',
  155. icon: 'none'
  156. })
  157. },
  158. // 购买
  159. async onSubmit() {
  160. if (!this.data.receiveAddress && this.data.hasInstrument) {
  161. wx.showToast({
  162. title: '请选择收货地址',
  163. icon: 'none'
  164. })
  165. return
  166. }
  167. wx.showLoading({
  168. mask: true,
  169. title: "订单提交中...",
  170. });
  171. try {
  172. const { allSalePrice, shopId, name, orderNo, goodsList } = this.data.goodsInfo
  173. const goodsInfos: any = []
  174. goodsList.forEach((item: any) => {
  175. goodsInfos.push({
  176. "goodsId": item.id,
  177. "goodsNum": 1,
  178. "goodsType": item.goodsType,
  179. "paymentCashAmount": item.salePrice,
  180. "paymentCouponAmount": 0
  181. })
  182. })
  183. if (orderNo) {
  184. const { data } = await api_userPaymentOrderUnpaid({
  185. orderNo: orderNo,
  186. paymentType: 'WECHAT_MINI'
  187. })
  188. if (data.code === 200) {
  189. const { paymentConfig, paymentType, orderNo } = data.data.paymentConfig
  190. this.onExecutePay(paymentConfig, paymentType, orderNo)
  191. } else {
  192. this.onPayError()
  193. }
  194. } else {
  195. const { data } = await api_executeOrder({
  196. "orderType": "WECHAT_MINI",
  197. "paymentType": this.data.paymentType,
  198. "paymentCashAmount": allSalePrice,
  199. "paymentCouponAmount": 0,
  200. "shopId": shopId,
  201. "openId": app.globalData.userInfo?.liteOpenid,
  202. "goodsInfos": goodsInfos,
  203. receiveAddress: this.data.receiveAddress,
  204. userBeneficiaryId: this.data.userBeneficiaryId,
  205. "orderName": name,
  206. "orderDesc": name
  207. })
  208. if (data.code === 200) {
  209. const { paymentConfig, paymentType, orderNo } = data.data
  210. this.onExecutePay(paymentConfig, paymentType, orderNo)
  211. } else if (data.code === 5200) {
  212. wx.hideLoading()
  213. wx.showToast({
  214. title: data.message,
  215. icon: 'none'
  216. })
  217. } else if ([5435, 5436, 5437, 5439, 5442, 5443, 5408, 5427, 5432].includes(data.code)) {
  218. wx.hideLoading()
  219. wx.showToast({
  220. title: data.message,
  221. icon: 'none'
  222. })
  223. setTimeout(() => {
  224. wx.navigateBack()
  225. }, 1000);
  226. } else {
  227. this.onPayError()
  228. }
  229. }
  230. } catch {
  231. wx.hideLoading()
  232. }
  233. },
  234. async onExecutePay(paymentConfig: any, paymentType: string, orderNo: string) {
  235. wx.login({
  236. success: async (wxres: any) => {
  237. const res = await api_executePayment({
  238. merOrderNo: paymentConfig.merOrderNo,
  239. paymentChannel: this.data.paymentChannel || 'wx_lite', // 'wx_pub', //
  240. paymentType,
  241. userId: app.globalData.userInfo?.id,
  242. code: wxres.code,
  243. wxMiniAppId: app.globalData.appId
  244. // code: '011yjYkl289aye4q2zml24UEWT3yjYkn',
  245. // wxPubAppId: 'wxbde13f59d40cb4f2'
  246. })
  247. wx.hideLoading()
  248. if (res.data.code === 200) {
  249. this.onPay(paymentType, res.data.data.reqParams, orderNo)
  250. } else if ([5435, 5436, 5437, 5439, 5442, 5443, 5408, 5427, 5432].includes(res.data.code)) {
  251. wx.hideLoading()
  252. wx.showToast({
  253. title: res.data.message,
  254. icon: 'none'
  255. })
  256. setTimeout(() => {
  257. wx.navigateBack()
  258. }, 1000);
  259. } else {
  260. this.onPayError(res.data.message)
  261. }
  262. },
  263. fail: () => {
  264. this.onPayError()
  265. }
  266. })
  267. },
  268. onPay(paymentType: string, paymentConfig: any, orderNo: string) {
  269. const isYeePay = paymentType.indexOf('yeepay') !== -1
  270. const prePayInfo = isYeePay ? JSON.parse(paymentConfig.prePayTn)
  271. : paymentConfig?.expend
  272. ? JSON.parse(paymentConfig?.expend?.pay_info)
  273. : paymentConfig
  274. const that = this
  275. wx.requestPayment({
  276. timeStamp: prePayInfo.timeStamp,
  277. nonceStr: prePayInfo.nonceStr,
  278. package: prePayInfo.package ? prePayInfo.package : prePayInfo.packageValue,
  279. paySign: prePayInfo.paySign,
  280. signType: prePayInfo.signType ? prePayInfo.signType : 'MD5',
  281. success() {
  282. wx.showToast({ title: '支付成功', icon: 'success' });
  283. wx.redirectTo({
  284. url: '/pages/orders/order-result?orderNo=' + orderNo
  285. })
  286. },
  287. fail(ressonInfo) {
  288. console.log('支付失败', ressonInfo)
  289. that.onPayError()
  290. const goodsInfo = that.data.goodsInfo
  291. goodsInfo.orderNo = orderNo
  292. that.setData({
  293. goodsInfo
  294. })
  295. }
  296. })
  297. },
  298. /** 客服 */
  299. onService() {
  300. console.log("showService")
  301. this.setData({
  302. showService: true
  303. })
  304. },
  305. changePop(event: { detail: any }) {
  306. this.setData({
  307. showService: event.detail
  308. })
  309. },
  310. /**
  311. * 生命周期函数--监听页面初次渲染完成
  312. */
  313. onReady() {
  314. },
  315. /**
  316. * 生命周期函数--监听页面显示
  317. */
  318. onShow() {
  319. if (this.data.backParams) {
  320. console.log(this.data.backParams, 'backParams'); // { key: 'value' }
  321. const backParams: any = this.data.backParams || {};
  322. this.setData({
  323. receiveAddress: backParams.receiveAddress,
  324. receiveAddressInfo: backParams.receiveAddressInfo,
  325. backParams: null // 清空参数
  326. })
  327. }
  328. this.getAddress()
  329. },
  330. /**
  331. * 生命周期函数--监听页面隐藏
  332. */
  333. onHide() {
  334. },
  335. /**
  336. * 生命周期函数--监听页面卸载
  337. */
  338. onUnload() {
  339. },
  340. /**
  341. * 页面相关事件处理函数--监听用户下拉动作
  342. */
  343. onPullDownRefresh() {
  344. },
  345. /**
  346. * 页面上拉触底事件的处理函数
  347. */
  348. onReachBottom() {
  349. },
  350. /** 地址列表 */
  351. async getAddress() {
  352. try {
  353. const { data } = await api_userReceiveAddressPage({ page: 1, rows: -1 })
  354. this.setData({
  355. addressList: data.data.rows || []
  356. }, () => {
  357. if (this.data.addressList.length <= 0) {
  358. this.getAreas()
  359. }
  360. })
  361. } catch {
  362. //
  363. }
  364. },
  365. /** 获取省市区 */
  366. async getAreas() {
  367. try {
  368. const { data } = await api_sysAreaQueryAllProvince({})
  369. const areaList: any = this.formateArea(data.data)
  370. const currentValues = []
  371. if (areaList?.province_list) {
  372. // 获取第一个键值对
  373. const firstKey = Object.keys(areaList?.province_list)[0];
  374. // 通过键获取值
  375. const firstValue = areaList?.province_list[firstKey];
  376. currentValues.push({
  377. code: firstKey,
  378. name: firstValue
  379. })
  380. }
  381. if (areaList?.city_list) {
  382. // 获取第一个键值对
  383. const firstKey = Object.keys(areaList?.city_list)[0];
  384. // 通过键获取值
  385. const firstValue = areaList?.city_list[firstKey];
  386. currentValues.push({
  387. code: firstKey,
  388. name: firstValue
  389. })
  390. }
  391. if (areaList?.county_list) {
  392. // 获取第一个键值对
  393. const firstKey = Object.keys(areaList?.county_list)[0];
  394. // 通过键获取值
  395. const firstValue = areaList?.county_list[firstKey];
  396. currentValues.push({
  397. code: firstKey,
  398. name: firstValue
  399. })
  400. }
  401. console.log(areaList,
  402. currentValues)
  403. this.setData({
  404. areaList,
  405. currentValues
  406. })
  407. } catch {
  408. //
  409. }
  410. },
  411. formateArea(area: any[]) {
  412. const province_list: { [_: string]: string } = {};
  413. const city_list: { [_: string]: string } = {};
  414. const county_list: { [_: string]: string } = {};
  415. area.forEach((item: any) => {
  416. province_list[item.code] = item.name;
  417. });
  418. area.forEach((item: any) => {
  419. item.areas && item.areas.forEach((city: any) => {
  420. city_list[city.code] = city.name;
  421. });
  422. });
  423. area.forEach((item: any) => {
  424. item.areas && item.areas.forEach((city: any) => {
  425. city.areas && city.areas.forEach((county: any) => {
  426. county_list[county.code] = county.name;
  427. });
  428. });
  429. });
  430. return {
  431. province_list,
  432. city_list,
  433. county_list
  434. };
  435. },
  436. /** 显示选择地区 */
  437. async onShowAreaList() {
  438. this.setData({
  439. showArea: true
  440. })
  441. },
  442. /** 关闭选择地区 */
  443. onCloseAreaList() {
  444. this.setData({
  445. showArea: false
  446. })
  447. },
  448. /** 确定选择地区 */
  449. submitArea(e: any) {
  450. const selectedOptions: any = e.detail.values
  451. this.setData({
  452. provinceCode: selectedOptions[0].code,
  453. cityCode: selectedOptions[1].code,
  454. regionCode: selectedOptions[2].code,
  455. provinceName: selectedOptions[0].name,
  456. cityName: selectedOptions[1].name,
  457. regionName: selectedOptions[2].name,
  458. showArea: false,
  459. })
  460. },
  461. onShowAddress() {
  462. this.setData({
  463. addressAfterLeave: false,
  464. addressShow: true
  465. })
  466. },
  467. onCloseAddress() {
  468. this.setData({
  469. addressShow: false
  470. })
  471. },
  472. onAddressAfterLeave() {
  473. this.setData({
  474. addressAfterLeave: true,
  475. name: '',
  476. phoneNumber: '',
  477. detailAddress: '',
  478. cityCode: 0,
  479. cityName: "",
  480. provinceCode: 0,
  481. provinceName: "",
  482. regionCode: '',
  483. regionName: "",
  484. })
  485. },
  486. /** 创建/修改收货地址 */
  487. async onOperationAddress() {
  488. const addressForm = this.data
  489. try {
  490. if (!addressForm.name) {
  491. wx.showToast({
  492. title: '请输入收货人姓名',
  493. icon: "none"
  494. })
  495. return
  496. }
  497. if (!addressForm.phoneNumber || !/^1[3456789]\d{9}$/.test(addressForm.phoneNumber)) {
  498. wx.showToast({
  499. title: '请输入正确的手机号码',
  500. icon: "none"
  501. })
  502. return
  503. }
  504. if (!addressForm.provinceCode || !addressForm.cityCode || !addressForm.regionCode) {
  505. wx.showToast({
  506. title: '请选择地区',
  507. icon: "none"
  508. })
  509. return
  510. }
  511. if (!addressForm.detailAddress) {
  512. wx.showToast({
  513. title: '请输入详细地址',
  514. icon: "none"
  515. })
  516. return
  517. }
  518. const params = {
  519. name: addressForm.name,
  520. phoneNumber: addressForm.phoneNumber,
  521. province: addressForm.provinceCode,
  522. city: addressForm.cityCode,
  523. region: addressForm.regionCode,
  524. detailAddress: addressForm.detailAddress
  525. }
  526. const { data } = await api_userReceiveAddressSave({
  527. ...params
  528. })
  529. wx.showToast({
  530. title: '添加成功',
  531. icon: 'none'
  532. })
  533. this.setData({
  534. receiveAddress: data.data, // 选择的地址信息
  535. receiveAddressInfo: {
  536. addressDetail: addressForm.provinceName + addressForm.cityName + addressForm.regionName + addressForm.detailAddress,
  537. name: addressForm.name,
  538. phoneNumber: addressForm.phoneNumber
  539. }
  540. })
  541. this.onCloseAddress()
  542. } catch (e) {
  543. //
  544. console.log(e, '1212')
  545. }
  546. },
  547. /**
  548. * 用户点击右上角分享
  549. */
  550. onShareAppMessage() {
  551. return {
  552. title: '器乐数字AI工具',
  553. path: '/pages/index/index',
  554. imageUrl: 'https://oss.dayaedu.com/ktyq/1733312164991.png'
  555. }
  556. }
  557. })