/** * 数据源适配器(核心文件) * 根据配置动态选择 Mock数据 或 真实API数据 * * 这是保护Mock版本UI的核心机制: * - Mock模式:使用本地Mock数据,不依赖后端,UI功能完整 * - API模式:调用真实后端接口,获取数据库数据 * * 通过修改 config/env.config.js 中的 dataMode 即可切换模式 */ import config from '@/config/env.config.js' /** * DataAdapter 类 * 单例模式,全局统一管理数据源 */ class DataAdapter { constructor() { this.mode = config.dataMode // 'mock' 或 'api' this.debug = config.debug this.mockDelay = config.mockDelay // 延迟加载,避免循环依赖 this.mockData = null this.apiService = null if (this.debug) { console.log(`[DataAdapter] 初始化完成,当前模式: ${this.mode}`) } } /** * 延迟加载 Mock 数据模块 */ async _loadMockData() { if (!this.mockData) { const mockModule = await import('@/mock/index.js') this.mockData = mockModule.default } return this.mockData } /** * 延迟加载 API 服务模块 */ async _loadApiService() { if (!this.apiService) { const apiModule = await import('@/api/index.js') this.apiService = apiModule.default } return this.apiService } /** * 统一数据获取接口 * @param {String} resource - 资源名称(如 'login', 'getMyAthletes') * @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 数据 * @private */ async _getMockData(resource, params) { if (this.debug) { console.log(`[Mock数据] 请求: ${resource}`, params) } try { // 模拟网络延迟 if (this.mockDelay > 0) { await this._delay(this.mockDelay) } // 加载Mock数据模块 const mockData = await this._loadMockData() // 检查资源是否存在 if (!mockData[resource]) { throw new Error(`Mock数据中未找到资源: ${resource}`) } // 调用Mock数据函数 const data = mockData[resource](params) if (this.debug) { console.log(`[Mock数据] 响应: ${resource}`, data) } // 返回统一格式 return { code: 200, message: '成功', data, success: true } } catch (error) { console.error(`[Mock数据] 错误: ${resource}`, error) throw { code: 500, message: error.message || 'Mock数据获取失败', data: null } } } /** * 获取 API 数据 * @private */ async _getApiData(resource, params) { if (this.debug) { console.log(`[API请求] 请求: ${resource}`, params) } try { // 加载API服务模块 const apiService = await this._loadApiService() // 检查接口是否存在 if (!apiService[resource]) { throw new Error(`API服务中未找到接口: ${resource}`) } // 调用API接口 const response = await apiService[resource](params) if (this.debug) { console.log(`[API请求] 响应: ${resource}`, response) } // API响应已经是统一格式(由 request.js 处理) return response } catch (error) { console.error(`[API请求] 错误: ${resource}`, error) // 重新抛出,由调用方处理 throw error } } /** * 延迟函数(模拟网络请求) * @private */ _delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } /** * 切换数据模式 * @param {String} mode - 'mock' 或 'api' */ switchMode(mode) { if (mode === 'mock' || mode === 'api') { this.mode = mode console.log(`[DataAdapter] 数据模式已切换为: ${mode}`) } else { console.error('[DataAdapter] 无效的数据模式,只能是 "mock" 或 "api"') } } /** * 获取当前模式 * @returns {String} 'mock' 或 'api' */ getMode() { return this.mode } /** * 检查是否为Mock模式 * @returns {Boolean} */ isMockMode() { return this.mode === 'mock' } /** * 检查是否为API模式 * @returns {Boolean} */ isApiMode() { return this.mode === 'api' } } // 导出单例 export default new DataAdapter() /** * 使用示例: * * // 在页面中使用 * import dataAdapter from '@/utils/dataAdapter.js' * * export default { * data() { * return { * players: [] * } * }, * * async onLoad() { * try { * // 获取数据(自动根据配置选择Mock或API) * const response = await dataAdapter.getData('getMyAthletes', { * judgeId: 123, * venueId: 1, * projectId: 5 * }) * * this.players = response.data * } catch (error) { * console.error('数据加载失败:', error.message) * } * }, * * methods: { * // 查看当前模式 * checkMode() { * console.log('当前数据模式:', dataAdapter.getMode()) * console.log('是否Mock模式:', dataAdapter.isMockMode()) * }, * * // 动态切换模式(开发调试用) * toggleMode() { * const newMode = dataAdapter.isMockMode() ? 'api' : 'mock' * dataAdapter.switchMode(newMode) * } * } * } * * --- * * 资源名称(resource)与Mock/API的映射关系: * * | resource | Mock函数 | API函数 | 说明 | * |---------------------|----------------------|---------------------|---------------| * | login | mockData.login | apiService.login | 登录验证 | * | getMyAthletes | mockData.getMyAthletes | apiService.getMyAthletes | 选手列表(评委) | * | getAthletesForAdmin | mockData.getAthletesForAdmin | apiService.getAthletesForAdmin | 选手列表(裁判长) | * | submitScore | mockData.submitScore | apiService.submitScore | 提交评分 | * | getScoreDetail | mockData.getScoreDetail | apiService.getScoreDetail | 评分详情 | * | modifyScore | mockData.modifyScore | apiService.modifyScore | 修改评分 | * | getDeductions | mockData.getDeductions | apiService.getDeductions | 扣分项列表 | * | getVenues | mockData.getVenues | apiService.getVenues | 场地列表 | * | getProjects | mockData.getProjects | apiService.getProjects | 项目列表 | */