266 lines
7.8 KiB
JavaScript
266 lines
7.8 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,
|
|
calculating: false,
|
|
|
|
refundRulesText: '退款规则以赛事说明为准',
|
|
|
|
items: [],
|
|
selectAll: false,
|
|
selectedCount: 0,
|
|
refundAmount: '0',
|
|
refundableAmount: '0',
|
|
actualPaidAmount: '',
|
|
refundedAmount: '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 paymentStatus = d.paymentStatus != null ? Number(d.paymentStatus) : null;
|
|
if (paymentStatus === 3) {
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '该报名已取消,无法继续操作',
|
|
showCancel: false,
|
|
confirmText: '确定',
|
|
success: () => {
|
|
wx.navigateBack();
|
|
}
|
|
});
|
|
this.setData({ loading: false });
|
|
return;
|
|
}
|
|
|
|
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}`,
|
|
personId: p.id,
|
|
label,
|
|
price,
|
|
selected: false
|
|
};
|
|
})
|
|
: [
|
|
{
|
|
pillKey: `i-${idx}-g`,
|
|
groupId: it.id,
|
|
label: groupName || '组别',
|
|
price,
|
|
selected: false
|
|
}
|
|
];
|
|
|
|
return {
|
|
itemKey: `it-${idx}`,
|
|
projectName,
|
|
pills
|
|
};
|
|
});
|
|
|
|
const refundRulesText = d.refundRulesText || d.RefundRulesText || '退款规则以赛事说明为准';
|
|
|
|
this.setData({
|
|
items,
|
|
selectAll: false,
|
|
refundRulesText,
|
|
loading: false
|
|
});
|
|
|
|
this.recalcFromBackend();
|
|
})
|
|
.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.recalcFromBackend();
|
|
},
|
|
|
|
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.recalcFromBackend();
|
|
},
|
|
|
|
recalcFromBackend() {
|
|
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
|
|
});
|
|
|
|
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,
|
|
// 如果没有选择项目,退款金额显示为 0
|
|
refundAmount: selected.length > 0 ? formatMoney(r.refundAmount) : '0',
|
|
refundableAmount: formatMoney(r.refundableAmount),
|
|
actualPaidAmount: formatMoney(r.actualPaidAmount),
|
|
refundedAmount: formatMoney(r.refundedAmount)
|
|
});
|
|
})
|
|
.catch((err) => {
|
|
this.setData({ calculating: false });
|
|
wx.showToast({ title: (err && err.message) || '计算退款金额失败', icon: 'none' });
|
|
});
|
|
},
|
|
|
|
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() {
|
|
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,
|
|
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,
|
|
refundReason: '用户取消报名'
|
|
}
|
|
})
|
|
.then(() => {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '退款申请已提交', icon: 'success' });
|
|
setTimeout(() => {
|
|
const pages = getCurrentPages();
|
|
if (pages.length > 1) {
|
|
const prevPage = pages[pages.length - 2];
|
|
if (prevPage && prevPage.route && prevPage.route.includes('records')) {
|
|
if (prevPage.initData) {
|
|
prevPage.initData(true);
|
|
}
|
|
}
|
|
}
|
|
wx.navigateBack();
|
|
}, 1500);
|
|
})
|
|
.catch((err) => {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: (err && err.message) || '提交失败,请稍后重试', icon: 'none' });
|
|
});
|
|
}
|
|
});
|