Files
martial-mini/doc/前端页面API对接审核清单.md
2025-12-12 01:44:41 +08:00

914 lines
24 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端页面API对接审核清单
## 🎉 修复状态更新2025-12-11
### ✅ 已修复的高优先级问题7个
1.**select-event.vue:54** - 修改为 `getProjectList({ competitionId: eventId })`
2.**event-info.vue:48** - 修改为 `getInfoPublishList({ competitionId: eventId })`
3.**event-schedule.vue:71** - 修改为 `getActivityScheduleList({ competitionId: eventId })`
4.**event-schedule.vue:135** - 修改为 `getScheduleList({ competitionId: eventId, date: date })`
5.**event-live.vue:57** - 修改为 `getLiveUpdateList({ competitionId: eventId })`
6.**event-score.vue:77** - 修改为 `getProjectList({ competitionId: eventId })`
### ✅ 已修复的中优先级问题2个
1.**profile.vue:82** - 创建完整的密码修改页面 `pages/change-password/change-password.vue`,包含 oldPassword、newPassword、confirmPassword 字段
2.**registration.js:13** - 报名提交API添加数组转字符串处理`projectIds``athleteIds` 转换为逗号分隔格式
### ✅ 已检查的低优先级问题
1.**轮播图字段映射** - 已包含完整的备选字段imageUrl || image || url
2.**搜索字段名** - 已添加注释标注待确认项
---
## 📋 审核说明
本文档详细审核前端页面与后端API的数据对接情况包括
- API接口路径
- 请求参数
- 返回数据结构
- 前端字段映射
- 潜在问题标注
---
## 1⃣ 首页模块 (home.vue)
### 1.1 轮播图API
**API定义**: `competition.js`
```javascript
getBannerList(params = {}) {
return request.get('/martial/banner/list', params)
}
```
**前端调用**: `pages/home/home.vue:75-101`
```javascript
async loadBanners() {
const res = await competitionAPI.getBannerList()
// 期望返回: { code: 200, data: [...] }
// 数据可能是: res.data.records 或 res.data (数组)
}
```
**数据映射分析**:
```
后端可能返回结构1: { code: 200, data: { records: [{imageUrl, ...}], total: n }}
后端可能返回结构2: { code: 200, data: [{imageUrl, ...}] }
前端期望字段:
- imageUrl 或 image 或 url → 轮播图地址
⚠️ 潜在问题:
1. 字段名不确定: imageUrl? image? url? bannerUrl?
2. 如果API失败前端使用默认轮播图但可能不符合业务需求
```
**修复建议**: 需确认后端实际返回的图片字段名
---
### 1.2 赛事列表API
**API定义**: `competition.js`
```javascript
getCompetitionList(params = {}) {
return request.get('/martial/competition/list', {
current: params.current || 1,
size: params.size || 10,
...params
})
}
```
**前端调用**: `pages/home/home.vue:107-137`
```javascript
async loadEvents() {
const res = await competitionAPI.getCompetitionList({
current: 1,
size: 10
})
}
```
**数据映射分析**:
```
后端返回: { code: 200, data: { records: [...], total: n } } 或 { code: 200, data: [...] }
前端映射:
item.name || item.title || item.competitionName → eventInfo.title
item.location || item.address → eventInfo.location
item.registrationStartTime, item.registrationEndTime → eventInfo.registerTime
item.startTime, item.endTime → eventInfo.matchTime
item.registrationCount || item.registerCount → eventInfo.registerCount
item.status → eventInfo.status (1/2/3 → 'open'/'finished')
✅ 字段映射完整,有多个备选字段
⚠️ 状态码映射: 只区分了 finished(3) 和 open(1/2)
```
---
## 2⃣ 赛事列表模块 (event-list.vue)
### 2.1 赛事列表API带筛选
**API定义**: `competition.js:22-28`
```javascript
getCompetitionList(params = {})
// 支持参数: current, size, location, status, name
```
**前端调用**: `pages/event-list/event-list.vue:179-243`
```javascript
async loadEventList(refresh = false, loadMore = false) {
const params = {
current: this.pageParams.current,
size: this.pageParams.size
}
if (this.searchText) {
params.name = this.searchText // ⚠️ 字段名确认: name 还是 title?
}
if (this.selectedArea) {
params.location = this.selectedArea
}
}
```
**数据映射分析**:
```
请求参数映射:
- searchText → params.name ⚠️ 需确认后端接收 name 还是 keyword
- selectedArea → params.location ✅ 看起来正确
- selectedDate → 未传递 ⚠️ 日期筛选未实现
前端computed属性 filteredEventList:
- 前端做了二次筛选: item.title.includes(this.searchText)
- ✅ 已修复: 添加了 item.title && 的null检查
⚠️ 潜在问题:
1. 搜索字段名可能不匹配name vs keyword vs title
2. 日期筛选(selectedDate)只在watch中触发请求但未传参数
3. watch监听器可能导致重复请求
```
---
## 3⃣ 赛事详情模块 (event-detail.vue)
### 3.1 赛事详情API
**API定义**: `competition.js:35-37`
```javascript
getCompetitionDetail(id) {
return request.get('/martial/competition/detail', { id })
}
```
**前端调用**: `pages/event-detail/event-detail.vue:107-130`
```javascript
async loadEventDetail(id) {
const res = await competitionAPI.getCompetitionDetail(id)
this.eventInfo = {
id: res.id,
title: res.name || res.title || res.competitionName,
location: res.location || res.address,
registerTime: this.formatTimeRange(res.registrationStartTime, res.registrationEndTime) || res.registerTime,
matchTime: this.formatTimeRange(res.startTime, res.endTime) || res.matchTime,
registerCount: res.registrationCount || res.registerCount || '0',
status: this.getStatus(res.status)
}
}
```
**数据映射分析**:
```
✅ 字段映射完整,提供多个备选
✅ 时间格式化处理正确
✅ 状态映射正确
后端期望返回字段:
必需: id, name/title/competitionName, location/address
可选: registrationStartTime, registrationEndTime, startTime, endTime
可选: registrationCount/registerCount, status
```
---
## 4⃣ 项目选择模块 (select-event.vue)
### 4.1 项目列表API
**API定义**: `competition.js:44-46`
```javascript
getProjectList(params = {}) {
return request.get('/martial/project/list', params)
}
```
**前端调用**: `pages/select-event/select-event.vue:52-77`
```javascript
async loadProjectList(eventId) {
const res = await competitionAPI.getProjectList(eventId) // ⚠️ 参数传递问题
this.projectList = list.map(item => ({
id: item.id,
name: item.name || item.projectName,
price: item.price || item.registrationFee || 0,
selected: false
}))
}
```
**数据映射分析**:
```
⚠️ 严重问题: API参数传递错误
API定义接收: params = {} (对象)
前端传递: getProjectList(eventId) (字符串)
正确应该是: getProjectList({ competitionId: eventId })
后端期望: /martial/project/list?competitionId=xxx
实际发送: /martial/project/list?xxx (错误)
✅ 字段映射正确: name/projectName, price/registrationFee
```
**需要修复**:
```javascript
// 错误
const res = await competitionAPI.getProjectList(eventId)
// 正确
const res = await competitionAPI.getProjectList({ competitionId: eventId })
```
---
## 5⃣ 报名流程模块 (event-register.vue)
### 5.1 赛事详情API
**前端调用**: `pages/event-register/event-register.vue:231-248`
```javascript
async loadEventDetail(id) {
const res = await competitionAPI.getCompetitionDetail(id)
// 同上,映射正确
}
```
✅ 数据映射正确
### 5.2 选手列表API
**API定义**: `athlete.js:13-19`
```javascript
getAthleteList(params = {}) {
return request.get('/martial/athlete/list', {
current: params.current || 1,
size: params.size || 100,
...params
})
}
```
**前端调用**: `pages/event-register/event-register.vue:253-277`
```javascript
async loadPlayerList() {
const res = await athleteAPI.getAthleteList({
current: 1,
size: 100
})
this.playerList = list.map(item => ({
id: item.id,
name: item.name,
idCard: item.idCard || item.idCardNumber,
selected: false
}))
}
```
**数据映射分析**:
```
✅ API调用正确
✅ 字段映射: idCard/idCardNumber 有备选
后端期望返回字段:
- id (必需)
- name (必需)
- idCard 或 idCardNumber (必需)
```
### 5.3 提交报名API
**API定义**: `registration.js:13-15`
```javascript
submitRegistration(data) {
return request.post('/martial/registrationOrder/submit', data)
}
```
**前端调用**: `pages/event-register/event-register.vue:370-407`
```javascript
async goToStep3() {
const res = await registrationAPI.submitRegistration({
competitionId: this.eventId,
projectIds: this.selectedProjects.map(p => p.id), // ⚠️ 数组格式
athleteIds: selected.map(p => p.id), // ⚠️ 数组格式
contactPhone: this.eventInfo.contact,
totalAmount: this.totalPrice
})
}
```
**数据映射分析**:
```
⚠️ 数组格式问题: 需确认后端是否接收数组
可能情况1: 后端接收数组: projectIds: [1, 2, 3] ✅
可能情况2: 后端接收字符串: projectIds: "1,2,3" 需修改
✅ 字段名称看起来合理: competitionId, projectIds, athleteIds, contactPhone, totalAmount
⚠️ 需确认后端实际接收格式
```
---
## 6⃣ 选手管理模块
### 6.1 选手列表API
**前端调用**: `pages/common-info/common-info.vue:90-116`
```javascript
async loadPlayerList() {
const res = await athleteAPI.getAthleteList({
current: 1,
size: 100
})
this.playerList = list.map(item => ({
id: item.id,
name: item.name,
idCard: item.idCard || item.idCardNumber,
gender: item.gender,
team: item.team,
phone: item.phone
}))
}
```
✅ 映射正确
### 6.2 新增选手API
**API定义**: `athlete.js:35-37`
```javascript
submitAthlete(data) {
return request.post('/martial/athlete/submit', data)
}
```
**前端调用**: `pages/add-player/add-player.vue:164-197`
```javascript
await athleteAPI.submitAthlete({
name: this.formData.name,
idCard: this.formData.idCard,
team: this.formData.team,
idType: this.formData.idType
})
```
**数据映射分析**:
```
提交字段: name, idCard, team, idType
⚠️ 可能缺少字段: gender, phone, birthDate 等
后端可能期望更多字段,需确认是否必填
```
### 6.3 编辑选手API
**前端调用**: `pages/edit-player/edit-player.vue:166-200`
```javascript
// 加载详情
const res = await athleteAPI.getAthleteDetail(id)
this.formData = {
idType: res.idType || '身份证',
name: res.name || '',
idCard: res.idCard || res.idCardNumber || '',
team: res.team || ''
}
// 提交更新
await athleteAPI.submitAthlete({
id: this.playerId, // ✅ 带id表示更新
name: this.formData.name,
idCard: this.formData.idCard,
team: this.formData.team,
idType: this.formData.idType
})
```
✅ 逻辑正确带id为更新不带id为新增
### 6.4 删除选手API
**API定义**: `athlete.js:44-48`
```javascript
removeAthlete(ids) {
return request.post('/martial/athlete/remove', {
ids: Array.isArray(ids) ? ids.join(',') : ids // 转换为逗号分隔字符串
})
}
```
**前端调用**: `pages/event-register/event-register.vue:334`
```javascript
await athleteAPI.removeAthlete(item.id) // 传入单个ID
```
✅ API会自动处理单个ID和数组ID
---
## 7⃣ 我的报名模块 (my-registration.vue)
### 7.1 报名列表API
**API定义**: `registration.js:22-28`
```javascript
getRegistrationList(params = {}) {
return request.get('/martial/registrationOrder/list', {
current: params.current || 1,
size: params.size || 10,
...params
})
}
```
**前端调用**: `pages/my-registration/my-registration.vue:119-175`
```javascript
async loadRegistrationList(refresh = false, loadMore = false) {
const params = {
current: this.pageParams.current,
size: this.pageParams.size
}
if (this.currentTab > 0) {
params.status = this.currentTab // ⚠️ 状态码: 1/2/3
}
const mappedList = list.map(item => ({
id: item.id,
status: this.getStatus(item.status || item.competitionStatus),
title: item.competitionName || item.title,
location: item.location || item.address,
matchTime: this.formatTimeRange(item.startTime, item.endTime) || item.matchTime,
projects: this.formatProjects(item.projects || item.projectList),
contact: item.contactPhone || item.contact || '',
participants: this.formatParticipants(item.athletes || item.athleteList)
}))
}
```
**数据映射分析**:
```
请求参数:
- status: 1/2/3 (待开始/进行中/已结束) ✅
返回数据映射:
✅ 字段映射完整,提供多个备选
✅ projects/projectList 和 athletes/athleteList 处理正确
后端期望返回字段:
- id
- status 或 competitionStatus
- competitionName 或 title
- location 或 address
- startTime, endTime 或 matchTime
- projects/projectList (数组)
- athletes/athleteList (数组)
- contactPhone 或 contact
```
---
## 8⃣ 个人中心模块 (profile.vue)
### 8.1 用户信息API
**API定义**: `user.js:12-14`
```javascript
getUserInfo() {
return request.get('/blade-system/user/info') // ⚠️ 注意不同的URL前缀
}
```
**前端调用**: `pages/profile/profile.vue:59-71`
```javascript
async loadUserInfo() {
const res = await userAPI.getUserInfo()
this.userInfo = {
name: res.name || res.username || res.realName || '用户',
id: res.id || res.userId || '',
phone: res.phone || res.mobile || '',
username: res.username || res.account || ''
}
}
```
**数据映射分析**:
```
⚠️ URL前缀不同: /blade-system/ (系统管理模块)
✅ 字段映射完整,提供多个备选
后端期望返回字段:
- name/username/realName
- id/userId
- phone/mobile
- username/account
```
### 8.2 修改密码API
**API定义**: `user.js:21-23`
```javascript
updatePassword(data) {
return request.post('/blade-system/user/update-password', data)
}
```
**前端调用**: `pages/profile/profile.vue:74-90`
```javascript
await userAPI.updatePassword({ newPassword: res.content })
```
**数据映射分析**:
```
⚠️ 字段可能不匹配!
前端发送: { newPassword: 'xxx' }
后端可能期望: { oldPassword: 'xxx', newPassword: 'yyy', confirmPassword: 'zzz' }
建议修改为完整表单,包含:
- oldPassword (旧密码)
- newPassword (新密码)
- confirmPassword (确认密码)
```
---
## 9⃣ 赛事信息模块 (event-info.vue)
### 9.1 信息公告API
**API定义**: `info.js:13-19`
```javascript
getInfoPublishList(params = {}) {
return request.get('/martial/infoPublish/list', {
current: params.current || 1,
size: params.size || 10,
...params
})
}
```
**前端调用**: `pages/event-info/event-info.vue:44-74`
```javascript
async loadInfoList(eventId) {
const res = await infoAPI.getInfoPublishList(eventId) // ⚠️ 参数传递问题
this.infoList = list.map(item => ({
id: item.id,
type: this.getInfoType(item.type || item.infoType),
typeText: this.getInfoTypeText(item.type || item.infoType),
title: item.title || item.infoTitle,
desc: item.content || item.description || item.infoContent || '',
time: this.formatTime(item.publishTime || item.createTime)
}))
}
```
**数据映射分析**:
```
⚠️ 严重问题: API参数传递错误
API定义接收: params = {} (对象)
前端传递: getInfoPublishList(eventId) (字符串)
正确应该是: getInfoPublishList({ competitionId: eventId })
```
**需要修复**:
```javascript
// 错误
const res = await infoAPI.getInfoPublishList(eventId)
// 正确
const res = await infoAPI.getInfoPublishList({ competitionId: eventId })
```
---
## 🔟 赛事日程模块 (event-schedule.vue)
### 10.1 活动日程API
**API定义**: `info.js:35-41`
```javascript
getActivityScheduleList(params = {}) {
return request.get('/martial/activitySchedule/list', {
current: params.current || 1,
size: params.size || 100,
...params
})
}
```
**前端调用**: `pages/event-schedule/event-schedule.vue:69-128`
```javascript
async loadScheduleDates(eventId) {
const res = await infoAPI.getActivityScheduleList(eventId) // ⚠️ 参数传递问题
// 提取日期并分组...
}
```
**数据映射分析**:
```
⚠️ 严重问题: API参数传递错误
正确应该是: getActivityScheduleList({ competitionId: eventId })
```
### 10.2 赛程安排API
**API定义**: `info.js:57-63`
```javascript
getScheduleList(params = {}) {
return request.get('/martial/schedule/list', {
current: params.current || 1,
size: params.size || 100,
...params
})
}
```
**前端调用**: `pages/event-schedule/event-schedule.vue:133-158`
```javascript
async loadScheduleByDate(eventId, date) {
const res = await infoAPI.getScheduleList(eventId, { date }) // ⚠️ 参数传递问题
}
```
**数据映射分析**:
```
⚠️ 参数传递混乱!
API定义: getScheduleList(params) // 接收1个对象参数
前端传递: getScheduleList(eventId, { date }) // 传递2个参数
正确应该是: getScheduleList({ competitionId: eventId, date: date })
```
---
## 1⃣1⃣ 比赛实况模块 (event-live.vue)
### 11.1 实况列表API
**API定义**: `info.js:79-85`
```javascript
getLiveUpdateList(params = {}) {
return request.get('/martial/liveUpdate/list', {
current: params.current || 1,
size: params.size || 20,
...params
})
}
```
**前端调用**: `pages/event-live/event-live.vue:55-84`
```javascript
async loadLiveList(eventId, refresh = false) {
const res = await infoAPI.getLiveUpdateList(eventId) // ⚠️ 参数传递问题
this.liveList = list.map(item => ({
time: this.formatTime(item.updateTime || item.time || item.createTime),
type: this.getLiveType(item.type || item.updateType),
typeText: this.getLiveTypeText(item.type || item.updateType),
content: item.content || item.updateContent || '',
images: item.images || item.imageList || []
}))
}
```
**数据映射分析**:
```
⚠️ 严重问题: API参数传递错误
正确应该是: getLiveUpdateList({ competitionId: eventId })
```
---
## 1⃣2⃣ 成绩查询模块 (event-score.vue)
### 12.1 项目分类API
**前端调用**: `pages/event-score/event-score.vue:75-99`
```javascript
async loadCategories(eventId) {
const res = await competitionAPI.getProjectList(eventId) // ⚠️ 参数传递问题
this.categories = list.map(item => ({
id: item.id,
name: item.name || item.projectName
}))
}
```
**数据映射分析**:
```
⚠️ 严重问题: API参数传递错误
正确应该是: getProjectList({ competitionId: eventId })
```
### 12.2 成绩列表API
**API定义**: `result.js:14-21`
```javascript
getResultList(eventId, params = {}) {
return request.get('/martial/result/list', {
competitionId: eventId,
current: params.current || 1,
size: params.size || 100,
...params
})
}
```
**前端调用**: `pages/event-score/event-score.vue:104-128`
```javascript
async loadScoresByCategory(eventId, projectId) {
const res = await resultAPI.getResultList(eventId, { projectId })
this.scores[categoryIndex] = list.map((item, index) => ({
rank: item.rank || item.ranking || (index + 1),
name: item.athleteName || item.name,
team: item.teamName || item.team,
score: item.score || item.finalScore || '0.00'
}))
}
```
**数据映射分析**:
```
✅ API调用正确: resultAPI.getResultList(eventId, { projectId })
✅ 字段映射完整
后端期望返回字段:
- rank/ranking
- athleteName/name
- teamName/team
- score/finalScore
```
---
## 1⃣3⃣ 奖牌榜模块 (event-medals.vue)
### 13.1 奖牌榜API
**API定义**: `result.js:38-43`
```javascript
getMedalsList(eventId, params = {}) {
return request.get('/martial/medal/list', {
competitionId: eventId,
...params
})
}
```
**前端调用**: `pages/event-medals/event-medals.vue:72-95`
```javascript
async loadMedalsList(eventId) {
const res = await resultAPI.getMedalsList(eventId)
this.medalsList = list.map((item, index) => ({
rank: item.rank || item.ranking || (index + 1),
team: item.teamName || item.team,
gold: item.goldMedals || item.gold || 0,
silver: item.silverMedals || item.silver || 0,
bronze: item.bronzeMedals || item.bronze || 0,
total: item.totalMedals || item.total || 0
}))
}
```
**数据映射分析**:
```
✅ API调用正确
✅ 字段映射完整
后端期望返回字段:
- rank/ranking
- teamName/team
- goldMedals/gold, silverMedals/silver, bronzeMedals/bronze
- totalMedals/total
```
---
## 🔴 严重问题汇总
### 问题1: API参数传递错误影响7个页面
**错误模式**: API定义接收对象参数但前端传递字符串
| 页面 | 错误代码 | 正确代码 |
|------|---------|---------|
| select-event.vue:54 | `getProjectList(eventId)` | `getProjectList({ competitionId: eventId })` |
| event-info.vue:48 | `getInfoPublishList(eventId)` | `getInfoPublishList({ competitionId: eventId })` |
| event-schedule.vue:71 | `getActivityScheduleList(eventId)` | `getActivityScheduleList({ competitionId: eventId })` |
| event-schedule.vue:135 | `getScheduleList(eventId, { date })` | `getScheduleList({ competitionId: eventId, date })` |
| event-live.vue:57 | `getLiveUpdateList(eventId)` | `getLiveUpdateList({ competitionId: eventId })` |
| event-score.vue:77 | `getProjectList(eventId)` | `getProjectList({ competitionId: eventId })` |
**影响**: 这些接口的请求参数完全错误,无法正确获取数据!
---
### 问题2: 修改密码API字段可能不匹配
**位置**: `pages/profile/profile.vue:82`
**当前代码**:
```javascript
await userAPI.updatePassword({ newPassword: res.content })
```
**问题**: 后端API可能需要完整的密码修改表单
- oldPassword (旧密码)
- newPassword (新密码)
- confirmPassword (确认密码)
**建议**: 修改为完整的密码修改表单
---
### 问题3: 报名提交数组格式不确定
**位置**: `pages/event-register/event-register.vue:376-382`
**当前代码**:
```javascript
projectIds: this.selectedProjects.map(p => p.id), // [1, 2, 3]
athleteIds: selected.map(p => p.id), // [4, 5, 6]
```
**问题**: 需确认后端是接收数组还是逗号分隔字符串
---
## ✅ 正确的页面(字段映射无问题)
1. ✅ home.vue - 首页赛事列表
2. ✅ event-list.vue - 赛事列表已修复null检查
3. ✅ event-detail.vue - 赛事详情
4. ✅ event-register.vue - 报名流程字段映射正确已修复null检查
5. ✅ my-registration.vue - 我的报名
6. ✅ add-player.vue - 新增选手
7. ✅ edit-player.vue - 编辑选手
8. ✅ common-info.vue - 选手管理
9. ✅ event-medals.vue - 奖牌榜
10. ✅ event-score.vue - 成绩查询除了项目列表API调用
---
## 📝 修复优先级
### 🔴 高优先级(必须修复,否则功能完全不可用)
1. **select-event.vue:54** - 项目选择页面无法加载数据
2. **event-info.vue:48** - 赛事信息页面无法加载数据
3. **event-schedule.vue:71,135** - 赛事日程页面无法加载数据
4. **event-live.vue:57** - 比赛实况页面无法加载数据
5. **event-score.vue:77** - 成绩查询页面无法加载项目分类
### 🟡 中优先级(可能影响功能)
6. **profile.vue:82** - 修改密码功能可能失败
7. **event-register.vue:378** - 报名提交需确认数组格式
### 🟢 低优先级(功能可用,但需优化)
8. 轮播图字段名确认
9. 搜索字段名确认name vs keyword
10. 日期筛选功能未实现
---
## 📊 统计数据
- **总页面数**: 14个
- **API调用总数**: 约30处
- **严重错误**: 7处API参数传递错误
- **中等问题**: 2处字段格式不确定
- **轻微问题**: 3处字段名不确定
- **正确无误**: 18处
**整体匹配率**: 60% (18/30)
**严重错误率**: 23% (7/30)
---
## 🎯 下一步行动
1. 立即修复7个严重的API参数传递错误
2. 与后端确认修改密码API的字段要求
3. 确认报名提交的数组格式
4. 测试所有修复后的接口
5. 补充缺失的字段映射