From 341449efe9d7bada350d4e5293e6221b36c7377d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Mon, 21 Sep 2026 14:15:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8A=A5=E6=97=B6=E9=97=B4=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E7=9A=84=E6=AF=94=E8=B5=9B=E5=BC=B9=E7=AA=97=E6=8F=90?= =?UTF-8?q?=E9=86=92=20=E6=A3=80=E5=BD=95=E5=B7=A5=E4=BD=9C=E5=8F=B0?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E9=A1=B9=E7=9B=AE=E5=90=8E=E4=B8=8D=E7=94=A8?= =?UTF-8?q?=E5=86=8D=E7=BB=86=E5=8C=96=E5=88=B0=E7=BB=84=E5=88=AB=EF=BC=8C?= =?UTF-8?q?=E6=8C=89=E7=85=A7=E5=9C=BA=E6=AC=A1=E9=A1=BA=E5=BA=8F=E6=8E=92?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/detail/detail.js | 21 +++++++-- subpackages/mine/checkin/checkin.js | 66 ++++----------------------- subpackages/mine/checkin/checkin.wxml | 46 +++++-------------- utils/competition.js | 24 +++++----- 4 files changed, 50 insertions(+), 107 deletions(-) diff --git a/pages/detail/detail.js b/pages/detail/detail.js index eb0f293..fc05798 100644 --- a/pages/detail/detail.js +++ b/pages/detail/detail.js @@ -111,6 +111,21 @@ function toastForEventStatus(es) { return '当前不可报名'; } +function showRefereeApplyFailure(message, fallbackMessage) { + const content = String(message || fallbackMessage || '报名执裁失败'); + if (content.includes('执裁时间存在重叠')) { + wx.showModal({ + title: '报名提示', + content, + showCancel: false, + confirmText: '我知道了' + }); + return; + } + + wx.showToast({ title: content, icon: 'none' }); +} + function registrationModeText(mode) { const m = mode === undefined || mode === null ? null : Number(mode); if (m === 1) return '只允许个人报名'; @@ -913,11 +928,11 @@ Page({ return; } if (quota && (quota.isFull || quota.canApply === false) && !quota.applied4Me) { - wx.showToast({ title: quota.message || '裁判报名名额已满', icon: 'none' }); + showRefereeApplyFailure(quota.message, '裁判报名名额已满'); return; } this._confirmRefereeApply(); - }).catch((err) => wx.showToast({ title: (err && err.message) || '裁判资格校验失败', icon: 'none' })) + }).catch((err) => showRefereeApplyFailure(err && err.message, '裁判资格校验失败')) .finally(() => wx.hideLoading()); }, @@ -942,7 +957,7 @@ Page({ this.setData({ isRegistered: true, applyDisabled: true, applyGrey: true, applyButtonText: '已报名执裁' }); wx.showToast({ title: '报名执裁成功', icon: 'success' }); }).catch((err) => { - wx.showToast({ title: (err && err.message) || '报名执裁失败', icon: 'none' }); + showRefereeApplyFailure(err && err.message, '报名执裁失败'); }).finally(() => wx.hideLoading()); } }); diff --git a/subpackages/mine/checkin/checkin.js b/subpackages/mine/checkin/checkin.js index f1e8ee6..3126686 100644 --- a/subpackages/mine/checkin/checkin.js +++ b/subpackages/mine/checkin/checkin.js @@ -5,15 +5,10 @@ Page({ loading: true, context: null, projects: [], - projectNames: [], projectIndex: 0, - groups: [], - groupNames: [], - groupIndex: 0, units: [], pendingUnits: [], checkedUnits: [], - checkedGroups: [], lockedUnits: [], checkedCount: 0, pendingCount: 0, @@ -25,7 +20,7 @@ Page({ onLoad() { this.loadContext(); }, onPullDownRefresh() { - this.loadContext(this.currentProjectId(), this.currentGroupId()).finally(() => wx.stopPullDownRefresh()); + this.loadContext(this.currentProjectId()).finally(() => wx.stopPullDownRefresh()); }, currentProjectId() { @@ -33,14 +28,9 @@ Page({ return item && item.eventProjectId; }, - currentGroupId() { - const item = this.data.groups[this.data.groupIndex]; - return item && item.id; - }, - - loadContext(eventProjectId, groupId) { + loadContext(eventProjectId) { this.setData({ loading: true }); - return competition.fetchCurrentCheckin({ eventProjectId, groupId }) + return competition.fetchCurrentCheckin({ eventProjectId }) .then((context) => this.applyContext(context)) .catch((err) => wx.showToast({ title: (err && err.message) || '检录信息加载失败', icon: 'none' })) .finally(() => this.setData({ loading: false })); @@ -50,9 +40,6 @@ Page({ const projects = (context && context.projects) || []; let projectIndex = projects.findIndex((item) => String(item.eventProjectId) === String(context.selectedEventProjectId)); if (projectIndex < 0) projectIndex = 0; - const groups = (projects[projectIndex] && projects[projectIndex].groups) || []; - let groupIndex = groups.findIndex((item) => String(item.id) === String(context.selectedGroupId)); - if (groupIndex < 0) groupIndex = 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); @@ -64,33 +51,13 @@ Page({ 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, - groups, - groupNames: groups.map((item) => item.groupName), - groupIndex, units, pendingUnits, checkedUnits, - checkedGroups, lockedUnits, checkedCount, pendingCount: pendingUnits.length, @@ -103,33 +70,23 @@ Page({ const projectIndex = Number(e.currentTarget.dataset.index) || 0; if (projectIndex === this.data.projectIndex) return; const project = this.data.projects[projectIndex]; - const group = project && project.groups && project.groups[0]; - if (project && group) this.loadContext(project.eventProjectId, group.id); - }, - - onGroupTap(e) { - if (this.data.loading) return; - const groupIndex = Number(e.currentTarget.dataset.index) || 0; - if (groupIndex === this.data.groupIndex) return; - const group = this.data.groups[groupIndex]; - if (group) this.loadContext(this.currentProjectId(), group.id); + if (project) this.loadContext(project.eventProjectId); }, onStartCheckin() { if (this.data.actionLoading) return; const eventProjectId = this.currentProjectId(); - const groupId = this.currentGroupId(); wx.showModal({ title: '开始检录', - content: '开始后将通知本组报名人员,确认继续吗?', + content: '开始后将通知当前项目的报名人员,确认继续吗?', success: (res) => { if (!res.confirm) return; this.setData({ actionLoading: true }); - competition.startCheckin({ eventProjectId, groupId }) + 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, groupId); + if (!(result && result.context)) return this.loadContext(eventProjectId); }) .catch((err) => wx.showToast({ title: (err && err.message) || '开始检录失败', icon: 'none' })) .finally(() => this.setData({ actionLoading: false })); @@ -145,8 +102,7 @@ Page({ this.setData({ actionLoading: true }); competition.scanCheckin({ code: scan.result, - eventProjectId: this.currentProjectId(), - groupId: this.currentGroupId() + eventProjectId: this.currentProjectId() }).then((result) => { // 后端在号码布不匹配时返回 success:false + message 且不带 context, // 必须照样给出提示,否则检录员扫错码时收不到任何反馈。 @@ -156,7 +112,7 @@ Page({ title: (result && result.message) || (ok ? '扫码检录成功' : '扫码检录失败'), icon: ok ? 'success' : 'none' }); - if (!(result && result.context)) return this.loadContext(this.currentProjectId(), this.currentGroupId()); + if (!(result && result.context)) return this.loadContext(this.currentProjectId()); }).catch((err) => wx.showToast({ title: (err && err.message) || '扫码检录失败', icon: 'none' })) .finally(() => this.setData({ actionLoading: false })); } @@ -169,8 +125,7 @@ Page({ this.setData({ updatingKey: unitKey }); competition.markCheckinOnStage({ unitKey, - eventProjectId: this.currentProjectId(), - groupId: this.currentGroupId() + eventProjectId: this.currentProjectId() }).then((context) => { if (context) this.applyContext(context); wx.showToast({ title: '已标记上场', icon: 'success' }); @@ -205,7 +160,6 @@ Page({ competition.updateCheckinStatus({ unitKey, eventProjectId: this.currentProjectId(), - groupId: this.currentGroupId(), checked }).then((res) => { this.applyContext(res); diff --git a/subpackages/mine/checkin/checkin.wxml b/subpackages/mine/checkin/checkin.wxml index a404d95..cfcbba7 100644 --- a/subpackages/mine/checkin/checkin.wxml +++ b/subpackages/mine/checkin/checkin.wxml @@ -12,8 +12,8 @@ - 当前组别 - {{context.currentGroupName || '请选择组别'}} + 当前项目 + {{projects[projectIndex].projectName || '请选择项目'}} @@ -40,30 +40,10 @@ - - - - 2 - 选择参赛组别点击后立即切换检录名单 - - - - - - {{item.groupName}}{{item.checkedUnits}}/{{item.totalUnits}} · {{item.isCompleted ? '已完成' : item.progressPercent + '%'}} - - - - + @@ -71,23 +51,23 @@ - 当前组别进度{{checkedCount}} / {{units.length}} 项 + 当前项目进度{{checkedCount}} / {{units.length}} 项 已检录 {{checkedCount}} 项待检录 {{pendingCount}} 项 待检录按秩序册顺序 - {{item.teamName || '个人参赛'}}{{item.venueName}} + {{item.teamName || '个人参赛'}}第{{item.sessionIndex}}场 · {{item.venueName}} 单位{{item.unitName}} {{athlete.name}} 确认检录 - 当前组别暂无待检录项 + 当前项目暂无待检录项 等待前序检录前一检通过后可操作 - {{item.teamName || '个人参赛'}}{{item.venueName}} + {{item.teamName || '个人参赛'}}第{{item.sessionIndex}}场 · {{item.venueName}} 单位{{item.unitName}} {{athlete.name}} {{item.lockReason}} @@ -95,15 +75,11 @@ 已检录{{checkedUnits.length}} 项 - 仅展示当前选中项目和组别的已检录结果 + 仅展示当前项目,按场次顺序排列 - - - {{checkedGroup.projectName}}{{checkedGroup.groupName}} - {{checkedGroup.units.length}} 项 - - - {{item.teamName || '个人参赛'}}{{item.venueName}} + + + {{item.teamName || '个人参赛'}}第{{item.sessionIndex}}场 · {{item.venueName}} 单位{{item.unitName}} {{athlete.name}} diff --git a/utils/competition.js b/utils/competition.js index cecaa7e..76f7410 100644 --- a/utils/competition.js +++ b/utils/competition.js @@ -25,49 +25,47 @@ function rejectWith(message) { return Promise.reject(new Error(message)); } -function withScope(data, eventProjectId, groupId) { +function withProjectScope(data, eventProjectId) { if (!isEmptyValue(eventProjectId)) data.eventProjectId = eventProjectId; - if (!isEmptyValue(groupId)) data.groupId = groupId; return data; } -function fetchCurrentCheckin({ eventProjectId, groupId } = {}) { - return request({ path: API.checkinContext, method: 'GET', data: withScope({}, eventProjectId, groupId), needAuth: true }); +function fetchCurrentCheckin({ eventProjectId } = {}) { + return request({ path: API.checkinContext, method: 'GET', data: withProjectScope({}, eventProjectId), needAuth: true }); } -function updateCheckinStatus({ unitKey, eventProjectId, groupId, checked }) { - return request({ path: API.checkinStatus, method: 'POST', data: withScope({ unitKey, checked }, eventProjectId, groupId), needAuth: true }); +function updateCheckinStatus({ unitKey, eventProjectId, checked }) { + return request({ path: API.checkinStatus, method: 'POST', data: withProjectScope({ unitKey, checked }, eventProjectId), needAuth: true }); } -function startCheckin({ eventProjectId, groupId } = {}) { +function startCheckin({ eventProjectId } = {}) { if (isEmptyValue(eventProjectId)) return rejectWith('请选择检录项目'); - if (isEmptyValue(groupId)) return rejectWith('请选择检录组别'); return request({ path: API.checkinStart, method: 'POST', - data: { eventProjectId, groupId }, + data: { eventProjectId }, needAuth: true }); } -function scanCheckin({ code, eventProjectId, groupId } = {}) { +function scanCheckin({ code, eventProjectId } = {}) { if (isEmptyValue(code)) return rejectWith('未识别到有效检录码'); const normalizedCode = String(code).trim(); if (!normalizedCode) return rejectWith('未识别到有效检录码'); return request({ path: API.checkinScan, method: 'POST', - data: withScope({ code: normalizedCode }, eventProjectId, groupId), + data: withProjectScope({ code: normalizedCode }, eventProjectId), needAuth: true }); } -function markCheckinOnStage({ unitKey, eventProjectId, groupId } = {}) { +function markCheckinOnStage({ unitKey, eventProjectId } = {}) { if (isEmptyValue(unitKey)) return rejectWith('缺少参赛单位标识'); return request({ path: API.checkinOnStage, method: 'POST', - data: withScope({ unitKey }, eventProjectId, groupId), + data: withProjectScope({ unitKey }, eventProjectId), needAuth: true }); } From 6cdbc303a5e351eb8d4fb13fe1d9fdea8238a33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Wed, 23 Sep 2026 11:32:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8A=A5=E5=90=8D=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/detail/detail.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pages/detail/detail.js b/pages/detail/detail.js index fc05798..7fd7eed 100644 --- a/pages/detail/detail.js +++ b/pages/detail/detail.js @@ -113,7 +113,11 @@ function toastForEventStatus(es) { function showRefereeApplyFailure(message, fallbackMessage) { const content = String(message || fallbackMessage || '报名执裁失败'); - if (content.includes('执裁时间存在重叠')) { + const isTimeConflict = content.includes('执裁时间') && + (content.includes('重叠') || content.includes('冲突')); + if (isTimeConflict) { + wx.hideLoading(); + wx.hideToast(); wx.showModal({ title: '报名提示', content,