# 全局配置表迁移实施指南 ## 概述 当前 `comindex.uvue` 使用的是 key 后缀方式的全局配置(如 `company_name_zh`),需要迁移到新的主表+翻译表设计。 ## 当前状态分析 ### 当前使用的表结构 ```sql -- 原有设计(key后缀方式) ak_global_configs ( config_key VARCHAR, -- 如: company_name_zh, company_name_en config_value TEXT, config_type VARCHAR, is_active BOOLEAN ) ``` ### 新设计的表结构 ```sql -- 新设计(主表+翻译表) ak_global_config ( id UUID, config_key VARCHAR, -- 如: company_name config_category VARCHAR, is_translatable BOOLEAN, default_value TEXT ) ak_global_config_translations ( config_id UUID, language_code VARCHAR, -- zh, en, tw, ja translated_value TEXT ) ``` ## 迁移步骤 ### 1. 数据库迁移 #### Step 1: 创建新表结构 ```bash # 执行新表结构创建脚本 psql -h your-host -U your-user -d your-db -f improved_global_config_with_translation.sql ``` #### Step 2: 数据迁移脚本 创建数据迁移脚本: ```sql -- migrate_global_config_data.sql DO $$ DECLARE config_record RECORD; zh_value TEXT; en_value TEXT; tw_value TEXT; ja_value TEXT; BEGIN -- 迁移公司名称 SELECT config_value INTO zh_value FROM ak_global_configs WHERE config_key = 'company_name_zh' AND is_active = true; SELECT config_value INTO en_value FROM ak_global_configs WHERE config_key = 'company_name_en' AND is_active = true; SELECT config_value INTO tw_value FROM ak_global_configs WHERE config_key = 'company_name_tw' AND is_active = true; SELECT config_value INTO ja_value FROM ak_global_configs WHERE config_key = 'company_name_ja' AND is_active = true; -- 插入主配置 INSERT INTO ak_global_config (config_key, config_category, is_translatable, sort_order) VALUES ('company_name', 'company', true, 1) ON CONFLICT (config_key) DO NOTHING; -- 获取配置ID并插入翻译 SELECT id INTO config_record FROM ak_global_config WHERE config_key = 'company_name'; IF zh_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'zh', zh_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF en_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'en', en_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF tw_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'tw', tw_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF ja_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'ja', ja_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; -- 迁移公司标语 SELECT config_value INTO zh_value FROM ak_global_configs WHERE config_key = 'company_slogan_zh' AND is_active = true; SELECT config_value INTO en_value FROM ak_global_configs WHERE config_key = 'company_slogan_en' AND is_active = true; SELECT config_value INTO tw_value FROM ak_global_configs WHERE config_key = 'company_slogan_tw' AND is_active = true; SELECT config_value INTO ja_value FROM ak_global_configs WHERE config_key = 'company_slogan_ja' AND is_active = true; INSERT INTO ak_global_config (config_key, config_category, is_translatable, sort_order) VALUES ('company_slogan', 'company', true, 2) ON CONFLICT (config_key) DO NOTHING; SELECT id INTO config_record FROM ak_global_config WHERE config_key = 'company_slogan'; IF zh_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'zh', zh_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF en_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'en', en_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF tw_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'tw', tw_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; IF ja_value IS NOT NULL THEN INSERT INTO ak_global_config_translations (config_id, language_code, translated_value) VALUES (config_record.id, 'ja', ja_value) ON CONFLICT (config_id, language_code) DO UPDATE SET translated_value = EXCLUDED.translated_value; END IF; -- 继续迁移其他配置项... -- (公司地址、热门搜索等,按照相同模式) RAISE NOTICE '数据迁移完成!'; END $$; ``` ### 2. 前端代码更新 #### 当前代码问题 ```javascript // 当前使用的旧方式 const result = await supa .from('ak_global_configs') // 复数表名 .select('*') .eq('is_active', true) // 基于语言后缀的配置获取 const nameConfig = companyConfigMap.value.get(`company_name${langSuffix}`) ``` #### 解决方案 我已经在 `comindex.uvue` 中添加了新的配置加载函数,它支持: 1. **主方法**: 使用 RPC 函数 `get_config_by_language` 2. **备用方法**: 查询视图 `vw_global_config_multilingual` 3. **兜底方案**: 使用硬编码的默认值 #### 迁移验证 ```javascript // 测试新配置加载 const testNewConfig = async () => { try { const { data, error } = await supa .rpc('get_config_by_language', { lang_code: 'zh' }) console.log('新配置系统测试:', data) if (error) { console.error('RPC调用失败:', error) // 测试备用方法 const { data: fallbackData } = await supa .from('vw_global_config_multilingual') .select('*') .eq('language_code', 'zh') .eq('is_active', true) console.log('备用方法测试:', fallbackData) } } catch (e) { console.error('配置测试失败:', e) } } ``` ### 3. 渐进式迁移策略 #### 阶段1: 并行运行 - 保持原有 `ak_global_configs` 表不变 - 新建 `ak_global_config` 和 `ak_global_config_translations` 表 - 前端代码支持两种方式,优先使用新方式 #### 阶段2: 数据同步 - 将原有数据迁移到新表结构 - 验证数据完整性和功能正常性 - 监控性能和错误 #### 阶段3: 完全切换 - 前端代码移除旧方式的兼容代码 - 删除或重命名原有表(如有需要) ### 4. 验证清单 #### 数据验证 - [ ] 所有配置项都已迁移到新表 - [ ] 多语言翻译完整且正确 - [ ] 配置分类和排序正确 - [ ] 非翻译配置项的默认值正确 #### 功能验证 - [ ] 页面加载时配置正确显示 - [ ] 语言切换时配置正确更新 - [ ] 错误处理和默认值生效 - [ ] 性能满足要求 #### 兼容性验证 - [ ] 新旧系统可以并行运行 - [ ] 备用方案正常工作 - [ ] 数据回滚方案可行 ### 5. 回滚计划 如果迁移出现问题,可以: 1. **立即回滚**: 在前端代码中禁用新配置方式 2. **数据回滚**: 从备份恢复原有表数据 3. **配置回滚**: 重新启用旧的配置获取逻辑 ### 6. 监控和优化 #### 性能监控 - 配置加载时间 - 数据库查询性能 - 错误率和成功率 #### 优化建议 - 配置数据缓存 - 批量查询优化 - 索引优化 ## 部署建议 ### 测试环境部署 1. 执行 `improved_global_config_with_translation.sql` 2. 执行数据迁移脚本 3. 部署更新后的前端代码 4. 进行功能测试 ### 生产环境部署 1. 维护窗口期间执行数据库迁移 2. 部署前端代码更新 3. 监控系统运行状况 4. 准备快速回滚方案 ## 总结 新的全局配置系统提供了: - ✅ 更科学的数据结构设计 - ✅ 更易维护的多语言支持 - ✅ 更好的扩展性和灵活性 - ✅ 向后兼容的迁移方案 通过渐进式迁移,可以确保业务连续性,同时升级到更现代化的配置管理方案。