const competition = require('../../../utils/competition'); Page({ data: { loading: true, context: null, projects: [], projectIndex: 0, units: [], pendingUnits: [], checkedUnits: [], 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; this.setData({ context: context ? Object.assign({}, context, { rounds }) : null, projects, projectIndex, units, pendingUnits, checkedUnits, 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: '' })); } });