YD_Event.miniApp/utils/checkin-progress.js
马梓彭 b157e73eb2 新增检录进度页面
新增裁判认证页面
对接检录页面
对接成绩查询页面
2026-09-01 23:13:21 +08:00

115 lines
5.2 KiB
JavaScript

function asArray(value) {
if (Array.isArray(value)) return value;
if (value == null || value === '') return [];
return [value];
}
function asNumber(value, fallback = 0) {
const number = Number(value);
return Number.isFinite(number) ? number : fallback;
}
function clampPercent(value) {
return Math.max(0, Math.min(100, asNumber(value)));
}
function formatDateTime(value) {
if (!value) return '—';
const date = new Date(value);
if (Number.isNaN(date.getTime())) return String(value);
const pad = (number) => String(number).padStart(2, '0');
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
function containsAbnormalText(value) {
return /(异常|失败|取消|作废|拒绝|未通过|超时)/.test(String(value || ''));
}
function normalizeStage(stage, index = 0) {
const source = stage && typeof stage === 'object' ? stage : {};
const stageStatus = asNumber(source.stageStatus, -1);
const totalUnits = Math.max(0, asNumber(source.totalUnits));
const checkedUnits = Math.max(0, asNumber(source.checkedUnits));
const rawPercent = asNumber(source.progressPercent);
const isAbnormal = ![1, 2, 3, 4].includes(stageStatus) || checkedUnits > totalUnits || rawPercent < 0 || rawPercent > 100 || containsAbnormalText(source.stageStatusText);
const athleteNames = asArray(source.athleteNames);
return Object.assign({}, source, {
stageKey: source.stageKey || `${source.eventProjectId || 'project'}-${source.groupId || 'group'}-${index}`,
stageStatus,
totalUnits,
checkedUnits,
progressPercent: clampPercent(rawPercent),
displayName: source.displayName || [source.projectName, source.groupName].filter(Boolean).join(' - ') || '未命名项目',
stageStatusText: source.stageStatusText || (isAbnormal ? '状态异常' : '等待中'),
athleteNames,
athleteNamesText: athleteNames.join('、') || '—',
isAbnormal,
statusClass: isAbnormal ? 'abnormal' : `status-${stageStatus}`
});
}
function normalizeRound(round) {
const source = round && typeof round === 'object' ? round : {};
const passed = source.passed === true;
const isAbnormal = containsAbnormalText(source.statusText || source.checkinStatusText);
return Object.assign({}, source, {
checkinNo: asNumber(source.checkinNo),
checkinName: source.checkinName || `${asNumber(source.checkinNo)}检`,
passed,
checkedTimeText: passed ? formatDateTime(source.checkedTime) : '待完成',
checkerNameText: passed ? (source.checkerName || '—') : '—',
isAbnormal,
statusClass: isAbnormal ? 'abnormal' : (passed ? 'passed' : 'pending')
});
}
function normalizeMine(item) {
const source = item && typeof item === 'object' ? item : {};
const checkinStatus = asNumber(source.checkinStatus, -1);
const isAbnormal = ![0, 1, 2, 3].includes(checkinStatus) || containsAbnormalText(source.checkinStatusText) || containsAbnormalText(source.notice);
const athleteNames = asArray(source.athleteNames);
return Object.assign({}, source, {
checkinStatus,
displayName: source.displayName || [source.projectName, source.groupName].filter(Boolean).join(' - ') || '未命名项目',
athleteNames,
athleteNamesText: athleteNames.join('、') || '—',
rounds: asArray(source.rounds).map(normalizeRound),
checkinStatusText: source.checkinStatusText || (isAbnormal ? '状态异常' : '等待中'),
isAbnormal,
statusClass: isAbnormal ? 'abnormal' : `status-${checkinStatus}`
});
}
function normalizeCheckinProgress(payload) {
const source = payload && typeof payload === 'object' ? payload : {};
const stages = asArray(source.stages).map((stage, index) => normalizeStage(stage, index));
const mine = asArray(source.mine).map(normalizeMine);
const currentCheckin = source.currentCheckin ? normalizeStage(source.currentCheckin) : null;
const currentCompeting = source.currentCompeting ? normalizeStage(source.currentCompeting) : null;
const competingMine = currentCompeting && mine.find((item) =>
String(item.eventProjectId) === String(currentCompeting.eventProjectId) &&
String(item.groupId || '') === String(currentCompeting.groupId || '')
);
const currentCompetingDetail = currentCompeting ? Object.assign({}, currentCompeting, {
unitNameText: currentCompeting.unitName || (competingMine && competingMine.unitName) || '—',
teamNameText: currentCompeting.teamName || (competingMine && competingMine.teamName) || '—',
athleteNamesText: currentCompeting.athleteNamesText !== '—'
? currentCompeting.athleteNamesText
: ((competingMine && competingMine.athleteNamesText) || '—'),
registrationTypeText: currentCompeting.registrationTypeText || '个人报名'
}) : null;
return Object.assign({}, source, {
eventName: source.eventName || '检录进度',
serverTimeText: source.serverTimeText || formatDateTime(source.serverTime),
weekDayText: source.weekDayText || '',
currentCheckin,
currentCompeting,
currentCompetingDetail,
stages,
mine,
hasData: !!currentCheckin || !!currentCompeting || stages.length > 0 || mine.length > 0
});
}
module.exports = { normalizeCheckinProgress };