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

22 KiB
Raw Blame History

保护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版本

# 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对接分支

# 1. 基于main创建API分支
git checkout -b feature/api-integration

# 2. 推送到远程
git push -u origin feature/api-integration

步骤3开发过程中的保护

# ❌ 禁止直接在main分支修改
git checkout main
# ... 修改代码 (错误操作!)

# ✅ 正确始终在feature分支工作
git checkout feature/api-integration
# ... 修改代码
git add .
git commit -m "feat: 添加登录API对接"
git push

步骤4快速切换版本

# 切换到Mock版本演示UI
git checkout main

# 切换到API版本开发/测试)
git checkout feature/api-integration

# 切换到特定标签
git checkout v1.0-mock

2.3 .gitignore 配置

# .gitignore
node_modules/
dist/
unpackage/
.DS_Store
*.log

# 开发环境配置(不提交)
.env.development.local

# 构建产物
*.zip

三、配置开关控制方案(第二层保护)

3.1 环境配置文件

创建 config/env.config.js

/**
 * 环境配置
 * 控制应用的数据源模式
 */

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

/**
 * 数据源适配器
 * 根据配置动态选择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

<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

/**
 * 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

/**
 * 登录相关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

/**
 * 选手相关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

/**
 * 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

/**
 * 认证相关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

# 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

git checkout main

运行Mock版本

# 确保在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 初始化保护(首次执行)

# ========== 步骤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 日常开发流程

# ========== 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 紧急恢复流程

# ========== 如果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 提交信息规范

# 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模式

// config/env.config.js
const ENV_CONFIG = {
  development: {
    dataMode: 'mock',  // ✅ 修改这里
    apiBaseURL: 'http://localhost:8080',
    debug: true,
    timeout: 30000
  }
}

场景:

  • UI演示
  • 前端独立开发
  • 离线开发
  • 快速原型展示

8.2 切换到API模式

// config/env.config.js
const ENV_CONFIG = {
  development: {
    dataMode: 'api',  // ✅ 修改这里
    apiBaseURL: 'http://localhost:8080',
    debug: true,
    timeout: 30000
  }
}

场景:

  • 后端联调
  • 真实数据测试
  • 生产环境
  • 集成测试

8.3 动态切换(高级)

// 在代码中动态切换
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分支修改了代码怎么办

# 方案1撤销未提交的修改
git checkout -- .

# 方案2回退到上一次提交
git reset --hard HEAD

# 方案3回退到Mock版本标签
git reset --hard v1.0-mock

Q2: 如何查看当前使用的数据模式?

// 方法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数据格式不一致怎么办

方案: 在数据适配器中统一格式

// 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版本

# 方案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 维护人员: 开发团队