171 lines
6.7 KiB
JavaScript
171 lines
6.7 KiB
JavaScript
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: '' }));
|
||
}
|
||
});
|