order-list.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  2. import tickleBehavior, {
  3. getTickleContext,
  4. } from "../../../../core/behavior/tickle.behavior";
  5. import { handleWeChatPayment, getFullImageUrl } from "../../../../utils/util";
  6. import {
  7. orderListMethod,
  8. orderCancelMethod,
  9. orderPayMethod,
  10. } from "../../request";
  11. import I18nBehavior from "../../../../i18n/behavior";
  12. // module/article/pages/order-list/order-list.ts
  13. const i18n = {
  14. orderText: {
  15. mineOrder: "我的服务",
  16. paying: "待确认",
  17. paid: "已确认",
  18. paySuccess: "已完成",
  19. },
  20. };
  21. Page({
  22. behaviors: [PageContainerBehavior, tickleBehavior,I18nBehavior],
  23. properties: {},
  24. data: {
  25. i18n,
  26. showConfirm: false,
  27. currentTab: "all", // 当前选中的标签
  28. orders: [],
  29. filteredOrders: [], // 用于存储过滤后的订单
  30. patientId: 0,
  31. id: "",
  32. statusObj: {
  33. 0: "待付款",
  34. // 6: "待收货",
  35. 6: "已付款",
  36. 345: "交易成功",
  37. 2: "交易关闭",
  38. },
  39. statusClassObj: {
  40. 0: "status-pending",
  41. 6: "status-received",
  42. 345: "status-completed",
  43. 2: "status-closed",
  44. },
  45. selectedAddress: null,
  46. paying: false,
  47. payingId: '',
  48. showAddress: false,
  49. // 节流控制
  50. throttleTimers: {} as Record<string, boolean>,
  51. expandedItems: {} as Record<string, boolean>,
  52. },
  53. computed: {},
  54. // 节流 - 防止短时间内重复点击
  55. throttle(func: Function, delay: number = 1000, key: string = "default") {
  56. return (...args: any[]) => {
  57. // 如果该按钮正在节流中,直接返回
  58. if (this.data.throttleTimers[key]) {
  59. return;
  60. }
  61. // 设置节流定时器
  62. this.setData({
  63. [`throttleTimers.${key}`]: true,
  64. });
  65. // 执行函数
  66. const result = func.apply(this, args);
  67. // 延迟清除节流状态
  68. setTimeout(() => {
  69. this.setData({
  70. [`throttleTimers.${key}`]: false,
  71. });
  72. }, delay);
  73. return result;
  74. };
  75. },
  76. onLoad(options: any) {
  77. // 读取 tab 参数,默认为 all
  78. const tab = options?.tab || "all";
  79. this.setData({ currentTab: tab });
  80. },
  81. onShow() {
  82. this.filterOrdersList(this.data.currentTab);
  83. },
  84. // 切换tab
  85. onTabChange(event: any) {
  86. const type = event.detail.value;
  87. this.setData({ currentTab: type });
  88. this.filterOrdersList(type);
  89. },
  90. // 获取列表数据
  91. async getOrderList(progress: string) {
  92. const patientId = wx.getStorageSync("patientId");
  93. if (!patientId) {
  94. getTickleContext.call(this).showWarnMessage("请先登录");
  95. return;
  96. }
  97. const res = await orderListMethod(patientId, progress);
  98. if (res && res.data) {
  99. res.data.forEach((item: any) => {
  100. item.address = `${item.provinceName}${item.cityName}${item.areaName}${item.detailAddress}`;
  101. item.liaison =
  102. item.liaison !== null && item.liaison !== undefined
  103. ? item.liaison
  104. : "";
  105. item.phone =
  106. item.phone !== null && item.phone !== undefined ? item.phone : "";
  107. if (
  108. !item.provinceName ||
  109. !item.cityName ||
  110. !item.areaName ||
  111. !item.detailAddress ||
  112. !item.liaison ||
  113. !item.phone
  114. ) {
  115. item.showAddress = false;
  116. } else {
  117. item.showAddress = true;
  118. }
  119. if (item.items && Array.isArray(item.items)) {
  120. item.items = item.items.map((subItem: any) => {
  121. return {
  122. id: subItem.id || '',
  123. name: subItem.conditioningProgramName || '',
  124. description: (() => {
  125. const dose = subItem?.convertDose ?? '1';
  126. const unit = subItem?.convertUnit ?? '次';
  127. return `${dose} ${unit}`;
  128. })(),
  129. photo: getFullImageUrl(subItem.conditioningProgramPhoto) || '',
  130. price: subItem.unitPrice || 0,
  131. quantity: subItem?.totalMeasure || 0,
  132. }
  133. });
  134. }
  135. });
  136. // 批量初始化展开状态为false(默认折叠)
  137. const expandedItems: Record<string, boolean> = {};
  138. res.data.forEach((item: any) => {
  139. if (!this.data.expandedItems[item.id]) {
  140. expandedItems[item.id] = false;
  141. }
  142. });
  143. if (Object.keys(expandedItems).length > 0) {
  144. this.setData({ expandedItems: { ...this.data.expandedItems, ...expandedItems } });
  145. }
  146. res.data.forEach((item: any) => {
  147. item.photo = getFullImageUrl(item.photo);
  148. });
  149. this.setData({ orders: res.data });
  150. }
  151. },
  152. // 过滤订单l列表
  153. filterOrdersList(type: any) {
  154. // 根据当前选中的标签过滤订单
  155. switch (type) {
  156. // 全部订单
  157. case "all":
  158. this.getOrderList("");
  159. break;
  160. // 待付款订单
  161. case "pending":
  162. this.getOrderList("0");
  163. break;
  164. // 已付款订单
  165. case "paid":
  166. this.getOrderList("6");
  167. break;
  168. // 交易完成订单
  169. case "completed":
  170. this.getOrderList("345");
  171. break;
  172. // 交易关闭订单
  173. case "closed":
  174. this.getOrderList("2");
  175. break;
  176. default:
  177. break;
  178. }
  179. },
  180. // 订单支付
  181. onPay: function (event: any) {
  182. return this.throttle(
  183. async (e: any) => {
  184. const orderId = e.currentTarget.dataset.id;
  185. if (this.data.payingId) return; // 防重复
  186. this.setData({ paying: true, payingId: orderId });
  187. try {
  188. // 调用支付接口
  189. const payResult = await orderPayMethod(orderId);
  190. if (payResult && payResult.data) {
  191. const paymentParams = payResult.data;
  192. handleWeChatPayment(paymentParams, (res: any) => {
  193. // 支付成功,跳转到成功页面
  194. wx.redirectTo({
  195. url: "/module/article/pages/success-page/success-page?title=订单支付成功",
  196. });
  197. }, (error: any) => {
  198. this.setData({ paying: false, payingId: '' });
  199. if (error.errMsg === 'requestPayment:fail cancel') {
  200. wx.showToast({
  201. title: "支付已取消",
  202. icon: "none",
  203. });
  204. } else {
  205. wx.showToast({
  206. title: error.errMsg || "支付失败,请重试",
  207. icon: "none",
  208. });
  209. }
  210. });
  211. } else {
  212. wx.showToast({
  213. title: payResult.errMsg,
  214. icon: "none",
  215. });
  216. }
  217. } catch (error: any) {
  218. wx.showToast({
  219. title: error.errMsg,
  220. icon: "none",
  221. });
  222. } finally {
  223. this.setData({ paying: false, payingId: '' });
  224. }
  225. },
  226. 2000,
  227. "pay"
  228. )(event);
  229. },
  230. // 查看物流
  231. onSeeLogistics: function (e: any) {
  232. return this.throttle(
  233. (event: any) => {
  234. wx.showToast({
  235. title: "暂未开通",
  236. icon: "none",
  237. });
  238. },
  239. 2000,
  240. "logistics"
  241. )(e);
  242. },
  243. // 切换地址
  244. changeAddress: function (e: any) {
  245. return this.throttle(
  246. (event: any) => {
  247. const orderStatus = event.currentTarget.dataset.status;
  248. const id = event.currentTarget.dataset.id;
  249. // 根据订单状态判断是否可以切换地址. 待付款状态下可以切换地址
  250. if (orderStatus === "0") {
  251. wx.navigateTo({
  252. url:
  253. "/module/article/pages/manage-address/manage-address?type=orderList&orderId=" +
  254. id,
  255. });
  256. }
  257. },
  258. 2000,
  259. "changeAddress"
  260. )(e);
  261. },
  262. // 打开取消订单弹窗
  263. onCancel: function (event: any) {
  264. return this.throttle(
  265. (e: any) => {
  266. const orderId = e.currentTarget.dataset.id;
  267. // 处理订单取消逻辑
  268. this.setData({ id: orderId });
  269. this.setData({ showConfirm: true });
  270. },
  271. 2000,
  272. "cancel"
  273. )(event);
  274. },
  275. // 取消订单
  276. async cancelOrder(id: string) {
  277. this.setData({ showConfirm: true });
  278. try {
  279. await orderCancelMethod(id);
  280. /* 取消订单逻辑 */
  281. this.setData({ showConfirm: false });
  282. wx.navigateTo({
  283. url: "/module/article/pages/success-page/success-page?title=订单取消成功",
  284. });
  285. } catch (error: any) {
  286. getTickleContext.call(this).showWarnMessage(error.errMsg);
  287. }
  288. },
  289. // 确认取消订单
  290. confirmCancelDialog() {
  291. this.cancelOrder(this.data.id);
  292. },
  293. // 关闭取消订单弹窗
  294. closeDialog() {
  295. this.setData({ showConfirm: false });
  296. },
  297. // 确认收货
  298. onConfirmReceiving: function (e: any) {
  299. return this.throttle(
  300. (event: any) => {
  301. const orderId = event.currentTarget.dataset.id;
  302. wx.navigateTo({
  303. url: `/module/article/pages/confirm-receiving/confirm-receiving?orderId=${orderId}`,
  304. });
  305. },
  306. 2000,
  307. "confirmReceiving"
  308. )(e);
  309. },
  310. // 切换地址
  311. onChangeAddress(e: any) {
  312. const orderId = e.currentTarget.dataset.id;
  313. // 打开地址选择器,选择后更新对应订单的地址
  314. // 伪代码
  315. wx.chooseAddress({
  316. success: (res) => {
  317. // 假设你有 orders 数组
  318. const idx = this.data.orders.findIndex(
  319. (o: any) => o.orderId === orderId
  320. );
  321. if (idx !== -1) {
  322. this.setData({
  323. [`orders[${idx}].address`]: res.detailInfo,
  324. });
  325. }
  326. },
  327. });
  328. },
  329. // 订单详情
  330. onOrderDetail(e: any) {
  331. const id = e.currentTarget.dataset.id;
  332. const status = e.currentTarget.dataset.status;
  333. if (status === '0') {
  334. wx.navigateTo({
  335. url: `/module/order/pages/order-detail/order-detail?id=${id}&status=${status}`,
  336. });
  337. } else {
  338. wx.navigateTo({
  339. url: `/module/order/pages/other-detail/other-detail?id=${id}&status=${status}`,
  340. });
  341. }
  342. },
  343. //回到我的页面
  344. goMine() {
  345. wx.redirectTo({
  346. url: "/pages/mine/mine",
  347. });
  348. },
  349. // 切换服务包展开/收起
  350. toggleServicePackages(e: any) {
  351. const orderId = e.currentTarget.dataset.id;
  352. const currentExpanded = this.data.expandedItems[orderId] || false;
  353. this.setData({
  354. [`expandedItems[${orderId}]`]: !currentExpanded,
  355. });
  356. },
  357. });