192 lines
7.5 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 competition = require('../../../utils/competition');
Page({
data: {
loading: true,
context: null,
projects: [],
projectNames: [],
projectIndex: 0,
currentProjectName: '',
units: [],
pendingUnits: [],
checkedUnits: [],
checkedGroups: [],
lockedUnits: [],
checkedCount: 0,
pendingCount: 0,
progressPercent: 0,
updatingKey: '',
actionLoading: false
},
onLoad() { this.loadContext(); },
onPullDownRefresh() {
this.loadContext(this.currentProjectId()).finally(() => wx.stopPullDownRefresh());
},
currentProjectId() {
const item = this.data.projects[this.data.projectIndex];
return item && item.eventProjectId;
},
loadContext(eventProjectId) {
this.setData({ loading: true });
return competition.fetchCurrentCheckin({ eventProjectId })
.then((context) => this.applyContext(context))
.catch((err) => wx.showToast({ title: (err && err.message) || '检录信息加载失败', icon: 'none' }))
.finally(() => this.setData({ loading: false }));
},
applyContext(context) {
const projects = (context && context.projects) || [];
let projectIndex = projects.findIndex((item) => String(item.eventProjectId) === String(context.selectedEventProjectId));
if (projectIndex < 0) projectIndex = 0;
const units = (context && context.units) || [];
const pendingUnits = Array.isArray(context && context.pendingUnits) ? context.pendingUnits : units.filter((item) => item.canCheck && !item.checked);
const checkedUnits = Array.isArray(context && context.checkedUnits) ? context.checkedUnits : units.filter((item) => item.checked);
const lockedUnits = Array.isArray(context && context.lockedUnits) ? context.lockedUnits : units.filter((item) => !item.canCheck);
const totalRounds = Number(context && (context.totalCheckins || context.totalRounds)) || 0;
const currentRound = Number(context && (context.currentCheckinNo || context.currentRound)) || 0;
const rounds = Array.from({ length: totalRounds }, (_, index) => {
const number = index + 1;
return { number, state: number < currentRound ? 'done' : number === currentRound ? 'active' : '', label: number < currentRound ? '✓' : String(number) };
});
const checkedCount = units.filter((item) => item.checked).length;
const checkedGroups = [];
checkedUnits.forEach((item) => {
const key = `${item.eventProjectId || item.projectId}-${item.groupId || item.groupName}`;
let group = checkedGroups.find((entry) => entry.key === key);
if (!group) {
group = {
key,
projectName: item.projectName || '未命名项目',
groupName: item.groupName || '未分组',
units: []
};
checkedGroups.push(group);
}
group.units.push(item);
});
this.setData({
context: context ? Object.assign({}, context, { rounds }) : null,
projects,
projectNames: projects.map((item) => item.projectName),
projectIndex,
currentProjectName: (projects[projectIndex] && projects[projectIndex].projectName) || '',
units,
pendingUnits,
checkedUnits,
checkedGroups,
lockedUnits,
checkedCount,
pendingCount: pendingUnits.length,
progressPercent: units.length ? Math.round(checkedCount * 100 / units.length) : 0
});
},
onProjectTap(e) {
if (this.data.loading) return;
const projectIndex = Number(e.currentTarget.dataset.index) || 0;
if (projectIndex === this.data.projectIndex) return;
const project = this.data.projects[projectIndex];
if (project) this.loadContext(project.eventProjectId);
},
onStartCheckin() {
if (this.data.actionLoading) return;
const eventProjectId = this.currentProjectId();
wx.showModal({
title: '开始检录',
content: '开始后将按秩序册顺序检录该项目全部组别,并通知报名人员,确认继续吗?',
success: (res) => {
if (!res.confirm) return;
this.setData({ actionLoading: true });
competition.startCheckin({ eventProjectId })
.then((result) => {
if (result && result.context) this.applyContext(result.context);
wx.showToast({ title: (result && result.message) || '检录已开始', icon: 'none' });
if (!(result && result.context)) return this.loadContext(eventProjectId);
})
.catch((err) => wx.showToast({ title: (err && err.message) || '开始检录失败', icon: 'none' }))
.finally(() => this.setData({ actionLoading: false }));
}
});
},
onScanCheckin() {
if (this.data.actionLoading) return;
wx.scanCode({
scanType: ['qrCode', 'barCode'],
success: (scan) => {
this.setData({ actionLoading: true });
competition.scanCheckin({
code: scan.result,
eventProjectId: this.currentProjectId()
}).then((result) => {
// 后端在号码布不匹配时返回 success:false + message 且不带 context,
// 必须照样给出提示,否则检录员扫错码时收不到任何反馈。
const ok = !result || result.success !== false;
if (result && result.context) this.applyContext(result.context);
wx.showToast({
title: (result && result.message) || (ok ? '扫码检录成功' : '扫码检录失败'),
icon: ok ? 'success' : 'none'
});
if (!(result && result.context)) return this.loadContext(this.currentProjectId());
}).catch((err) => wx.showToast({ title: (err && err.message) || '扫码检录失败', icon: 'none' }))
.finally(() => this.setData({ actionLoading: false }));
}
});
},
onMarkOnStage(e) {
const unitKey = e.currentTarget.dataset.key;
if (!unitKey || this.data.updatingKey) return;
this.setData({ updatingKey: unitKey });
competition.markCheckinOnStage({
unitKey,
eventProjectId: this.currentProjectId()
}).then((context) => {
if (context) this.applyContext(context);
wx.showToast({ title: '已标记上场', icon: 'success' });
}).catch((err) => wx.showToast({ title: (err && err.message) || '标记上场失败', icon: 'none' }))
.finally(() => this.setData({ updatingKey: '' }));
},
onToggleUnit(e) {
const unitKey = e.currentTarget.dataset.key;
const current = this.data.units.find((item) => item.unitKey === unitKey)
|| this.data.checkedUnits.find((item) => item.unitKey === unitKey);
if (!current || !current.canCheck || this.data.updatingKey) return;
const checked = !current.checked;
if (current.checked) {
wx.showModal({
title: '取消检录',
content: `确认取消${current.teamName || current.athletes.map((item) => item.name).join('、')}的当前检录吗?`,
confirmText: '确认取消',
confirmColor: '#d94b4b',
success: (res) => {
if (res.confirm) this.updateUnitStatus(current, checked);
}
});
return;
}
this.updateUnitStatus(current, checked);
},
updateUnitStatus(current, checked) {
const unitKey = current.unitKey;
this.setData({ updatingKey: unitKey });
competition.updateCheckinStatus({
unitKey,
eventProjectId: this.currentProjectId(),
checked
}).then((res) => {
this.applyContext(res);
wx.showToast({ title: checked ? '该列已完成检录' : '已取消该列检录', icon: 'none' });
}).catch((err) => wx.showToast({ title: (err && err.message) || '操作失败', icon: 'none' }))
.finally(() => this.setData({ updatingKey: '' }));
}
});