Files
martial-admin-mini/doc/保护Mock版本的实施方案.md
宅房 7bd197f4ac Mock版本完成 - UI冻结版本
完成内容:
- 5个完整的UI页面(登录、评分列表、评分详情、多场地列表、修改评分)
- 完整的Mock数据展示
- 完整的业务逻辑实现
- 文档体系建立(2000+行文档)

文档包含:
- 项目概述.md
- 页面功能说明.md
- API接口设计.md (17个接口)
- 数据结构设计.md (17个接口定义)
- 功能模块划分.md
- 后端实现对比报告.md
- 数据可行性分析报告.md (95分评估)
- 保护Mock版本的实施方案.md (4层保护机制)
- API对接完成度检查报告.md

此版本为Mock原型版本,所有UI功能完整,数据为硬编码Mock数据。
2025-12-11 13:22:19 +08:00

1041 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# 保护Mock版本的完整实施方案
## 方案目标
在对接后端API的同时**永久保护当前的Mock版本UI代码**,确保:
1. ✅ Mock版本UI代码不被修改
2. ✅ 可随时切换Mock模式和API模式
3. ✅ 支持独立演示Mock版本
4. ✅ 便于团队协作开发
---
## 一、保护策略总览
### 1.1 多层保护机制
```
┌─────────────────────────────────────────┐
│ 第一层Git分支隔离 │
│ - main分支永久保存Mock版本 │
│ - feature/api分支API对接开发 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 第二层:配置开关控制 │
│ - dataMode: 'mock' | 'api' │
│ - 运行时动态切换数据源 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 第三层:代码架构分离 │
│ - Mock数据独立目录 │
│ - API调用独立目录 │
│ - 业务逻辑层统一适配 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 第四层:文档备份 │
│ - 完整的Mock版本文档存档 │
│ - 代码快照保存 │
└─────────────────────────────────────────┘
```
---
## 二、Git分支管理方案第一层保护
### 2.1 分支结构设计
```
main (Mock版本永久保护)
├─ feature/api-integration (API对接开发)
│ │
│ ├─ feature/api-login (登录接口)
│ ├─ feature/api-score (评分接口)
│ └─ feature/api-admin (裁判长功能)
├─ release/v1.0-mock (Mock版本发布)
└─ release/v2.0-api (API版本发布)
```
### 2.2 实施步骤
#### 步骤1保存当前Mock版本
```bash
# 1. 确保所有更改已提交
git add .
git commit -m "✅ Mock版本完成 - UI冻结版本"
# 2. 打标签标记Mock版本
git tag -a v1.0-mock -m "Mock原型版本 - 完整UI展示"
# 3. 推送到远程
git push origin main
git push origin v1.0-mock
```
#### 步骤2创建API对接分支
```bash
# 1. 基于main创建API分支
git checkout -b feature/api-integration
# 2. 推送到远程
git push -u origin feature/api-integration
```
#### 步骤3开发过程中的保护
```bash
# ❌ 禁止直接在main分支修改
git checkout main
# ... 修改代码 (错误操作!)
# ✅ 正确始终在feature分支工作
git checkout feature/api-integration
# ... 修改代码
git add .
git commit -m "feat: 添加登录API对接"
git push
```
#### 步骤4快速切换版本
```bash
# 切换到Mock版本演示UI
git checkout main
# 切换到API版本开发/测试)
git checkout feature/api-integration
# 切换到特定标签
git checkout v1.0-mock
```
### 2.3 .gitignore 配置
```bash
# .gitignore
node_modules/
dist/
unpackage/
.DS_Store
*.log
# 开发环境配置(不提交)
.env.development.local
# 构建产物
*.zip
```
---
## 三、配置开关控制方案(第二层保护)
### 3.1 环境配置文件
#### 创建 `config/env.config.js`
```javascript
/**
* 环境配置
* 控制应用的数据源模式
*/
const ENV_CONFIG = {
// 开发环境
development: {
// 数据模式: 'mock' | 'api'
dataMode: 'mock',
// API基础路径
apiBaseURL: 'http://localhost:8080',
// 是否开启调试
debug: true,
// 请求超时时间(毫秒)
timeout: 30000
},
// 测试环境
test: {
dataMode: 'api',
apiBaseURL: 'http://test-api.yourdomain.com',
debug: true,
timeout: 30000
},
// 生产环境
production: {
dataMode: 'api',
apiBaseURL: 'https://api.yourdomain.com',
debug: false,
timeout: 30000
}
}
// 获取当前环境
const env = process.env.NODE_ENV || 'development'
// 导出配置
export default {
...ENV_CONFIG[env],
env
}
/**
* 使用说明:
*
* 1. Mock模式UI演示:
* 设置 dataMode: 'mock'
*
* 2. API模式真实对接:
* 设置 dataMode: 'api'
*
* 3. 动态切换:
* import config from '@/config/env.config.js'
* if (config.dataMode === 'mock') { ... }
*/
```
### 3.2 数据源适配器
#### 创建 `utils/dataAdapter.js`
```javascript
/**
* 数据源适配器
* 根据配置动态选择Mock数据或API数据
*/
import config from '@/config/env.config.js'
import mockData from '@/mock/index.js'
import apiService from '@/api/index.js'
class DataAdapter {
constructor() {
this.mode = config.dataMode
this.debug = config.debug
}
/**
* 统一数据获取接口
* @param {String} resource - 资源名称
* @param {Object} params - 请求参数
* @returns {Promise}
*/
async getData(resource, params = {}) {
if (this.mode === 'mock') {
return this._getMockData(resource, params)
} else {
return this._getApiData(resource, params)
}
}
/**
* 获取Mock数据
*/
async _getMockData(resource, params) {
if (this.debug) {
console.log(`[Mock数据] 请求: ${resource}`, params)
}
// 模拟网络延迟
await this._delay(300)
const data = mockData[resource](params)
if (this.debug) {
console.log(`[Mock数据] 响应: ${resource}`, data)
}
return {
code: 200,
message: '成功',
data
}
}
/**
* 获取API数据
*/
async _getApiData(resource, params) {
if (this.debug) {
console.log(`[API请求] 请求: ${resource}`, params)
}
const response = await apiService[resource](params)
if (this.debug) {
console.log(`[API请求] 响应: ${resource}`, response)
}
return response
}
/**
* 延迟函数(模拟网络请求)
*/
_delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
/**
* 切换数据模式
*/
switchMode(mode) {
if (mode === 'mock' || mode === 'api') {
this.mode = mode
console.log(`数据模式已切换为: ${mode}`)
} else {
console.error('无效的数据模式,只能是 "mock" 或 "api"')
}
}
/**
* 获取当前模式
*/
getMode() {
return this.mode
}
}
// 导出单例
export default new DataAdapter()
```
### 3.3 页面使用示例
#### 修改 `pages/login/login.vue`
```vue
<script>
import dataAdapter from '@/utils/dataAdapter.js'
import config from '@/config/env.config.js'
export default {
data() {
return {
matchCode: '',
inviteCode: '',
// 显示当前数据模式(开发时)
currentMode: config.dataMode
}
},
onLoad() {
// 开发环境显示数据模式
if (config.debug) {
console.log(`当前数据模式: ${config.dataMode}`)
}
},
methods: {
async handleSubmit() {
// 表单验证
if (!this.matchCode || !this.inviteCode) {
uni.showToast({ title: '请填写完整信息', icon: 'none' })
return
}
try {
uni.showLoading({ title: '登录中...' })
// 🔥 关键使用数据适配器自动选择Mock或API
const response = await dataAdapter.getData('login', {
matchCode: this.matchCode,
inviteCode: this.inviteCode
})
uni.hideLoading()
// 处理响应Mock和API返回格式相同
const { token, userRole, judgeId, judgeName, venueId } = response.data
// 保存Token
uni.setStorageSync('token', token)
// 保存用户信息
getApp().globalData = {
userRole,
matchCode: this.matchCode,
judgeId,
judgeName,
venueId
}
// 路由跳转
if (userRole === 'admin') {
uni.navigateTo({ url: '/pages/score-list-multi/score-list-multi' })
} else {
uni.navigateTo({ url: '/pages/score-list/score-list' })
}
} catch (error) {
uni.hideLoading()
uni.showToast({
title: error.message || '登录失败',
icon: 'none'
})
}
}
}
}
</script>
```
---
## 四、代码架构分离(第三层保护)
### 4.1 目录结构设计
```
martial-admin-mini/
├── config/
│ ├── env.config.js # 环境配置
│ └── api.config.js # API配置
├── mock/ # 🔥 Mock数据目录独立
│ ├── index.js # Mock数据入口
│ ├── login.js # 登录Mock数据
│ ├── athlete.js # 选手Mock数据
│ ├── score.js # 评分Mock数据
│ └── README.md # Mock数据说明
├── api/ # 🔥 API调用目录独立
│ ├── index.js # API入口
│ ├── auth.js # 认证API
│ ├── athlete.js # 选手API
│ ├── score.js # 评分API
│ └── README.md # API说明
├── utils/
│ ├── request.js # 网络请求封装
│ ├── dataAdapter.js # 🔥 数据适配器(核心)
│ └── storage.js # 本地存储工具
├── pages/
│ ├── login/
│ │ └── login.vue # ✅ UI代码不变
│ ├── score-list/
│ │ └── score-list.vue # ✅ UI代码不变
│ └── ...
└── doc/
├── Mock版本快照.md # Mock版本文档备份
└── 数据可行性分析报告.md
```
### 4.2 Mock数据模块
#### 创建 `mock/index.js`
```javascript
/**
* Mock数据中心
* 所有Mock数据的统一入口
*/
import loginMock from './login.js'
import athleteMock from './athlete.js'
import scoreMock from './score.js'
export default {
// 登录
login: loginMock.login,
// 选手列表
getMyAthletes: athleteMock.getMyAthletes,
getAthletesForAdmin: athleteMock.getAthletesForAdmin,
// 评分
submitScore: scoreMock.submitScore,
getScoreDetail: scoreMock.getScoreDetail,
modifyScore: scoreMock.modifyScore,
// 扣分项
getDeductions: scoreMock.getDeductions
}
```
#### 创建 `mock/login.js`
```javascript
/**
* 登录相关Mock数据
*/
export default {
/**
* 登录
*/
login(params) {
const { matchCode, inviteCode } = params
const role = inviteCode.toLowerCase()
// 模拟验证
if (role !== 'pub' && role !== 'admin') {
throw new Error('邀请码错误')
}
// 返回Mock数据
return {
token: 'mock_token_' + Date.now(),
userRole: role,
matchId: '123',
matchName: '2025年全国武术散打锦标赛暨第十七届世界武术锦标赛选拔赛',
matchTime: '2025年6月25日 9:00',
judgeId: '456',
judgeName: '欧阳丽娜',
venueId: role === 'pub' ? '1' : null,
venueName: role === 'pub' ? '第一场地' : null,
projects: ['女子组长拳', '男子组陈氏太极拳']
}
}
}
```
#### 创建 `mock/athlete.js`
```javascript
/**
* 选手相关Mock数据
*/
export default {
/**
* 获取我的选手列表(普通评委)
*/
getMyAthletes(params) {
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: null,
totalScore: null,
scored: false,
scoreTime: null
},
// ... 更多Mock数据
]
},
/**
* 获取选手列表(裁判长)
*/
getAthletesForAdmin(params) {
return [
{
athleteId: '1',
name: '张三',
idCard: '123456789000000000',
team: '少林寺武术大学院',
number: '123-4567898275',
totalScore: 8.907,
judgeCount: 6,
totalJudges: 6,
canModify: true
},
// ... 更多Mock数据
]
}
}
```
### 4.3 API调用模块
#### 创建 `api/index.js`
```javascript
/**
* API调用中心
* 所有API调用的统一入口
*/
import authApi from './auth.js'
import athleteApi from './athlete.js'
import scoreApi from './score.js'
export default {
// 登录
login: authApi.login,
// 选手列表
getMyAthletes: athleteApi.getMyAthletes,
getAthletesForAdmin: athleteApi.getAthletesForAdmin,
// 评分
submitScore: scoreApi.submitScore,
getScoreDetail: scoreApi.getScoreDetail,
modifyScore: scoreApi.modifyScore,
// 扣分项
getDeductions: scoreApi.getDeductions
}
```
#### 创建 `api/auth.js`
```javascript
/**
* 认证相关API
*/
import request from '@/utils/request.js'
export default {
/**
* 登录
*/
login(data) {
return request({
url: '/mini/login',
method: 'POST',
data
})
},
/**
* 退出登录
*/
logout() {
return request({
url: '/mini/logout',
method: 'POST'
})
},
/**
* Token验证
*/
verifyToken() {
return request({
url: '/mini/verify',
method: 'GET'
})
}
}
```
---
## 五、文档备份(第四层保护)
### 5.1 Mock版本快照文档
#### 创建 `doc/Mock版本快照.md`
```markdown
# Mock版本快照文档
## 版本信息
- **版本号**: v1.0-mock
- **创建时间**: 2025-12-11
- **Git标签**: v1.0-mock
- **Git提交**: c2f3313
- **分支**: main
## 页面列表
### 1. 登录页 (`pages/login/login.vue`)
- **功能**: 比赛编码 + 邀请码登录
- **角色**: pub普通评委, admin裁判长
- **数据**: 完全Mock无API依赖
### 2. 评分列表页 (`pages/score-list/score-list.vue`)
- **功能**: 选手列表展示,评分状态显示
- **数据**: 3个Mock选手数据
### 3. 评分详情页 (`pages/score-detail/score-detail.vue`)
- **功能**: 评分操作0.001精度),扣分项选择
- **数据**: 8个扣分项Mock数据
### 4. 多场地列表页 (`pages/score-list-multi/score-list-multi.vue`)
- **功能**: 5个场地 + 8个项目切换
- **数据**: 场地和项目Mock数据
### 5. 修改评分页 (`pages/modify-score/modify-score.vue`)
- **功能**: 查看评委评分,修改总分
- **数据**: 6位评委评分Mock数据
## Mock数据说明
所有Mock数据硬编码在组件的 `data()` 中,无外部依赖。
## 恢复Mock版本
```bash
git checkout v1.0-mock
```
```bash
git checkout main
```
## 运行Mock版本
```bash
# 确保在main分支
git checkout main
# 运行
npm run dev:mp-weixin
# 或
npm run dev:h5
```
```
### 5.2 代码备份策略
```bash
# 1. 创建压缩包备份
cd D:\workspace\31.比赛项目\project\
tar -czf martial-admin-mini-mock-v1.0-$(date +%Y%m%d).tar.gz martial-admin-mini/
# 2. 创建Git存档
cd martial-admin-mini
git archive --format=zip --output=../martial-admin-mini-mock-v1.0.zip v1.0-mock
# 3. 导出完整提交历史
git log --pretty=format:"%h - %an, %ar : %s" > ../git-history.txt
```
---
## 六、实施操作指南
### 6.1 初始化保护(首次执行)
```bash
# ========== 步骤1提交当前代码 ==========
cd D:\workspace\31.比赛项目\project\martial-admin-mini
git add .
git commit -m "✅ Mock版本完成 - 冻结UI代码"
# ========== 步骤2打标签 ==========
git tag -a v1.0-mock -m "Mock原型版本 - 完整UI展示"
# ========== 步骤3创建API分支 ==========
git checkout -b feature/api-integration
git push -u origin feature/api-integration
# ========== 步骤4创建目录结构 ==========
mkdir -p config mock api
# ========== 步骤5创建配置文件 ==========
# 创建 config/env.config.js
# 创建 utils/dataAdapter.js
# 创建 mock/index.js
# ... (根据上面的代码创建)
# ========== 步骤6测试Mock模式 ==========
# 设置 config/env.config.js 中 dataMode: 'mock'
npm run dev:mp-weixin
# ========== 步骤7提交保护机制 ==========
git add .
git commit -m "feat: 添加Mock版本保护机制"
git push
```
### 6.2 日常开发流程
```bash
# ========== API开发时 ==========
git checkout feature/api-integration
# 修改代码...
git add .
git commit -m "feat: 添加登录API对接"
git push
# ========== 演示Mock版本时 ==========
git checkout main
npm run dev:mp-weixin
# ========== 测试API版本时 ==========
git checkout feature/api-integration
# 修改 config/env.config.js: dataMode: 'api'
npm run dev:mp-weixin
```
### 6.3 紧急恢复流程
```bash
# ========== 如果API分支出错立即恢复Mock版本 ==========
git checkout main
# ========== 如果main分支被误修改 ==========
git reset --hard v1.0-mock
# ========== 如果本地代码全部丢失 ==========
git clone <repository-url>
git checkout v1.0-mock
```
---
## 七、团队协作规范
### 7.1 分支保护规则
**main分支保护**:
- ❌ 禁止直接push
- ❌ 禁止force push
- ✅ 只允许通过PR合并
- ✅ 需要代码审查
**feature分支规范**:
- ✅ 可以自由提交
- ✅ 定期合并main分支
- ✅ 完成后提PR到main
### 7.2 提交信息规范
```bash
# Mock版本相关
git commit -m "✅ Mock版本: 修复样式问题"
git commit -m "✅ Mock版本: 更新文档"
# API对接相关
git commit -m "feat: 添加登录API对接"
git commit -m "feat: 实现评分提交接口"
git commit -m "fix: 修复Token过期问题"
# 配置相关
git commit -m "config: 切换到Mock模式"
git commit -m "config: 更新API地址"
```
### 7.3 代码审查清单
**合并到main分支前检查**:
- [ ] UI代码是否被修改应该没有
- [ ] Mock数据是否完整
- [ ] 配置文件是否正确?
- [ ] 文档是否更新?
- [ ] 版本号是否更新?
---
## 八、配置开关使用指南
### 8.1 切换到Mock模式
```javascript
// config/env.config.js
const ENV_CONFIG = {
development: {
dataMode: 'mock', // ✅ 修改这里
apiBaseURL: 'http://localhost:8080',
debug: true,
timeout: 30000
}
}
```
**场景**:
- UI演示
- 前端独立开发
- 离线开发
- 快速原型展示
### 8.2 切换到API模式
```javascript
// config/env.config.js
const ENV_CONFIG = {
development: {
dataMode: 'api', // ✅ 修改这里
apiBaseURL: 'http://localhost:8080',
debug: true,
timeout: 30000
}
}
```
**场景**:
- 后端联调
- 真实数据测试
- 生产环境
- 集成测试
### 8.3 动态切换(高级)
```javascript
// 在代码中动态切换
import dataAdapter from '@/utils/dataAdapter.js'
// 切换到Mock模式
dataAdapter.switchMode('mock')
// 切换到API模式
dataAdapter.switchMode('api')
// 查看当前模式
console.log(dataAdapter.getMode())
```
---
## 九、验证清单
### 9.1 Mock版本验证
- [ ] 切换到main分支
- [ ] 设置 `dataMode: 'mock'`
- [ ] 运行项目
- [ ] 登录功能正常
- [ ] 所有页面正常显示
- [ ] Mock数据正常加载
- [ ] UI样式无变化
### 9.2 API版本验证
- [ ] 切换到feature分支
- [ ] 设置 `dataMode: 'api'`
- [ ] 确认后端服务已启动
- [ ] 运行项目
- [ ] API登录成功
- [ ] 数据正常加载
- [ ] Token正常传递
### 9.3 切换验证
- [ ] Mock → API 切换成功
- [ ] API → Mock 切换成功
- [ ] 配置文件生效
- [ ] 数据适配器正常工作
- [ ] 无报错
---
## 十、常见问题
### Q1: 如果不小心在main分支修改了代码怎么办
```bash
# 方案1撤销未提交的修改
git checkout -- .
# 方案2回退到上一次提交
git reset --hard HEAD
# 方案3回退到Mock版本标签
git reset --hard v1.0-mock
```
### Q2: 如何查看当前使用的数据模式?
```javascript
// 方法1查看配置文件
import config from '@/config/env.config.js'
console.log(config.dataMode)
# 方法2查看数据适配器
import dataAdapter from '@/utils/dataAdapter.js'
console.log(dataAdapter.getMode())
```
### Q3: Mock数据和API数据格式不一致怎么办
**方案**: 在数据适配器中统一格式
```javascript
// utils/dataAdapter.js
async _getApiData(resource, params) {
const response = await apiService[resource](params)
// 🔥 统一数据格式
return {
code: response.code,
message: response.msg || response.message,
data: this._transformData(response.data)
}
}
_transformData(data) {
// 根据需要转换数据格式
// 例如: Long → String, BigDecimal → Number
return data
}
```
### Q4: 如何给其他人演示Mock版本
```bash
# 方案1发送压缩包
git archive --format=zip --output=martial-admin-mini-mock.zip main
# 方案2提供Git地址和分支
git clone <repository-url>
git checkout main
# 确保 config/env.config.js 中 dataMode: 'mock'
npm install
npm run dev:mp-weixin
```
---
## 十一、总结
### ✅ 保护机制优势
1. **安全性**: 4层保护机制Mock版本不会被破坏
2. **灵活性**: 随时切换Mock/API模式
3. **可维护性**: 代码结构清晰,易于维护
4. **可扩展性**: 便于添加新的数据源
5. **团队协作**: 分支隔离,互不干扰
### 📊 实施成本
| 项目 | 预计时间 | 难度 |
|------|---------|------|
| Git分支设置 | 10分钟 | 简单 |
| 创建配置文件 | 30分钟 | 简单 |
| 创建数据适配器 | 1小时 | 中等 |
| Mock数据整理 | 2小时 | 简单 |
| 文档编写 | 1小时 | 简单 |
| **总计** | **约5小时** | **中等** |
### 🎯 最终效果
```
✅ Mock版本永久保护随时演示
✅ API版本独立开发不影响Mock
✅ 一键切换:配置文件控制
✅ 零UI改动完全兼容现有代码
```
---
**文档版本**: v1.0
**创建时间**: 2025-12-11
**适用项目**: martial-admin-mini
**维护人员**: 开发团队