feat: 添加Mock版本保护机制 - 基础架构完成
完成内容: ✅ 第一层保护: Git分支隔离 - 创建 v1.0-mock 标签 - 创建 feature/api-integration 分支 ✅ 第二层保护: 配置开关控制 - config/env.config.js (环境配置,支持Mock/API模式切换) ✅ 第三层保护: 代码架构分离 - utils/request.js (网络请求封装,支持Blade-Auth) - utils/dataAdapter.js (核心适配器,自动选择数据源) ✅ Mock数据模块 (4个文件): - mock/index.js (统一入口) - mock/login.js (登录Mock数据) - mock/athlete.js (选手Mock数据,含场地、项目) - mock/score.js (评分Mock数据,含扣分项、详情、修改) ✅ API接口模块 (4个文件): - api/index.js (统一入口) - api/auth.js (认证API,含后端接口规范) - api/athlete.js (选手API,含SQL示例) - api/score.js (评分API,含实现逻辑说明) 特性: - 通过修改 config/env.config.js 的 dataMode 即可切换Mock/API模式 - Mock模式: 完全离线,无需后端,UI功能完整 - API模式: 调用真实后端接口(需后端实现5个专用接口) - 零UI修改: 原有页面代码完全保护,仅替换数据源 下一步: - 修改5个页面使用 dataAdapter - 测试Mock模式功能 - 后端开发5个小程序专用接口 代码统计: - 新增11个文件 - 约1000行代码 - 完整的注释和使用说明
This commit is contained in:
162
mock/athlete.js
Normal file
162
mock/athlete.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Mock 数据 - 选手模块
|
||||
* 模拟选手列表数据
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取我的选手列表(普通评委)
|
||||
* @param {Object} params
|
||||
* @param {String} params.judgeId - 评委ID
|
||||
* @param {String} params.venueId - 场地ID
|
||||
* @param {String} params.projectId - 项目ID
|
||||
* @returns {Array} 选手列表(带评分状态)
|
||||
*/
|
||||
export function getMyAthletes(params) {
|
||||
// 模拟3个选手数据
|
||||
return [
|
||||
{
|
||||
athleteId: '1',
|
||||
name: '张三',
|
||||
idCard: '123456789000000000',
|
||||
team: '少林寺武术大学院',
|
||||
number: '123-4567898275',
|
||||
myScore: 8.906, // 我的评分
|
||||
totalScore: 8.907, // 总分
|
||||
scored: true, // 已评分
|
||||
scoreTime: '2025-06-25 09:15:00'
|
||||
},
|
||||
{
|
||||
athleteId: '2',
|
||||
name: '李四',
|
||||
idCard: '123456789000000001',
|
||||
team: '武当山武术学院',
|
||||
number: '123-4567898276',
|
||||
myScore: 8.901,
|
||||
totalScore: 8.902,
|
||||
scored: true,
|
||||
scoreTime: '2025-06-25 09:20:00'
|
||||
},
|
||||
{
|
||||
athleteId: '3',
|
||||
name: '王五',
|
||||
idCard: '123456789000000002',
|
||||
team: '峨眉派武术学校',
|
||||
number: '123-4567898277',
|
||||
myScore: null, // 未评分
|
||||
totalScore: null,
|
||||
scored: false,
|
||||
scoreTime: null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选手列表(裁判长)
|
||||
* @param {Object} params
|
||||
* @param {String} params.competitionId - 比赛ID
|
||||
* @param {String} params.venueId - 场地ID
|
||||
* @param {String} params.projectId - 项目ID
|
||||
* @returns {Array} 选手列表(带评分统计)
|
||||
*/
|
||||
export function getAthletesForAdmin(params) {
|
||||
// 模拟5个选手数据
|
||||
return [
|
||||
{
|
||||
athleteId: '1',
|
||||
name: '张三',
|
||||
idCard: '123456789000000000',
|
||||
team: '少林寺武术大学院',
|
||||
number: '123-4567898275',
|
||||
totalScore: 8.907,
|
||||
judgeCount: 6, // 已评分评委数
|
||||
totalJudges: 6, // 总评委数
|
||||
canModify: true // 可以修改(所有评委已评分)
|
||||
},
|
||||
{
|
||||
athleteId: '2',
|
||||
name: '李四',
|
||||
idCard: '123456789000000001',
|
||||
team: '武当山武术学院',
|
||||
number: '123-4567898276',
|
||||
totalScore: 8.902,
|
||||
judgeCount: 6,
|
||||
totalJudges: 6,
|
||||
canModify: true
|
||||
},
|
||||
{
|
||||
athleteId: '3',
|
||||
name: '王五',
|
||||
idCard: '123456789000000002',
|
||||
team: '峨眉派武术学校',
|
||||
number: '123-4567898277',
|
||||
totalScore: null,
|
||||
judgeCount: 3, // 只有3位评委评分
|
||||
totalJudges: 6,
|
||||
canModify: false // 不能修改(未全部评分)
|
||||
},
|
||||
{
|
||||
athleteId: '4',
|
||||
name: '赵六',
|
||||
idCard: '123456789000000003',
|
||||
team: '华山武术学院',
|
||||
number: '123-4567898278',
|
||||
totalScore: 8.899,
|
||||
judgeCount: 6,
|
||||
totalJudges: 6,
|
||||
canModify: true
|
||||
},
|
||||
{
|
||||
athleteId: '5',
|
||||
name: '孙七',
|
||||
idCard: '123456789000000004',
|
||||
team: '崆峒派武术学校',
|
||||
number: '123-4567898279',
|
||||
totalScore: 8.912,
|
||||
judgeCount: 6,
|
||||
totalJudges: 6,
|
||||
canModify: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场地列表
|
||||
* @param {Object} params
|
||||
* @param {String} params.competitionId - 比赛ID
|
||||
* @returns {Array} 场地列表
|
||||
*/
|
||||
export function getVenues(params) {
|
||||
return [
|
||||
{ id: '1', name: '第一场地' },
|
||||
{ id: '2', name: '第二场地' },
|
||||
{ id: '3', name: '第三场地' },
|
||||
{ id: '4', name: '第四场地' },
|
||||
{ id: '5', name: '第五场地' }
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @param {Object} params
|
||||
* @param {String} params.competitionId - 比赛ID
|
||||
* @returns {Array} 项目列表
|
||||
*/
|
||||
export function getProjects(params) {
|
||||
return [
|
||||
'女子组长拳',
|
||||
'男子组陈氏太极拳',
|
||||
'女子组双剑(含长穗双剑)',
|
||||
'男子组杨氏太极拳',
|
||||
'女子组刀术',
|
||||
'男子组棍术',
|
||||
'女子组枪术',
|
||||
'男子组剑术'
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
getMyAthletes,
|
||||
getAthletesForAdmin,
|
||||
getVenues,
|
||||
getProjects
|
||||
}
|
||||
117
mock/index.js
Normal file
117
mock/index.js
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Mock数据中心
|
||||
* 所有Mock数据的统一入口
|
||||
*
|
||||
* 这个文件汇总了所有业务模块的Mock数据函数,
|
||||
* 提供给 dataAdapter.js 调用
|
||||
*/
|
||||
|
||||
import loginMock from './login.js'
|
||||
import athleteMock from './athlete.js'
|
||||
import scoreMock from './score.js'
|
||||
|
||||
/**
|
||||
* 导出所有Mock数据函数
|
||||
*
|
||||
* 资源名称(key)对应 dataAdapter.getData() 的第一个参数
|
||||
* 例如:dataAdapter.getData('login', params) 会调用 loginMock.login(params)
|
||||
*/
|
||||
export default {
|
||||
// ==================== 认证模块 ====================
|
||||
/**
|
||||
* 登录验证
|
||||
* @param {Object} params - { matchCode, inviteCode }
|
||||
* @returns {Object} 用户信息和Token
|
||||
*/
|
||||
login: loginMock.login,
|
||||
|
||||
// ==================== 选手模块 ====================
|
||||
/**
|
||||
* 获取我的选手列表(普通评委)
|
||||
* @param {Object} params - { judgeId, venueId, projectId }
|
||||
* @returns {Array} 选手列表(带评分状态)
|
||||
*/
|
||||
getMyAthletes: athleteMock.getMyAthletes,
|
||||
|
||||
/**
|
||||
* 获取选手列表(裁判长)
|
||||
* @param {Object} params - { competitionId, venueId, projectId }
|
||||
* @returns {Array} 选手列表(带评分统计)
|
||||
*/
|
||||
getAthletesForAdmin: athleteMock.getAthletesForAdmin,
|
||||
|
||||
/**
|
||||
* 获取场地列表
|
||||
* @param {Object} params - { competitionId }
|
||||
* @returns {Array} 场地列表
|
||||
*/
|
||||
getVenues: athleteMock.getVenues,
|
||||
|
||||
/**
|
||||
* 获取项目列表
|
||||
* @param {Object} params - { competitionId }
|
||||
* @returns {Array} 项目列表
|
||||
*/
|
||||
getProjects: athleteMock.getProjects,
|
||||
|
||||
// ==================== 评分模块 ====================
|
||||
/**
|
||||
* 获取扣分项列表
|
||||
* @param {Object} params - { projectId }
|
||||
* @returns {Array} 扣分项列表
|
||||
*/
|
||||
getDeductions: scoreMock.getDeductions,
|
||||
|
||||
/**
|
||||
* 提交评分
|
||||
* @param {Object} params - { athleteId, judgeId, score, deductions, note }
|
||||
* @returns {Object} 提交结果
|
||||
*/
|
||||
submitScore: scoreMock.submitScore,
|
||||
|
||||
/**
|
||||
* 获取评分详情(裁判长查看)
|
||||
* @param {Object} params - { athleteId }
|
||||
* @returns {Object} 评分详情(选手信息+评委评分)
|
||||
*/
|
||||
getScoreDetail: scoreMock.getScoreDetail,
|
||||
|
||||
/**
|
||||
* 修改评分(裁判长)
|
||||
* @param {Object} params - { athleteId, modifierId, modifiedScore, note }
|
||||
* @returns {Object} 修改结果
|
||||
*/
|
||||
modifyScore: scoreMock.modifyScore
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用说明:
|
||||
*
|
||||
* 这个文件不直接在页面中使用,而是通过 dataAdapter.js 间接调用。
|
||||
*
|
||||
* 页面使用示例:
|
||||
*
|
||||
* import dataAdapter from '@/utils/dataAdapter.js'
|
||||
*
|
||||
* // 登录
|
||||
* const res = await dataAdapter.getData('login', {
|
||||
* matchCode: '123',
|
||||
* inviteCode: 'pub'
|
||||
* })
|
||||
*
|
||||
* // 获取选手列表
|
||||
* const res = await dataAdapter.getData('getMyAthletes', {
|
||||
* judgeId: '456',
|
||||
* venueId: '1',
|
||||
* projectId: '5'
|
||||
* })
|
||||
*
|
||||
* // 提交评分
|
||||
* const res = await dataAdapter.getData('submitScore', {
|
||||
* athleteId: '1',
|
||||
* judgeId: '456',
|
||||
* score: 8.907,
|
||||
* deductions: [...],
|
||||
* note: '表现优秀'
|
||||
* })
|
||||
*/
|
||||
44
mock/login.js
Normal file
44
mock/login.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Mock 数据 - 登录模块
|
||||
* 模拟登录验证和用户信息返回
|
||||
*/
|
||||
|
||||
/**
|
||||
* 登录验证
|
||||
* @param {Object} params
|
||||
* @param {String} params.matchCode - 比赛编码
|
||||
* @param {String} params.inviteCode - 邀请码(pub 或 admin)
|
||||
* @returns {Object} 用户信息和Token
|
||||
*/
|
||||
export function login(params) {
|
||||
const { matchCode, inviteCode } = params
|
||||
|
||||
// 模拟验证逻辑
|
||||
const role = inviteCode.toLowerCase()
|
||||
|
||||
if (role !== 'pub' && role !== 'admin') {
|
||||
throw new Error('邀请码错误,请使用 pub 或 admin')
|
||||
}
|
||||
|
||||
// 返回Mock登录数据
|
||||
return {
|
||||
token: 'mock_token_' + Date.now(),
|
||||
userRole: role, // 'pub' 或 'admin'
|
||||
matchId: '123',
|
||||
matchName: '2025年全国武术散打锦标赛暨第十七届世界武术锦标赛选拔赛',
|
||||
matchTime: '2025年6月25日 9:00',
|
||||
judgeId: '456',
|
||||
judgeName: '欧阳丽娜',
|
||||
// 普通评委有固定场地,裁判长可以查看所有场地
|
||||
venueId: role === 'pub' ? '1' : null,
|
||||
venueName: role === 'pub' ? '第一场地' : null,
|
||||
// 分配的项目列表
|
||||
projects: role === 'pub'
|
||||
? ['女子组长拳', '男子组陈氏太极拳']
|
||||
: ['女子组长拳', '男子组陈氏太极拳', '女子组双剑(含长穗双剑)', '男子组杨氏太极拳', '女子组刀术', '男子组棍术', '女子组枪术', '男子组剑术']
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
login
|
||||
}
|
||||
162
mock/score.js
Normal file
162
mock/score.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Mock 数据 - 评分模块
|
||||
* 模拟评分相关数据
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取扣分项列表
|
||||
* @param {Object} params
|
||||
* @param {String} params.projectId - 项目ID
|
||||
* @returns {Array} 扣分项列表
|
||||
*/
|
||||
export function getDeductions(params) {
|
||||
// 模拟8个扣分项
|
||||
return [
|
||||
{ id: '1', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '2', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '3', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '4', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '5', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '6', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '7', text: '扣分项描述', score: -0.1, checked: false },
|
||||
{ id: '8', text: '扣分项描述', score: -0.1, checked: false }
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交评分
|
||||
* @param {Object} params
|
||||
* @param {String} params.athleteId - 选手ID
|
||||
* @param {String} params.judgeId - 评委ID
|
||||
* @param {Number} params.score - 评分
|
||||
* @param {Array} params.deductions - 扣分项
|
||||
* @param {String} params.note - 备注
|
||||
* @returns {Object} 提交结果
|
||||
*/
|
||||
export function submitScore(params) {
|
||||
const { athleteId, judgeId, score, deductions, note } = params
|
||||
|
||||
// 模拟提交成功
|
||||
console.log('Mock提交评分:', {
|
||||
athleteId,
|
||||
judgeId,
|
||||
score,
|
||||
deductions: deductions.filter(d => d.checked).length + '项',
|
||||
note
|
||||
})
|
||||
|
||||
return {
|
||||
scoreId: 'score_' + Date.now(),
|
||||
athleteId,
|
||||
judgeId,
|
||||
score,
|
||||
submitTime: new Date().toISOString(),
|
||||
message: '评分提交成功'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评分详情(裁判长查看)
|
||||
* @param {Object} params
|
||||
* @param {String} params.athleteId - 选手ID
|
||||
* @returns {Object} 评分详情
|
||||
*/
|
||||
export function getScoreDetail(params) {
|
||||
const { athleteId } = params
|
||||
|
||||
// 模拟选手信息和评委评分
|
||||
return {
|
||||
athleteInfo: {
|
||||
athleteId,
|
||||
name: '张三',
|
||||
idCard: '123456789000000000',
|
||||
team: '少林寺武术大学院',
|
||||
number: '123-4567898275',
|
||||
totalScore: 8.907
|
||||
},
|
||||
// 6位评委的评分
|
||||
judgeScores: [
|
||||
{
|
||||
judgeId: '1',
|
||||
judgeName: '欧阳丽娜',
|
||||
score: 8.907,
|
||||
scoreTime: '2025-06-25 09:15:00',
|
||||
note: ''
|
||||
},
|
||||
{
|
||||
judgeId: '2',
|
||||
judgeName: '张三',
|
||||
score: 8.901,
|
||||
scoreTime: '2025-06-25 09:15:30',
|
||||
note: ''
|
||||
},
|
||||
{
|
||||
judgeId: '3',
|
||||
judgeName: '裁判姓名',
|
||||
score: 8.902,
|
||||
scoreTime: '2025-06-25 09:16:00',
|
||||
note: ''
|
||||
},
|
||||
{
|
||||
judgeId: '4',
|
||||
judgeName: '裁判姓名',
|
||||
score: 8.907,
|
||||
scoreTime: '2025-06-25 09:16:30',
|
||||
note: ''
|
||||
},
|
||||
{
|
||||
judgeId: '5',
|
||||
judgeName: '裁判姓名',
|
||||
score: 8.905,
|
||||
scoreTime: '2025-06-25 09:17:00',
|
||||
note: ''
|
||||
},
|
||||
{
|
||||
judgeId: '6',
|
||||
judgeName: '裁判姓名',
|
||||
score: 8.904,
|
||||
scoreTime: '2025-06-25 09:17:30',
|
||||
note: ''
|
||||
}
|
||||
],
|
||||
// 修改记录(如果有)
|
||||
modification: null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改评分(裁判长)
|
||||
* @param {Object} params
|
||||
* @param {String} params.athleteId - 选手ID
|
||||
* @param {String} params.modifierId - 修改人ID(裁判长)
|
||||
* @param {Number} params.modifiedScore - 修改后的分数
|
||||
* @param {String} params.note - 修改原因
|
||||
* @returns {Object} 修改结果
|
||||
*/
|
||||
export function modifyScore(params) {
|
||||
const { athleteId, modifierId, modifiedScore, note } = params
|
||||
|
||||
// 模拟修改成功
|
||||
console.log('Mock修改评分:', {
|
||||
athleteId,
|
||||
modifierId,
|
||||
originalScore: 8.907,
|
||||
modifiedScore,
|
||||
note
|
||||
})
|
||||
|
||||
return {
|
||||
athleteId,
|
||||
originalScore: 8.907,
|
||||
modifiedScore,
|
||||
modifyTime: new Date().toISOString(),
|
||||
message: '评分修改成功'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getDeductions,
|
||||
submitScore,
|
||||
getScoreDetail,
|
||||
modifyScore
|
||||
}
|
||||
Reference in New Issue
Block a user