## 主要改动
### 1. 修复Mock数据格式问题
- 修复 mock/athlete.js 中 getProjects 函数
- 从字符串数组改为对象数组 { id, name }
- 确保Mock模式和API模式数据格式一致
### 2. 优化网络请求处理
- 优化 utils/request.js 的GET请求参数处理
- 参数自动URL编码
- 支持URL中已有查询参数的情况
- 代码逻辑更清晰
### 3. 新增完整的文档体系
- API对接说明.md - 项目根目录快速说明
- doc/API对接快速启动指南.md - 5分钟快速上手
- doc/后端接口开发清单.md - 后端开发规范(5个接口,6人天)
- doc/前端API对接指南.md - 前端联调指南
- doc/API对接准备完成报告.md - 项目状态总结
## 项目状态
✅ 前端准备完成度: 100%
- 架构设计优秀(dataAdapter适配器模式)
- 代码质量高(注释详细,结构清晰)
- Mock数据完整(可独立演示)
- API接口定义完整(9个接口)
- 页面全部接入(5个页面)
- 文档体系完善(20个文档)
⚠️ 后端待开发: 5个接口
- POST /api/mini/login
- GET /api/mini/athletes
- GET /api/mini/athletes/admin
- GET /api/mini/score/detail/{id}
- PUT /api/mini/score/modify
## 下一步
后端开发者可以参考 doc/后端接口开发清单.md 开始开发
预计工作量: 6人天(约1周)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
555 lines
14 KiB
Markdown
555 lines
14 KiB
Markdown
# 如何查看比赛编码和邀请码
|
||
|
||
**日期**: 2025-12-11
|
||
**用途**: 用于评委登录小程序评分系统
|
||
|
||
---
|
||
|
||
## 📌 概述
|
||
|
||
评委登录小程序需要两个信息:
|
||
1. **比赛编码** (competition_code) - 存储在 `martial_competition` 表
|
||
2. **评委邀请码** (invite_code) - 存储在 `martial_judge_invite` 表
|
||
|
||
---
|
||
|
||
## 🔍 方式一:通过数据库查询(最直接)
|
||
|
||
### 1. 查看比赛编码
|
||
|
||
```sql
|
||
-- 查询所有比赛的编码
|
||
SELECT
|
||
id AS 比赛ID,
|
||
competition_name AS 比赛名称,
|
||
competition_code AS 比赛编码,
|
||
competition_start_time AS 开始时间,
|
||
competition_end_time AS 结束时间,
|
||
is_deleted AS 是否删除
|
||
FROM martial_competition
|
||
WHERE is_deleted = 0
|
||
ORDER BY create_time DESC;
|
||
```
|
||
|
||
**示例结果**:
|
||
```
|
||
比赛ID | 比赛名称 | 比赛编码 | 开始时间 | 结束时间
|
||
-------|----------------------------------|---------|--------------------|-----------------
|
||
200 | 2025年全国武术散打锦标赛 | WS2025 | 2025-11-06 08:00 | 2025-11-08 18:00
|
||
```
|
||
|
||
### 2. 查看评委邀请码
|
||
|
||
```sql
|
||
-- 查询某个比赛的所有邀请码
|
||
SELECT
|
||
ji.id AS 邀请码ID,
|
||
ji.invite_code AS 邀请码,
|
||
ji.role AS 角色,
|
||
j.name AS 评委姓名,
|
||
j.phone AS 手机号,
|
||
v.venue_name AS 场地名称,
|
||
ji.projects AS 分配项目,
|
||
ji.expire_time AS 过期时间,
|
||
ji.is_used AS 是否已使用,
|
||
ji.use_time AS 使用时间
|
||
FROM martial_judge_invite ji
|
||
LEFT JOIN martial_judge j ON ji.judge_id = j.id
|
||
LEFT JOIN martial_venue v ON ji.venue_id = v.id
|
||
WHERE ji.competition_id = 200 -- 替换为实际的比赛ID
|
||
AND ji.is_deleted = 0
|
||
ORDER BY ji.role DESC, ji.create_time DESC;
|
||
```
|
||
|
||
**示例结果**:
|
||
```
|
||
邀请码ID | 邀请码 | 角色 | 评委姓名 | 手机号 | 场地名称 | 过期时间
|
||
---------|--------|------------|-----------|------------|----------|------------------
|
||
1 | ADMIN01| chief_judge| 张裁判长 | 13800001001| NULL | 2025-12-18 23:59
|
||
2 | JUDGE01| judge | 李评委 | 13800001002| 一号场地 | 2025-12-18 23:59
|
||
3 | JUDGE02| judge | 王评委 | 13800001003| 二号场地 | 2025-12-18 23:59
|
||
```
|
||
|
||
### 3. 组合查询(完整登录信息)
|
||
|
||
```sql
|
||
-- 查询完整的登录信息(比赛编码+邀请码)
|
||
SELECT
|
||
c.competition_code AS 比赛编码,
|
||
c.competition_name AS 比赛名称,
|
||
ji.invite_code AS 邀请码,
|
||
CASE
|
||
WHEN ji.role = 'chief_judge' THEN '总裁判/裁判长'
|
||
ELSE '普通裁判'
|
||
END AS 角色类型,
|
||
j.name AS 评委姓名,
|
||
v.venue_name AS 场地名称,
|
||
ji.expire_time AS 邀请码过期时间,
|
||
CASE
|
||
WHEN ji.is_used = 1 THEN CONCAT('已使用(', ji.use_time, ')')
|
||
ELSE '未使用'
|
||
END AS 使用状态
|
||
FROM martial_competition c
|
||
INNER JOIN martial_judge_invite ji ON c.id = ji.competition_id
|
||
LEFT JOIN martial_judge j ON ji.judge_id = j.id
|
||
LEFT JOIN martial_venue v ON ji.venue_id = v.id
|
||
WHERE c.id = 200 -- 替换为实际的比赛ID
|
||
AND c.is_deleted = 0
|
||
AND ji.is_deleted = 0
|
||
ORDER BY ji.role DESC, ji.create_time;
|
||
```
|
||
|
||
**示例结果**:
|
||
```
|
||
比赛编码 | 比赛名称 | 邀请码 | 角色类型 | 评委姓名 | 场地名称
|
||
--------|------------------------|--------|--------------|---------|----------
|
||
WS2025 | 2025年全国武术散打锦标赛| ADMIN01| 总裁判/裁判长 | 张裁判长 | (全部场地)
|
||
WS2025 | 2025年全国武术散打锦标赛| JUDGE01| 普通裁判 | 李评委 | 一号场地
|
||
WS2025 | 2025年全国武术散打锦标赛| JUDGE02| 普通裁判 | 王评委 | 二号场地
|
||
```
|
||
|
||
---
|
||
|
||
## 🌐 方式二:通过后端API查询
|
||
|
||
### 1. 查询比赛列表
|
||
|
||
**接口**: `GET http://localhost:8080/martial/competition/list`
|
||
|
||
**参数**:
|
||
```json
|
||
{
|
||
"current": 1,
|
||
"size": 10
|
||
}
|
||
```
|
||
|
||
**响应**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"success": true,
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"id": 200,
|
||
"competitionName": "2025年全国武术散打锦标赛",
|
||
"competitionCode": "WS2025",
|
||
"competitionStartTime": "2025-11-06 08:00:00",
|
||
"competitionEndTime": "2025-11-08 18:00:00"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 查询邀请码列表
|
||
|
||
**接口**: `GET http://localhost:8080/martial/judgeInvite/list`
|
||
|
||
**参数**:
|
||
```json
|
||
{
|
||
"current": 1,
|
||
"size": 10,
|
||
"competitionId": 200
|
||
}
|
||
```
|
||
|
||
**响应**:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"success": true,
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"id": 1,
|
||
"inviteCode": "ADMIN01",
|
||
"role": "chief_judge",
|
||
"judgeId": 1,
|
||
"competitionId": 200,
|
||
"venueId": null,
|
||
"projects": "[1001,1002,1003]",
|
||
"expireTime": "2025-12-18 23:59:59",
|
||
"isUsed": 0
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🖥️ 方式三:通过Swagger API文档查看
|
||
|
||
### 访问步骤
|
||
|
||
1. **启动后端服务**
|
||
```bash
|
||
cd D:\workspace\31.比赛项目\project\martial-master
|
||
# 使用IDEA运行 Application.java
|
||
```
|
||
|
||
2. **访问Swagger文档**
|
||
```
|
||
http://localhost:8080/doc.html
|
||
```
|
||
|
||
3. **查看比赛管理接口**
|
||
- 找到 "赛事管理" 模块
|
||
- 点击 `GET /martial/competition/list` 接口
|
||
- 点击 "调试" 按钮
|
||
- 输入参数后点击 "发送"
|
||
- 查看响应中的 `competitionCode` 字段
|
||
|
||
4. **查看邀请码管理接口**
|
||
- 找到 "裁判邀请码管理" 模块
|
||
- 点击 `GET /martial/judgeInvite/list` 接口
|
||
- 点击 "调试" 按钮
|
||
- 输入 `competitionId` 参数
|
||
- 查看响应中的 `inviteCode` 字段
|
||
|
||
---
|
||
|
||
## 📝 方式四:通过管理后台查看(如果有前端管理系统)
|
||
|
||
如果您的项目有后台管理系统(通常是另一个前端项目),可以:
|
||
|
||
1. **登录后台管理系统**
|
||
- 访问管理后台地址(例如: `http://localhost:8081`)
|
||
- 使用管理员账号登录
|
||
|
||
2. **查看比赛编码**
|
||
- 进入 "赛事管理" 菜单
|
||
- 在比赛列表中查看 "赛事编码" 列
|
||
|
||
3. **查看邀请码**
|
||
- 进入 "裁判管理" → "邀请码管理" 菜单
|
||
- 选择对应的比赛
|
||
- 查看邀请码列表
|
||
|
||
---
|
||
|
||
## 🔧 如何生成新的比赛编码和邀请码
|
||
|
||
### 1. 创建新比赛(自动生成比赛编码)
|
||
|
||
```sql
|
||
INSERT INTO martial_competition (
|
||
competition_name,
|
||
competition_code, -- 手动指定或自动生成
|
||
competition_start_time,
|
||
competition_end_time,
|
||
venue_address,
|
||
create_time,
|
||
update_time,
|
||
is_deleted
|
||
) VALUES (
|
||
'2025年春季武术锦标赛',
|
||
'WS2025SPRING', -- 比赛编码(建议格式:项目缩写+年份+季节)
|
||
'2025-03-15 08:00:00',
|
||
'2025-03-17 18:00:00',
|
||
'北京体育馆',
|
||
NOW(),
|
||
NOW(),
|
||
0
|
||
);
|
||
```
|
||
|
||
**比赛编码命名建议**:
|
||
- 格式: `项目缩写 + 年份 + 季节/序号`
|
||
- 示例:
|
||
- `WS2025SPRING` (武术2025春季)
|
||
- `WS2025_01` (武术2025第1场)
|
||
- `TJQ2025` (太极拳2025)
|
||
|
||
### 2. 生成评委邀请码
|
||
|
||
```sql
|
||
-- 为裁判长生成邀请码
|
||
INSERT INTO martial_judge_invite (
|
||
competition_id,
|
||
judge_id,
|
||
invite_code, -- 邀请码(建议随机生成)
|
||
role, -- chief_judge 或 judge
|
||
venue_id, -- 裁判长为NULL,普通裁判指定场地
|
||
projects, -- JSON数组格式: [1001,1002,1003]
|
||
expire_time,
|
||
is_used,
|
||
is_deleted,
|
||
create_time,
|
||
update_time
|
||
) VALUES (
|
||
200, -- 比赛ID
|
||
1, -- 评委ID
|
||
'ADMIN2025', -- 邀请码(裁判长)
|
||
'chief_judge',
|
||
NULL, -- 裁判长不固定场地
|
||
'[1001,1002,1003,1004,1005]', -- 所有项目
|
||
DATE_ADD(NOW(), INTERVAL 30 DAY), -- 30天后过期
|
||
0,
|
||
0,
|
||
NOW(),
|
||
NOW()
|
||
);
|
||
|
||
-- 为普通裁判生成邀请码
|
||
INSERT INTO martial_judge_invite (
|
||
competition_id,
|
||
judge_id,
|
||
invite_code,
|
||
role,
|
||
venue_id, -- 指定场地
|
||
projects,
|
||
expire_time,
|
||
is_used,
|
||
is_deleted,
|
||
create_time,
|
||
update_time
|
||
) VALUES (
|
||
200,
|
||
2,
|
||
'JUDGE001', -- 邀请码(普通裁判)
|
||
'judge',
|
||
1, -- 一号场地
|
||
'[1001,1002]', -- 分配的项目
|
||
DATE_ADD(NOW(), INTERVAL 30 DAY),
|
||
0,
|
||
0,
|
||
NOW(),
|
||
NOW()
|
||
);
|
||
```
|
||
|
||
**邀请码命名建议**:
|
||
- **裁判长**: `ADMIN + 年份` 或 `CHIEF + 编号`
|
||
- 示例: `ADMIN2025`, `CHIEF001`
|
||
- **普通裁判**: `JUDGE + 编号`
|
||
- 示例: `JUDGE001`, `JUDGE002`, `JUDGE003`
|
||
- **建议使用随机生成**: 6-8位字母数字组合
|
||
- 示例: `A3K7M2`, `P9R4T1`
|
||
|
||
### 3. 批量生成邀请码的SQL脚本
|
||
|
||
```sql
|
||
-- 为一个比赛批量生成评委邀请码(假设已有评委数据)
|
||
DELIMITER $$
|
||
|
||
CREATE PROCEDURE generate_invite_codes(
|
||
IN p_competition_id BIGINT,
|
||
IN p_expire_days INT
|
||
)
|
||
BEGIN
|
||
DECLARE v_judge_id BIGINT;
|
||
DECLARE v_role VARCHAR(50);
|
||
DECLARE v_venue_id BIGINT;
|
||
DECLARE v_invite_code VARCHAR(50);
|
||
DECLARE v_counter INT DEFAULT 1;
|
||
DECLARE done INT DEFAULT FALSE;
|
||
|
||
-- 游标:遍历评委
|
||
DECLARE judge_cursor CURSOR FOR
|
||
SELECT id, role FROM martial_judge WHERE is_deleted = 0;
|
||
|
||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||
|
||
OPEN judge_cursor;
|
||
|
||
read_loop: LOOP
|
||
FETCH judge_cursor INTO v_judge_id, v_role;
|
||
IF done THEN
|
||
LEAVE read_loop;
|
||
END IF;
|
||
|
||
-- 生成邀请码
|
||
IF v_role = 'chief_judge' THEN
|
||
SET v_invite_code = CONCAT('ADMIN', LPAD(v_counter, 3, '0'));
|
||
SET v_venue_id = NULL;
|
||
ELSE
|
||
SET v_invite_code = CONCAT('JUDGE', LPAD(v_counter, 3, '0'));
|
||
SET v_venue_id = (v_counter % 4) + 1; -- 循环分配场地
|
||
END IF;
|
||
|
||
-- 插入邀请码
|
||
INSERT INTO martial_judge_invite (
|
||
competition_id, judge_id, invite_code, role, venue_id,
|
||
projects, expire_time, is_used, is_deleted, create_time, update_time
|
||
) VALUES (
|
||
p_competition_id, v_judge_id, v_invite_code, v_role, v_venue_id,
|
||
'[1001,1002,1003]',
|
||
DATE_ADD(NOW(), INTERVAL p_expire_days DAY),
|
||
0, 0, NOW(), NOW()
|
||
);
|
||
|
||
SET v_counter = v_counter + 1;
|
||
END LOOP;
|
||
|
||
CLOSE judge_cursor;
|
||
END$$
|
||
|
||
DELIMITER ;
|
||
|
||
-- 使用示例:为比赛ID=200生成邀请码,有效期30天
|
||
CALL generate_invite_codes(200, 30);
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 登录测试示例
|
||
|
||
### 测试数据准备
|
||
|
||
假设数据库中有以下数据:
|
||
|
||
**比赛信息**:
|
||
```
|
||
competition_id: 200
|
||
competition_code: WS2025
|
||
competition_name: 2025年全国武术散打锦标赛
|
||
```
|
||
|
||
**邀请码信息**:
|
||
```
|
||
invite_code: ADMIN01 (裁判长)
|
||
invite_code: JUDGE01 (普通裁判 - 一号场地)
|
||
invite_code: JUDGE02 (普通裁判 - 二号场地)
|
||
```
|
||
|
||
### 测试步骤
|
||
|
||
1. **启动后端服务**
|
||
```bash
|
||
cd D:\workspace\31.比赛项目\project\martial-master
|
||
# 运行 Application.java
|
||
```
|
||
|
||
2. **启动小程序前端**
|
||
```bash
|
||
cd D:\workspace\31.比赛项目\project\martial-admin-mini
|
||
# 使用HBuilderX运行到微信开发者工具
|
||
```
|
||
|
||
3. **测试裁判长登录**
|
||
- 访问登录页
|
||
- 输入 **比赛编码**: `WS2025`
|
||
- 输入 **邀请码**: `ADMIN01`
|
||
- 点击 "立即评分"
|
||
- **预期结果**: 跳转到 `/pages/score-list-multi/score-list-multi` (多场地管理页)
|
||
|
||
4. **测试普通裁判登录**
|
||
- 访问登录页
|
||
- 输入 **比赛编码**: `WS2025`
|
||
- 输入 **邀请码**: `JUDGE01`
|
||
- 点击 "立即评分"
|
||
- **预期结果**: 跳转到 `/pages/score-list/score-list` (评分列表页)
|
||
|
||
---
|
||
|
||
## ⚠️ 常见问题
|
||
|
||
### 问题1: 提示"邀请码不存在"
|
||
|
||
**可能原因**:
|
||
1. 邀请码输入错误(区分大小写)
|
||
2. 邀请码被标记为删除(is_deleted = 1)
|
||
3. 数据库中确实不存在该邀请码
|
||
|
||
**解决方法**:
|
||
```sql
|
||
-- 检查邀请码是否存在
|
||
SELECT * FROM martial_judge_invite
|
||
WHERE invite_code = 'YOUR_CODE'
|
||
AND is_deleted = 0;
|
||
```
|
||
|
||
### 问题2: 提示"比赛编码不匹配"
|
||
|
||
**可能原因**:
|
||
1. 比赛编码输入错误
|
||
2. 邀请码对应的比赛ID与输入的比赛编码不匹配
|
||
|
||
**解决方法**:
|
||
```sql
|
||
-- 检查邀请码对应的比赛编码
|
||
SELECT
|
||
ji.invite_code,
|
||
c.competition_code,
|
||
c.competition_name
|
||
FROM martial_judge_invite ji
|
||
INNER JOIN martial_competition c ON ji.competition_id = c.id
|
||
WHERE ji.invite_code = 'YOUR_CODE'
|
||
AND ji.is_deleted = 0;
|
||
```
|
||
|
||
### 问题3: 提示"邀请码已过期"
|
||
|
||
**可能原因**:
|
||
邀请码的 `expire_time` 字段已经早于当前时间
|
||
|
||
**解决方法**:
|
||
```sql
|
||
-- 延长邀请码有效期
|
||
UPDATE martial_judge_invite
|
||
SET expire_time = DATE_ADD(NOW(), INTERVAL 30 DAY)
|
||
WHERE invite_code = 'YOUR_CODE';
|
||
```
|
||
|
||
### 问题4: 登录成功但Token验证失败
|
||
|
||
**可能原因**:
|
||
1. Token未正确保存到localStorage
|
||
2. 请求头中未添加 Blade-Auth
|
||
3. Token已过期
|
||
|
||
**解决方法**:
|
||
```javascript
|
||
// 检查Token是否保存(浏览器控制台)
|
||
uni.getStorageSync('token')
|
||
|
||
// 检查请求头(Network面板)
|
||
// 应该有: Blade-Auth: Bearer xxxxx
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 快速查询脚本(复制即用)
|
||
|
||
```sql
|
||
-- ============================================
|
||
-- 快速查询当前可用的登录信息
|
||
-- ============================================
|
||
|
||
-- 查询所有可用的比赛编码和邀请码
|
||
SELECT
|
||
c.competition_code AS '比赛编码(输入到小程序)',
|
||
ji.invite_code AS '邀请码(输入到小程序)',
|
||
c.competition_name AS '比赛名称',
|
||
CASE
|
||
WHEN ji.role = 'chief_judge' THEN '✅ 总裁判/裁判长'
|
||
ELSE '👤 普通裁判'
|
||
END AS '角色',
|
||
j.name AS '评委姓名',
|
||
COALESCE(v.venue_name, '全部场地') AS '负责场地',
|
||
ji.expire_time AS '邀请码过期时间',
|
||
CASE
|
||
WHEN ji.is_used = 1 THEN '❌ 已使用'
|
||
WHEN ji.expire_time < NOW() THEN '⏰ 已过期'
|
||
ELSE '✅ 可用'
|
||
END AS '状态'
|
||
FROM martial_competition c
|
||
INNER JOIN martial_judge_invite ji ON c.id = ji.competition_id
|
||
LEFT JOIN martial_judge j ON ji.judge_id = j.id
|
||
LEFT JOIN martial_venue v ON ji.venue_id = v.id
|
||
WHERE c.is_deleted = 0
|
||
AND ji.is_deleted = 0
|
||
AND ji.expire_time > NOW() -- 只显示未过期的
|
||
ORDER BY c.id DESC, ji.role DESC, ji.create_time;
|
||
```
|
||
|
||
---
|
||
|
||
**文档版本**: v1.0
|
||
**最后更新**: 2025-12-11
|
||
**维护者**: Claude Code Assistant
|