2026-04-04 18:57:50 +08:00

190 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { API } = require('../../utils/constants');
const { request } = require('../../utils/http');
const { formatDateTime } = require('../../utils/format');
// 中文数字映射(项目一、二、三…)
const CN_NUM = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
/**
* 将 projects 数组转换为按项目分组的结构
* 每个项目下展开所有 groups,附带 selected 状态
*/
function buildProjectGroups(projects) {
return projects.map((p, idx) => {
const groups = Array.isArray(p.groups) ? p.groups : [];
return {
projectId: p.id || p.Id || idx,
projectName: p.name || p.Name || '-',
index: CN_NUM[idx] || String(idx + 1),
fee: p.fee != null ? p.fee : 0,
groups: groups.map((g) => ({
groupId: g.groupId || g.GroupId || g.id,
groupName: g.groupName || g.GroupName || '-',
ageRange: g.ageRange || g.AgeRange || '',
gender: g.gender || g.Gender || '',
fee: g.fee != null ? g.fee : (p.fee != null ? p.fee : 0),
selected: false,
ageRequirement: g.ageRequirement || g.AgeRequirement || '',
genderRequirement: g.genderRequirement || g.GenderRequirement || '不限'
}))
};
});
}
/** 计算已选组别的总价 */
function calcTotalPrice(projectGroups) {
let total = 0;
projectGroups.forEach((p) => {
p.groups.forEach((g) => {
if (g.selected) total += Number(g.fee) || 0;
});
});
return total;
}
Page({
data: {
eventId: null,
loggedIn: false,
eventDetail: null,
projects: [],
projectGroups: [], // 分组后的展示数据
couponCode: '',
totalPrice: 0,
submitting: false
},
onLoad(options) {
const eventId = Number(options.eventId);
this.setData({ eventId });
this.fetchDetail(eventId);
},
onShow() {
const accessToken = wx.getStorageSync('accessToken') || '';
this.setData({ loggedIn: Boolean(accessToken) });
},
onBack() {
if (getCurrentPages().length > 1) {
wx.navigateBack();
} else {
wx.switchTab({ url: '/pages/home/home' });
}
},
fetchDetail(eventId) {
if (!eventId) return;
request({
path: API.eventDetail(eventId),
method: 'GET',
needAuth: false
})
.then((detail) => {
const projects = Array.isArray(detail.projects) ? detail.projects : [];
const projectGroups = buildProjectGroups(projects);
this.setData({
eventDetail: detail,
projects,
projectGroups,
totalPrice: 0
});
})
.catch(() => {
wx.showToast({ title: '加载失败', icon: 'none' });
});
},
onGoMineLogin() {
wx.switchTab({ url: '/pages/mine/mine' });
},
/** 点击组别标签切换选中状态 */
onGroupTap(e) {
const { projectId, groupId } = e.currentTarget.dataset;
const projectGroups = this.data.projectGroups.map((p) => {
if (p.projectId !== projectId) return p;
return {
...p,
groups: p.groups.map((g) => {
if (g.groupId !== groupId) return g;
return { ...g, selected: !g.selected };
})
};
});
const totalPrice = calcTotalPrice(projectGroups);
this.setData({ projectGroups, totalPrice });
},
onCouponInput(e) {
this.setData({ couponCode: (e.detail.value || '').trim() });
},
/** 收集已选的 projectId + groupId */
_getSelectedItems() {
const items = [];
this.data.projectGroups.forEach((p) => {
p.groups.forEach((g) => {
if (g.selected) {
items.push({ projectId: Number(p.projectId), groupId: Number(g.groupId) });
}
});
});
return items;
},
_validateAndGetPayload(paymentMethod) {
if (!this.data.loggedIn) {
wx.showToast({ title: '请先登录', icon: 'none' });
return null;
}
const items = this._getSelectedItems();
if (items.length === 0) {
wx.showToast({ title: '请至少选择一个组别', icon: 'none' });
return null;
}
return {
eventId: Number(this.data.eventId),
registrationMode: 1,
paymentMethod, // 1=线下 2=线上
couponCode: this.data.couponCode || null,
items
};
},
/** 线下支付 */
onPayOffline() {
const payload = this._validateAndGetPayload(1);
if (!payload) return;
this._submitApply(payload);
},
/** 线上支付 */
onPayOnline() {
const payload = this._validateAndGetPayload(2);
if (!payload) return;
this._submitApply(payload);
},
_submitApply(payload) {
this.setData({ submitting: true });
request({
path: API.apply,
method: 'POST',
needAuth: true,
data: payload,
contentType: 'application/json'
})
.then(() => {
wx.showToast({ title: '报名成功', icon: 'success' });
setTimeout(() => wx.switchTab({ url: '/pages/mine/mine' }), 800);
})
.catch((err) => {
wx.showToast({ title: err && err.message ? err.message : '提交失败', icon: 'none' });
})
.finally(() => this.setData({ submitting: false }));
}
});