裁判二维码对接

This commit is contained in:
马梓彭 2026-09-17 14:00:10 +08:00
parent c264a602d5
commit adfc7a66fb
6 changed files with 85 additions and 9 deletions

View File

@ -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) {

View File

@ -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({

View File

@ -125,7 +125,7 @@
<!-- 按钮区域 -->
<view class="btn-area">
<button class="btn-login" bindtap="onLoginTap" loading="{{logging}}">登录</button>
<navigator class="btn-register" url="/subpackages/mine/register/register" hover-class="btn-register-hover">注册</navigator>
<view class="btn-register" hover-class="btn-register-hover" bindtap="onRegisterTap">注册</view>
</view>
</view><!-- /content-card -->
</view>

View File

@ -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() {

View File

@ -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,

View File

@ -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',