2026-04-09 23:45:36 +08:00

179 lines
5.0 KiB
JavaScript

const { API } = require('../../../utils/constants');
const { request } = require('../../../utils/http');
function toNumber(v, fallback = 0) {
const n = Number(v);
return Number.isFinite(n) ? n : fallback;
}
function formatMoney(v) {
const n = toNumber(v, 0);
return (Math.round(n * 100) / 100).toFixed(2).replace(/\.00$/, '');
}
function genderText(v) {
if (v == null) return '';
const s = String(v).toLowerCase();
if (s === 'male' || s === 'm' || s === '1') return '男';
if (s === 'female' || s === 'f' || s === '2') return '女';
return '';
}
Page({
data: {
registrationId: null,
loading: true,
refundRulesText: '退款规则以赛事说明为准',
// items: [{ itemKey, projectName, pills: [{ pillKey, label, price, selected }] }]
items: [],
selectAll: false,
selectedCount: 0,
refundAmount: '0'
},
onLoad(options) {
const registrationId = Number(options.registrationId);
this.setData({ registrationId });
if (!registrationId) {
this.setData({ loading: false });
wx.showToast({ title: '参数错误', icon: 'none' });
return;
}
this.fetchRegistrationDetail(registrationId);
},
fetchRegistrationDetail(registrationId) {
this.setData({ loading: true });
request({
path: API.myRegistrationDetail(registrationId),
method: 'GET',
needAuth: true
})
.then((detail) => {
const d = detail && typeof detail === 'object' ? detail : {};
const rawItems = Array.isArray(d.items) ? d.items : [];
const items = rawItems.map((it, idx) => {
const projectName = it.projectName || it.ProjectName || `项目${idx + 1}`;
const groupName = it.groupName || it.GroupName || '';
const price = it.price != null ? toNumber(it.price, 0) : 0;
const persons = Array.isArray(it.persons) ? it.persons : [];
const pills =
persons.length > 0
? persons.map((p, pi) => {
const gender = genderText(p.gender);
const label = [groupName, gender].filter(Boolean).join(' | ') || groupName || '参赛人';
return {
pillKey: `i-${idx}-p-${pi}`,
label,
price,
selected: true
};
})
: [
{
pillKey: `i-${idx}-g`,
label: groupName || '组别',
price,
selected: true
}
];
return {
itemKey: `it-${idx}`,
projectName,
pills
};
});
// 默认全选
this.setData({
items,
selectAll: items.length > 0,
loading: false
});
this.recalc();
})
.catch((err) => {
this.setData({ loading: false, items: [] });
wx.showToast({ title: (err && err.message) || '加载失败', icon: 'none' });
});
},
onTogglePill(e) {
const pillKey = e.currentTarget.dataset.pillkey;
if (!pillKey) return;
const items = this.data.items.map((it) => ({
...it,
pills: it.pills.map((p) => (p.pillKey === pillKey ? { ...p, selected: !p.selected } : p))
}));
this.setData({ items });
this.recalc();
},
onToggleAll() {
const next = !this.data.selectAll;
const items = this.data.items.map((it) => ({
...it,
pills: it.pills.map((p) => ({ ...p, selected: next }))
}));
this.setData({ items, selectAll: next });
this.recalc();
},
recalc() {
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)
});
},
onConfirmCancel() {
if (this.data.selectedCount === 0) return;
wx.showModal({
title: '确认取消报名?',
content: `本次预计退款金额 ¥${this.data.refundAmount}`,
cancelText: '取消',
confirmText: '确定',
success: (res) => {
if (!res || !res.confirm) return;
this.submitCancelRegistration();
}
});
},
submitCancelRegistration() {
wx.showLoading({ title: '提交中...' });
request({
path: API.cancelRegistrationRefund,
method: 'POST',
needAuth: true,
data: {
registrationId: this.data.registrationId,
refundReason: '用户取消报名'
}
})
.then(() => {
wx.hideLoading();
wx.showToast({ title: '退款申请已提交', icon: 'success' });
setTimeout(() => {
wx.navigateBack();
}, 1500);
})
.catch((err) => {
wx.hideLoading();
wx.showToast({ title: (err && err.message) || '提交失败,请稍后重试', icon: 'none' });
});
}
});