Initial commit of akmon project
This commit is contained in:
267
GLOBAL_CONFIG_MIGRATION_GUIDE.md
Normal file
267
GLOBAL_CONFIG_MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# 全局配置表迁移实施指南
|
||||
|
||||
## 概述
|
||||
当前 `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. 准备快速回滚方案
|
||||
|
||||
## 总结
|
||||
|
||||
新的全局配置系统提供了:
|
||||
- ✅ 更科学的数据结构设计
|
||||
- ✅ 更易维护的多语言支持
|
||||
- ✅ 更好的扩展性和灵活性
|
||||
- ✅ 向后兼容的迁移方案
|
||||
|
||||
通过渐进式迁移,可以确保业务连续性,同时升级到更现代化的配置管理方案。
|
||||
Reference in New Issue
Block a user