Files
akmon/GLOBAL_CONFIG_MIGRATION_GUIDE.md
2026-01-20 08:04:15 +08:00

268 lines
8.6 KiB
Markdown
Raw Permalink 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.
# 全局配置表迁移实施指南
## 概述
当前 `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. 准备快速回滚方案
## 总结
新的全局配置系统提供了:
- ✅ 更科学的数据结构设计
- ✅ 更易维护的多语言支持
- ✅ 更好的扩展性和灵活性
- ✅ 向后兼容的迁移方案
通过渐进式迁移,可以确保业务连续性,同时升级到更现代化的配置管理方案。