From cf2724a6f1b01c51b5ee0b9169c9eb9906011459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Mon, 11 May 2026 13:56:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=9B=E4=BA=8B=E5=8F=96=E6=B6=88=E6=8A=A5?= =?UTF-8?q?=E5=90=8D=E9=80=9A=E8=BF=87=E6=8E=A5=E5=8F=A3=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E9=87=91=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cancel-registration.js | 104 ++++++++++++------ utils/constants.js | 1 + 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/subpackages/mine/cancel-registration/cancel-registration.js b/subpackages/mine/cancel-registration/cancel-registration.js index 25493ec..9e029c1 100644 --- a/subpackages/mine/cancel-registration/cancel-registration.js +++ b/subpackages/mine/cancel-registration/cancel-registration.js @@ -23,14 +23,15 @@ Page({ data: { registrationId: null, loading: true, + calculating: false, refundRulesText: '退款规则以赛事说明为准', - // items: [{ itemKey, projectName, pills: [{ pillKey, label, price, selected }] }] items: [], selectAll: false, selectedCount: 0, - refundAmount: '0' + refundAmount: '0', + refundableAmount: '0' }, onLoad(options) { @@ -54,7 +55,6 @@ Page({ .then((detail) => { const d = detail && typeof detail === 'object' ? detail : {}; - // 检查报名状态,如果已取消(PaymentStatus=3),则提示用户 const paymentStatus = d.paymentStatus != null ? Number(d.paymentStatus) : null; if (paymentStatus === 3) { wx.showModal({ @@ -85,17 +85,19 @@ Page({ const label = [groupName, gender].filter(Boolean).join(' | ') || groupName || '参赛人'; return { pillKey: `i-${idx}-p-${pi}`, + personId: p.id, label, price, - selected: true + selected: false }; }) : [ { pillKey: `i-${idx}-g`, + groupId: it.id, label: groupName || '组别', price, - selected: true + selected: false } ]; @@ -106,32 +108,16 @@ Page({ }; }); - // 使用后端返回的退款金额和规则 const refundRulesText = d.refundRulesText || d.RefundRulesText || '退款规则以赛事说明为准'; - const refundAmountFromBackend = d.refundAmount != null ? toNumber(d.refundAmount) : (d.RefundAmount != null ? toNumber(d.RefundAmount) : null); - // 默认全选 this.setData({ items, - selectAll: items.length > 0, + selectAll: false, refundRulesText, loading: false }); - // 优先使用后端计算的退款金额,否则使用前端计算 - if (refundAmountFromBackend != null) { - const all = []; - this.data.items.forEach((it) => it.pills.forEach((p) => all.push(p))); - const selected = all.filter((p) => p.selected); - const selectAll = all.length > 0 && selected.length === all.length; - this.setData({ - selectedCount: selected.length, - selectAll, - refundAmount: formatMoney(refundAmountFromBackend) - }); - } else { - this.recalc(); - } + this.recalcFromBackend(); }) .catch((err) => { this.setData({ loading: false, items: [] }); @@ -147,7 +133,7 @@ Page({ pills: it.pills.map((p) => (p.pillKey === pillKey ? { ...p, selected: !p.selected } : p)) })); this.setData({ items }); - this.recalc(); + this.recalcFromBackend(); }, onToggleAll() { @@ -157,20 +143,59 @@ Page({ pills: it.pills.map((p) => ({ ...p, selected: next })) })); this.setData({ items, selectAll: next }); - this.recalc(); + this.recalcFromBackend(); }, - recalc() { + recalcFromBackend() { const all = []; this.data.items.forEach((it) => it.pills.forEach((p) => all.push(p))); const selected = all.filter((p) => p.selected); - const sum = selected.reduce((acc, p) => acc + toNumber(p.price, 0), 0); const selectAll = all.length > 0 && selected.length === all.length; + this.setData({ selectedCount: selected.length, - selectAll, - refundAmount: formatMoney(sum) + selectAll }); + + if (selected.length === 0) { + this.setData({ refundAmount: '0' }); + return; + } + + const personIds = []; + const cancelTeams = []; + selected.forEach((p) => { + if (p.personId) { + personIds.push(p.personId); + } else if (p.groupId) { + cancelTeams.push(`${p.groupId}_team`); + } + }); + + this.setData({ calculating: true }); + request({ + path: API.calculateRefundAmount, + method: 'POST', + needAuth: true, + data: { + registrationId: this.data.registrationId, + cancelType: selectAll ? 0 : 1, + personIds: personIds.length > 0 ? personIds : null, + cancelTeams: cancelTeams.length > 0 ? cancelTeams : null + } + }) + .then((result) => { + const r = result && typeof result === 'object' ? result : {}; + this.setData({ + calculating: false, + refundAmount: formatMoney(r.refundAmount), + refundableAmount: formatMoney(r.refundableAmount) + }); + }) + .catch((err) => { + this.setData({ calculating: false }); + wx.showToast({ title: (err && err.message) || '计算退款金额失败', icon: 'none' }); + }); }, onConfirmCancel() { @@ -188,6 +213,21 @@ Page({ }, submitCancelRegistration() { + const all = []; + this.data.items.forEach((it) => it.pills.forEach((p) => all.push(p))); + const selected = all.filter((p) => p.selected); + const selectAll = all.length > 0 && selected.length === all.length; + + const personIds = []; + const cancelTeams = []; + selected.forEach((p) => { + if (p.personId) { + personIds.push(p.personId); + } else if (p.groupId) { + cancelTeams.push(`${p.groupId}_team`); + } + }); + wx.showLoading({ title: '提交中...' }); request({ path: API.cancelRegistrationRefund, @@ -195,6 +235,9 @@ Page({ needAuth: true, data: { registrationId: this.data.registrationId, + cancelType: selectAll ? 0 : 1, + personIds: personIds.length > 0 ? personIds : null, + cancelTeams: cancelTeams.length > 0 ? cancelTeams : null, refundReason: '用户取消报名' } }) @@ -202,11 +245,9 @@ Page({ wx.hideLoading(); wx.showToast({ title: '退款申请已提交', icon: 'success' }); setTimeout(() => { - // 返回上一页并刷新数据 const pages = getCurrentPages(); if (pages.length > 1) { const prevPage = pages[pages.length - 2]; - // 如果上一页是 records 页面,通知它刷新 if (prevPage && prevPage.route && prevPage.route.includes('records')) { if (prevPage.initData) { prevPage.initData(true); @@ -222,4 +263,3 @@ Page({ }); } }); - diff --git a/utils/constants.js b/utils/constants.js index 8902b06..ad23362 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -12,6 +12,7 @@ const API = { myRegistrationDetail: (registrationId) => `/api/eventclient/my-registration/${registrationId}`, apply: '/api/eventclient/apply', calculateAmount: '/api/eventclient/calculate-amount', + calculateRefundAmount: '/api/eventclient/calculate-refund-amount', cancelRegistrationRefund: '/api/eventclient/cancel-registration-refund', couponValidate: '/api/eventclient/coupon/validate', syncPayment: (registrationId) => `/api/eventclient/sync-payment/${registrationId}`,