order-detail.ts 17 KB

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