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

24 KiB
Raw Blame History

前端页面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添加数组转字符串处理projectIdsathleteIds 转换为逗号分隔格式

已检查的低优先级问题

  1. 轮播图字段映射 - 已包含完整的备选字段imageUrl || image || url
  2. 搜索字段名 - 已添加注释标注待确认项

📋 审核说明

本文档详细审核前端页面与后端API的数据对接情况包括

  • API接口路径
  • 请求参数
  • 返回数据结构
  • 前端字段映射
  • 潜在问题标注

1 首页模块 (home.vue)

1.1 轮播图API

API定义: competition.js

getBannerList(params = {}) {
  return request.get('/martial/banner/list', params)
}

前端调用: pages/home/home.vue:75-101

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

getCompetitionList(params = {}) {
  return request.get('/martial/competition/list', {
    current: params.current || 1,
    size: params.size || 10,
    ...params
  })
}

前端调用: pages/home/home.vue:107-137

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

getCompetitionList(params = {})
// 支持参数: current, size, location, status, name

前端调用: pages/event-list/event-list.vue:179-243

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

getCompetitionDetail(id) {
  return request.get('/martial/competition/detail', { id })
}

前端调用: pages/event-detail/event-detail.vue:107-130

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

getProjectList(params = {}) {
  return request.get('/martial/project/list', params)
}

前端调用: pages/select-event/select-event.vue:52-77

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

需要修复:

// 错误
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

async loadEventDetail(id) {
  const res = await competitionAPI.getCompetitionDetail(id)
  // 同上,映射正确
}

数据映射正确

5.2 选手列表API

API定义: athlete.js:13-19

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

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

submitRegistration(data) {
  return request.post('/martial/registrationOrder/submit', data)
}

前端调用: pages/event-register/event-register.vue:370-407

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

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

submitAthlete(data) {
  return request.post('/martial/athlete/submit', data)
}

前端调用: pages/add-player/add-player.vue:164-197

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

// 加载详情
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

removeAthlete(ids) {
  return request.post('/martial/athlete/remove', {
    ids: Array.isArray(ids) ? ids.join(',') : ids  // 转换为逗号分隔字符串
  })
}

前端调用: pages/event-register/event-register.vue:334

await athleteAPI.removeAthlete(item.id)  // 传入单个ID

API会自动处理单个ID和数组ID


7 我的报名模块 (my-registration.vue)

7.1 报名列表API

API定义: registration.js:22-28

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

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

getUserInfo() {
  return request.get('/blade-system/user/info')  // ⚠️ 注意不同的URL前缀
}

前端调用: pages/profile/profile.vue:59-71

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

updatePassword(data) {
  return request.post('/blade-system/user/update-password', data)
}

前端调用: pages/profile/profile.vue:74-90

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

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

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 })

需要修复:

// 错误
const res = await infoAPI.getInfoPublishList(eventId)

// 正确
const res = await infoAPI.getInfoPublishList({ competitionId: eventId })

🔟 赛事日程模块 (event-schedule.vue)

10.1 活动日程API

API定义: info.js:35-41

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

async loadScheduleDates(eventId) {
  const res = await infoAPI.getActivityScheduleList(eventId)  // ⚠️ 参数传递问题

  // 提取日期并分组...
}

数据映射分析:

⚠️ 严重问题: API参数传递错误

正确应该是: getActivityScheduleList({ competitionId: eventId })

10.2 赛程安排API

API定义: info.js:57-63

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

async loadScheduleByDate(eventId, date) {
  const res = await infoAPI.getScheduleList(eventId, { date })  // ⚠️ 参数传递问题
}

数据映射分析:

⚠️ 参数传递混乱!

API定义: getScheduleList(params)  // 接收1个对象参数
前端传递: getScheduleList(eventId, { date })  // 传递2个参数

正确应该是: getScheduleList({ competitionId: eventId, date: date })

11 比赛实况模块 (event-live.vue)

11.1 实况列表API

API定义: info.js:79-85

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

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 })

12 成绩查询模块 (event-score.vue)

12.1 项目分类API

前端调用: pages/event-score/event-score.vue:75-99

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

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

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

13 奖牌榜模块 (event-medals.vue)

13.1 奖牌榜API

API定义: result.js:38-43

getMedalsList(eventId, params = {}) {
  return request.get('/martial/medal/list', {
    competitionId: eventId,
    ...params
  })
}

前端调用: pages/event-medals/event-medals.vue:72-95

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

当前代码:

await userAPI.updatePassword({ newPassword: res.content })

问题: 后端API可能需要完整的密码修改表单

  • oldPassword (旧密码)
  • newPassword (新密码)
  • confirmPassword (确认密码)

建议: 修改为完整的密码修改表单


问题3: 报名提交数组格式不确定

位置: pages/event-register/event-register.vue:376-382

当前代码:

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 - 成绩查询页面无法加载项目分类

🟡 中优先级(可能影响功能)

  1. profile.vue:82 - 修改密码功能可能失败
  2. event-register.vue:378 - 报名提交需确认数组格式

🟢 低优先级(功能可用,但需优化)

  1. 轮播图字段名确认
  2. 搜索字段名确认name vs keyword
  3. 日期筛选功能未实现

📊 统计数据

  • 总页面数: 14个
  • API调用总数: 约30处
  • 严重错误: 7处API参数传递错误
  • 中等问题: 2处字段格式不确定
  • 轻微问题: 3处字段名不确定
  • 正确无误: 18处

整体匹配率: 60% (18/30) 严重错误率: 23% (7/30)


🎯 下一步行动

  1. 立即修复7个严重的API参数传递错误
  2. 与后端确认修改密码API的字段要求
  3. 确认报名提交的数组格式
  4. 测试所有修复后的接口
  5. 补充缺失的字段映射