赛事取消报名通过接口显示退款金额

This commit is contained in:
马梓彭 2026-05-11 13:56:09 +08:00
parent 2b3a08e499
commit cf2724a6f1
2 changed files with 73 additions and 32 deletions

View File

@ -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({
});
}
});

View File

@ -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}`,