From adfc7a66fb9dee1d79479c0284fe8e8d498bf9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Thu, 17 Sep 2026 14:00:10 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A3=81=E5=88=A4=E4=BA=8C=E7=BB=B4=E7=A0=81?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/detail/detail.js | 50 +++++++++++++++++++++++++-- subpackages/mine/login/login.js | 27 ++++++++++++--- subpackages/mine/login/login.wxml | 2 +- subpackages/mine/register/register.js | 8 ++++- utils/competition.js | 6 ++++ utils/constants.js | 1 + 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/pages/detail/detail.js b/pages/detail/detail.js index 748080a..eb0f293 100644 --- a/pages/detail/detail.js +++ b/pages/detail/detail.js @@ -514,6 +514,9 @@ Page({ isRegistered: false, /** 裁判身份进入赛事详情时,报名动作改为报名执裁 */ isReferee: false, + /** 是否通过后台生成的裁判报名小程序码进入 */ + isRefereeRegistrationEntry: false, + refereeRegistrationCode: '', /** 收费模式 0免费 1定价赛事 2单价赛事 3单价项目 */ chargeMode: null }, @@ -523,7 +526,22 @@ Page({ const loggedIn = !!(wx.getStorageSync('accessToken') || ''); const role = loggedIn ? getProfileRole(wx.getStorageSync('userProfile') || {}) : ROLE.PARTICIPANT; - this.setData({ isReferee: role === ROLE.REFEREE }); + let scene = ''; + if (options.scene) { + try { scene = decodeURIComponent(options.scene); } catch (e) { scene = options.scene; } + } + const refereeRegistrationCode = String(scene || options.refereeCode || '').trim(); + const isRefereeRegistrationEntry = !!refereeRegistrationCode; + this.setData({ + isReferee: isRefereeRegistrationEntry || role === ROLE.REFEREE, + isRefereeRegistrationEntry, + refereeRegistrationCode + }); + + if (isRefereeRegistrationEntry) { + this._resolveRefereeRegistrationCode(refereeRegistrationCode); + return; + } let rawId = options.id; @@ -548,6 +566,32 @@ Page({ this.fetchDetail(id); }, + onShow() { + if (!this.data.isRefereeRegistrationEntry || !this.data.id || !wx.getStorageSync('accessToken')) return; + this.setData({ isReferee: true }); + this._syncRefereeApplication(this.data.id); + }, + + _resolveRefereeRegistrationCode(code) { + wx.showLoading({ title: '正在打开赛事...', mask: true }); + competition.resolveRefereeRegistrationCode(code) + .then((result) => { + const id = Number(result); + if (!id) throw new Error('裁判报名码未关联有效赛事'); + this.setData({ id, isReferee: true }); + this.fetchDetail(id); + }) + .catch((err) => { + this.setData({ applyDisabled: true, applyGrey: true, applyButtonText: '报名码无效' }); + wx.showModal({ + title: '无法打开赛事', + content: (err && err.message) || '裁判报名码无效或赛事已停用', + showCancel: false + }); + }) + .finally(() => wx.hideLoading()); + }, + fetchDetail(id) { this.setData({ applyDisabled: true, applyGrey: true, applyButtonText: '加载中...' }); request({ @@ -781,7 +825,7 @@ Page({ applyButtonText: finalApplyButtonText, isRegistered: this.data.isReferee ? false : isRegistered }); - if (this.data.isReferee) this._syncRefereeApplication(id); + if (this.data.isReferee && wx.getStorageSync('accessToken')) this._syncRefereeApplication(id); }) .catch((err) => { // wx.showToast({ title: err.Error, icon: 'none' }); @@ -841,7 +885,7 @@ Page({ onRefereeApplyTap() { if (!wx.getStorageSync('accessToken')) { - wx.navigateTo({ url: '/subpackages/mine/login/login' }); + wx.navigateTo({ url: '/subpackages/mine/login/login?returnToPrevious=1&refereeRegistration=1' }); return; } if (this.data.isRegistered) { diff --git a/subpackages/mine/login/login.js b/subpackages/mine/login/login.js index 98ad609..1746aed 100644 --- a/subpackages/mine/login/login.js +++ b/subpackages/mine/login/login.js @@ -13,6 +13,8 @@ Page({ logging: false, agreed: false, statusBarHeight: 0, + returnToPrevious: false, + refereeRegistration: false, // 验证码倒计时 codeText: '发送验证码', @@ -22,15 +24,19 @@ Page({ _timer: null, - onLoad() { + onLoad(options) { const { statusBarHeight = 0 } = wx.getSystemInfoSync(); - this.setData({ statusBarHeight }); + this.setData({ + statusBarHeight, + returnToPrevious: options && options.returnToPrevious === '1', + refereeRegistration: options && options.refereeRegistration === '1' + }); }, onShow() { const accessToken = wx.getStorageSync('accessToken') || ''; if (accessToken) { - wx.redirectTo({ url: '/pages/mine/mine' }); + this._navigateAfterLogin(); } }, @@ -110,6 +116,11 @@ Page({ wx.navigateTo({ url: '/subpackages/mine/register/register?mode=reset' }); }, + onRegisterTap() { + const roleQuery = this.data.refereeRegistration ? '?role=referee' : ''; + wx.navigateTo({ url: `/subpackages/mine/register/register${roleQuery}` }); + }, + // ========= 发送验证码 ========= onSendCode() { @@ -173,7 +184,7 @@ Page({ .then(() => { wx.showToast({ title: '登录成功', icon: 'success' }); setTimeout(() => { - wx.switchTab({ url: '/pages/mine/mine' }); + this._navigateAfterLogin(); }, 400); }) .catch((err) => { @@ -188,6 +199,14 @@ Page({ // ========= 内部方法 ========= + _navigateAfterLogin() { + if (this.data.returnToPrevious && getCurrentPages().length > 1) { + wx.navigateBack(); + return; + } + wx.switchTab({ url: '/pages/mine/mine' }); + }, + _startCountdown() { let seconds = CODE_COUNTDOWN; this.setData({ diff --git a/subpackages/mine/login/login.wxml b/subpackages/mine/login/login.wxml index 9f4323b..6dc5b16 100644 --- a/subpackages/mine/login/login.wxml +++ b/subpackages/mine/login/login.wxml @@ -125,7 +125,7 @@ - 注册 + 注册 diff --git a/subpackages/mine/register/register.js b/subpackages/mine/register/register.js index 2f7afb5..2452966 100644 --- a/subpackages/mine/register/register.js +++ b/subpackages/mine/register/register.js @@ -25,7 +25,13 @@ Page({ onLoad(options) { const { statusBarHeight = 0 } = wx.getSystemInfoSync(); const isReset = options && options.mode === 'reset'; - this.setData({ statusBarHeight, isReset }); + const selectedRole = !isReset && options && options.role === 'referee' ? 'referee' : 'participant'; + this.setData({ + statusBarHeight, + isReset, + selectedRole, + selectedRoleDescription: ROLE_META[selectedRole].description + }); }, onUnload() { diff --git a/utils/competition.js b/utils/competition.js index affb2dd..cecaa7e 100644 --- a/utils/competition.js +++ b/utils/competition.js @@ -89,6 +89,11 @@ function fetchRefereeProfile() { .then((res) => (res && typeof res === 'object' ? res : {})); } +function resolveRefereeRegistrationCode(code) { + if (isEmptyValue(code)) return rejectWith('裁判报名码无效'); + return request({ path: API.refereeRegistrationCode(String(code).trim()), method: 'GET', needAuth: false }); +} + // 裁判角色是 [Flags] 位枚举(1-主裁 2-表现 4-难度 8-创意编排 16-完成质量)。 // 接口文档在 RefereeProfileSubmitInput/RefereeProfileDto 两处误写为 int 数组, // 后端实际按单个 RefereeRole 反序列化,因此提交前合并为位标志,回显时再拆开。 @@ -154,6 +159,7 @@ module.exports = { fetchCheckinProgress, fetchRefereeProfileOptions, fetchRefereeProfile, + resolveRefereeRegistrationCode, submitRefereeProfile, splitRefereeRoles, fetchRefereeQuota, diff --git a/utils/constants.js b/utils/constants.js index d4a4a94..b05f0ea 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -47,6 +47,7 @@ const API = { refereeProfileOptions: '/api/referee/profile/options', refereeProfile: '/api/referee/profile', refereeProfileSubmit: '/api/referee/profile/submit', + refereeRegistrationCode: (code) => `/api/referee/registration-code/${encodeURIComponent(code)}`, refereeApplicationQuota: '/api/referee/applications/quota', refereeApplications: '/api/referee/applications', refereeApply: '/api/referee/applications/apply',