refund-confirm-popup.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { Get } from "../../../../lib/request/method";
  2. Component({
  3. properties: {
  4. visible: { type: Boolean, value: false },
  5. goodsName: { type: String, value: "" },
  6. goodsImage: { type: String, value: "" },
  7. goodsPrice: { type: String, value: "" },
  8. goodsMeta1: { type: String, value: "" },
  9. goodsMeta2: { type: String, value: "" },
  10. refundReason: { type: String, value: "" },
  11. refundStatus: { type: String, value: "" },
  12. refundAmount: { type: Number, value: 0 },
  13. maxAmount: { type: Number, value: 0 },
  14. proofImages: { type: Array, value: [] },
  15. showReceiptStatus: { type: Boolean, value: true },
  16. },
  17. data: {
  18. statusPickerVisible: false,
  19. statusPickerOptions: [] as Array<{ label: string; value: string }>,
  20. statusPickerValue: [] as string[],
  21. statusLabel: "",
  22. // 退款金额编辑器(整屏弹窗)
  23. amountEditorVisible: false,
  24. amountInput: "",
  25. },
  26. observers: {
  27. refundStatus(v: string) {
  28. const options = (this as any).data?.statusPickerOptions || [];
  29. const matched = options.find((item: any) => item.value === v);
  30. if (matched) {
  31. (this as any).setData({
  32. statusPickerValue: [v],
  33. statusLabel: matched.label,
  34. });
  35. }
  36. },
  37. visible(v: boolean) {
  38. if (v && (this as any).data?.statusPickerOptions?.length) {
  39. const currentValue = (this as any).data?.statusPickerValue?.[0];
  40. if (currentValue) {
  41. (this as any).triggerEvent("changeStatus", { status: currentValue });
  42. }
  43. }
  44. },
  45. },
  46. lifetimes: {
  47. attached() {
  48. (this as any).fetchStatusOptions();
  49. },
  50. },
  51. methods: {
  52. getStatusLabel(value: string): string {
  53. const options = (this as any).data?.statusPickerOptions || [];
  54. return options.find((item: any) => item.value === value)?.label || "";
  55. },
  56. async fetchStatusOptions() {
  57. try {
  58. const res = await Get<any[]>("/dict/getDicts");
  59. const dict = (res as any)?.data?.find(
  60. (item: any) => item.dictType === "aftersale_receipt_status"
  61. );
  62. if (dict?.items?.length) {
  63. const options = dict.items.map((item: any) => ({
  64. label: item.dictLabel,
  65. value: item.dictValue,
  66. }));
  67. // 默认选中最后一个(未收到货)
  68. const lastOption = options[options.length - 1];
  69. const current = (this as any).data?.refundStatus;
  70. const matched = options.find((item: any) => item.value === current);
  71. const value = matched ? current : lastOption.value;
  72. const label = matched ? matched.label : lastOption.label;
  73. (this as any).setData({
  74. statusPickerOptions: options,
  75. statusPickerValue: [value],
  76. statusLabel: label,
  77. });
  78. // 回传默认值给父页面
  79. (this as any).triggerEvent("changeStatus", { status: value });
  80. }
  81. } catch {
  82. wx.showToast({ title: "获取商品状态失败", icon: "none" });
  83. }
  84. },
  85. onPopupVisibleChange(e: WechatMiniprogram.CustomEvent<{ visible: boolean }>) {
  86. if (!e?.detail?.visible) {
  87. (this as any).triggerEvent("close");
  88. }
  89. },
  90. onAmountPopupVisibleChange(e: WechatMiniprogram.CustomEvent<{ visible: boolean }>) {
  91. if (!e?.detail?.visible) {
  92. (this as any).setData({ amountEditorVisible: false });
  93. }
  94. },
  95. onClose() {
  96. (this as any).triggerEvent("close");
  97. },
  98. onOpenStatusPicker() {
  99. (this as any).setData({ statusPickerVisible: true });
  100. },
  101. onStatusPickerChange(e: any) {
  102. const valueArr = e?.detail?.value as Array<string | number> | undefined;
  103. const status = String(valueArr?.[0] ?? "");
  104. (this as any).triggerEvent("changeStatus", { status });
  105. (this as any).setData({ statusPickerVisible: false });
  106. },
  107. onStatusPickerClose() {
  108. (this as any).setData({ statusPickerVisible: false });
  109. },
  110. onEditReason() {
  111. (this as any).triggerEvent("editReason");
  112. },
  113. onEditAmount() {
  114. const cur = Number((this as any).data?.refundAmount ?? 0);
  115. (this as any).setData({ amountInput: cur ? String(cur) : "0", amountEditorVisible: true });
  116. },
  117. onEditProof() {
  118. (this as any).triggerEvent("editProof");
  119. },
  120. onAmountInput(e: WechatMiniprogram.Input) {
  121. const raw = e.detail?.value || "";
  122. // 保留数字与小数点
  123. const cleaned = raw.replace(/[^\d.]/g, "");
  124. (this as any).setData({ amountInput: cleaned });
  125. },
  126. onAmountClose() {
  127. (this as any).setData({ amountEditorVisible: false });
  128. },
  129. onAmountConfirm() {
  130. const maxAmount = Number((this as any).data?.maxAmount ?? 0);
  131. const amount = Number((this as any).data?.amountInput ?? 0);
  132. if (!amount || Number.isNaN(amount)) {
  133. wx.showToast({ title: "请输入退款金额", icon: "none" });
  134. return;
  135. }
  136. if (maxAmount && amount > maxAmount) {
  137. wx.showToast({ title: "不能超过最高可退金额", icon: "none" });
  138. return;
  139. }
  140. const fixed = Number(amount.toFixed(2));
  141. (this as any).triggerEvent("amountConfirm", { amount: fixed });
  142. (this as any).setData({ amountEditorVisible: false });
  143. },
  144. onSubmit() {
  145. (this as any).triggerEvent("submit");
  146. },
  147. },
  148. });