# 前端页面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. 补充缺失的字段映射