YD_Event.miniApp/utils/competition.js

162 lines
7.0 KiB
JavaScript
Raw Normal View History

const { API } = require('./constants');
const { request } = require('./http');
// 已对接 YD_Event.Admin;如需离线演示可临时改回 true。
const USE_LOCAL_MOCK = false;
const CHECKIN_STORAGE_KEY = 'mockCheckinAthletes';
const REFEREE_APPLICATIONS_KEY = 'mockRefereeApplications';
const MOCK_SCORE_EVENTS = [
{ id: 'event-2026-summer', name: '2026 跃享跳花样跳绳公开赛' },
{ id: 'event-2026-city', name: '跃享跳城市挑战赛' }
];
const MOCK_SCORES = [
{
id: 'score-001', eventId: 'event-2026-summer', eventName: '2026 跃享跳花样跳绳公开赛',
athleteName: '陈跃', athleteNo: 'A018', category: '个人花样', groupName: 'U12 男子组',
roundName: '决赛', rank: 1, totalScore: '86.50', difficultyScore: '28.50',
executionScore: '30.00', creativityScore: '28.00', status: '成绩有效',
judgeScores: [
{ label: '难度裁判', score: '28.50' }, { label: '完成裁判', score: '30.00' },
{ label: '创意裁判', score: '28.00' }
]
},
{
id: 'score-002', eventId: 'event-2026-summer', eventName: '2026 跃享跳花样跳绳公开赛',
athleteName: '林晓', athleteNo: 'A026', category: '个人花样', groupName: 'U12 女子组',
roundName: '决赛', rank: 2, totalScore: '84.20', difficultyScore: '27.70',
executionScore: '29.00', creativityScore: '27.50', status: '成绩有效',
judgeScores: [
{ label: '难度裁判', score: '27.70' }, { label: '完成裁判', score: '29.00' },
{ label: '创意裁判', score: '27.50' }
]
},
{
id: 'score-003', eventId: 'event-2026-city', eventName: '跃享跳城市挑战赛',
athleteName: '跃动少年队', athleteNo: 'T009', category: '团体花样', groupName: '公开组',
roundName: '预赛', rank: 3, totalScore: '81.80', difficultyScore: '26.80',
executionScore: '28.00', creativityScore: '27.00', status: '成绩有效',
judgeScores: [
{ label: '难度裁判', score: '26.80' }, { label: '完成裁判', score: '28.00' },
{ label: '创意裁判', score: '27.00' }
]
}
];
const DEFAULT_CHECKIN_ATHLETES = [
{ id: 'athlete-01', userId: 'user-01', bibNo: 'A018', name: '陈跃', teamName: '跃动俱乐部', checked: true, canCheck: true, orderBookSessionName: '第1场 · 30秒单摇' },
{ id: 'athlete-02', userId: 'user-02', bibNo: 'A021', name: '周航', teamName: '星火跳绳队', checked: true, canCheck: true, orderBookSessionName: '第1场 · 30秒单摇' },
{ id: 'athlete-03', userId: 'user-03', bibNo: 'A024', name: '许嘉', teamName: '青苗体育', checked: false, canCheck: true, orderBookSessionName: '第2场 · 花样跳绳' },
{ id: 'athlete-04', userId: 'user-04', bibNo: 'A027', name: '江晨', teamName: '跃动俱乐部', checked: false, canCheck: true, orderBookSessionName: '第2场 · 花样跳绳' }
];
function clone(data) {
return JSON.parse(JSON.stringify(data));
}
function mockResolve(data) {
return new Promise((resolve) => setTimeout(() => resolve(clone(data)), 180));
}
function fetchScoreEvents() {
if (USE_LOCAL_MOCK) return mockResolve(MOCK_SCORE_EVENTS);
return request({ path: API.scoreEvents, method: 'GET', needAuth: false });
}
function queryScores({ eventId, keyword } = {}) {
if (!USE_LOCAL_MOCK) {
return request({ path: API.scoreQuery, method: 'GET', data: { eventId, keyword }, needAuth: false });
}
const search = String(keyword || '').trim().toLowerCase();
const rows = MOCK_SCORES.filter((item) => {
const eventMatched = !eventId || item.eventId === eventId;
const keywordMatched = !search || [item.athleteName, item.athleteNo, item.groupName]
.some((value) => String(value || '').toLowerCase().includes(search));
return eventMatched && keywordMatched;
});
return mockResolve({ rows, total: rows.length });
}
function fetchCurrentCheckin({ eventProjectId, groupId } = {}) {
if (!USE_LOCAL_MOCK) {
const data = {};
if (eventProjectId !== undefined && eventProjectId !== null && eventProjectId !== '') {
data.eventProjectId = eventProjectId;
}
if (groupId !== undefined && groupId !== null && groupId !== '') {
data.groupId = groupId;
}
return request({ path: API.checkinContext, method: 'GET', data, needAuth: true });
}
const stored = wx.getStorageSync(CHECKIN_STORAGE_KEY);
const athletes = Array.isArray(stored) ? stored : clone(DEFAULT_CHECKIN_ATHLETES);
const rounds = [{ round: 1, order: 1 }, { round: 2, order: 2 }];
const pendingAthletes = athletes.filter((item) => !item.checked && item.canCheck);
const checkedAthletes = athletes.filter((item) => item.checked);
const lockedAthletes = athletes.filter((item) => !item.checked && !item.canCheck);
return mockResolve({
eventId: 'event-2026-summer', eventName: '2026 跃享跳花样跳绳公开赛', venue: '一号检录区',
totalCheckins: 2, currentCheckinNo: 1, currentCheckinName: '一检',
totalRounds: 2, currentRound: 1, roundName: '一检', currentSessionVenue: '一号检录区',
rounds, athletes, pendingAthletes, checkedAthletes, lockedAthletes
});
}
function updateCheckinStatus({ unitKey, eventProjectId, groupId, checked }) {
if (!USE_LOCAL_MOCK) {
const data = { unitKey, checked };
if (eventProjectId !== undefined && eventProjectId !== null && eventProjectId !== '') {
data.eventProjectId = eventProjectId;
}
if (groupId !== undefined && groupId !== null && groupId !== '') {
data.groupId = groupId;
}
return request({ path: API.checkinStatus, method: 'POST', data, needAuth: true });
}
return fetchCurrentCheckin().then((context) => {
const units = (context.units || []).map((item) => item.unitKey === unitKey ? Object.assign({}, item, { checked: !!checked }) : item);
return Object.assign({}, context, { units });
});
}
function fetchRefereeApplications() {
if (!USE_LOCAL_MOCK) {
return request({ path: API.refereeApplications, method: 'GET', needAuth: true });
}
const stored = wx.getStorageSync(REFEREE_APPLICATIONS_KEY);
return mockResolve({ rows: Array.isArray(stored) ? stored : [], total: Array.isArray(stored) ? stored.length : 0 });
}
function applyForReferee(event) {
const payload = event && typeof event === 'object' ? event : {};
if (!USE_LOCAL_MOCK) {
return request({ path: API.refereeApply, method: 'POST', data: { eventId: payload.eventId }, needAuth: true });
}
return fetchRefereeApplications().then((res) => {
const rows = (res && res.rows) || [];
const exists = rows.some((item) => String(item.eventId) === String(payload.eventId));
if (!exists) {
rows.unshift(Object.assign({}, payload, {
id: `referee-${payload.eventId}`,
applicationId: `mock-${Date.now()}`,
applicationStatus: 1,
applicationStatusText: '已报名执裁',
appliedAt: new Date().toISOString()
}));
wx.setStorageSync(REFEREE_APPLICATIONS_KEY, rows);
}
return { success: true, alreadyApplied: exists, rows };
});
}
module.exports = {
USE_LOCAL_MOCK,
fetchScoreEvents,
queryScores,
fetchCurrentCheckin,
updateCheckinStatus,
fetchRefereeApplications,
applyForReferee
};