-- =================================================================== -- 安全的全局配置表初始化脚本 -- 适配现有表结构,避免字段冲突 -- =================================================================== -- 首先检查现有的 ak_languages 表结构 DO $$ DECLARE rec RECORD; BEGIN RAISE NOTICE '========================================'; RAISE NOTICE '检查现有 ak_languages 表结构:'; RAISE NOTICE '========================================'; IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ak_languages') THEN FOR rec IN SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' ORDER BY ordinal_position LOOP RAISE NOTICE '列: % - 类型: % - 可空: % - 默认值: %', rec.column_name, rec.data_type, rec.is_nullable, rec.column_default; END LOOP; ELSE RAISE NOTICE 'ak_languages 表不存在'; END IF; RAISE NOTICE '========================================'; END $$; -- 检查并创建必要的扩展 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- 1. 检查并创建/修改主配置表 DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ak_global_config' ) THEN -- 如果主配置表不存在,创建新的主表+翻译表结构 CREATE TABLE public.ak_global_config ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, config_key VARCHAR(100) NOT NULL UNIQUE, config_type VARCHAR(50) DEFAULT 'string', config_category VARCHAR(50) DEFAULT 'general', default_value TEXT, is_translatable BOOLEAN DEFAULT false, is_active BOOLEAN DEFAULT true, sort_order INTEGER DEFAULT 0, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); RAISE NOTICE '已创建新的 ak_global_config 主表'; ELSE RAISE NOTICE 'ak_global_config 表已存在,检查是否需要添加字段'; -- 检查并添加缺失的字段 IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_global_config' AND column_name = 'config_category' ) THEN ALTER TABLE public.ak_global_config ADD COLUMN config_category VARCHAR(50) DEFAULT 'general'; RAISE NOTICE '已添加 config_category 字段'; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_global_config' AND column_name = 'is_translatable' ) THEN ALTER TABLE public.ak_global_config ADD COLUMN is_translatable BOOLEAN DEFAULT false; RAISE NOTICE '已添加 is_translatable 字段'; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_global_config' AND column_name = 'sort_order' ) THEN ALTER TABLE public.ak_global_config ADD COLUMN sort_order INTEGER DEFAULT 0; RAISE NOTICE '已添加 sort_order 字段'; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_global_config' AND column_name = 'default_value' ) THEN ALTER TABLE public.ak_global_config ADD COLUMN default_value TEXT; RAISE NOTICE '已添加 default_value 字段'; END IF; END IF; END $$; -- 2. 创建翻译表 CREATE TABLE IF NOT EXISTS public.ak_global_config_translations ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, config_id UUID NOT NULL REFERENCES public.ak_global_config(id) ON DELETE CASCADE, language_code VARCHAR(10) NOT NULL, translated_value TEXT NOT NULL, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), UNIQUE(config_id, language_code) ); -- 3. 适配现有的 ak_languages 表 DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ak_languages') THEN RAISE NOTICE '使用现有的 ak_languages 表'; -- 检查并添加可能缺失的字段 IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'sort_order' ) THEN ALTER TABLE public.ak_languages ADD COLUMN sort_order INTEGER DEFAULT 0; RAISE NOTICE '已为 ak_languages 表添加 sort_order 字段'; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'is_default' ) THEN ALTER TABLE public.ak_languages ADD COLUMN is_default BOOLEAN DEFAULT false; RAISE NOTICE '已为 ak_languages 表添加 is_default 字段'; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'native_name' ) THEN ALTER TABLE public.ak_languages ADD COLUMN native_name VARCHAR(100); RAISE NOTICE '已为 ak_languages 表添加 native_name 字段'; END IF; ELSE -- 创建新的语言表 CREATE TABLE public.ak_languages ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, code VARCHAR(10) NOT NULL UNIQUE, name VARCHAR(100) NOT NULL, native_name VARCHAR(100) NOT NULL, is_active BOOLEAN DEFAULT true, is_default BOOLEAN DEFAULT false, sort_order INTEGER DEFAULT 0, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); RAISE NOTICE '已创建新的 ak_languages 表'; END IF; END $$; -- 4. 创建索引 CREATE INDEX IF NOT EXISTS idx_ak_global_config_key ON public.ak_global_config(config_key); CREATE INDEX IF NOT EXISTS idx_ak_global_config_active ON public.ak_global_config(is_active); CREATE INDEX IF NOT EXISTS idx_ak_global_config_category ON public.ak_global_config(config_category); CREATE INDEX IF NOT EXISTS idx_ak_global_config_translatable ON public.ak_global_config(is_translatable); CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_config ON public.ak_global_config_translations(config_id); CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_lang ON public.ak_global_config_translations(language_code); CREATE INDEX IF NOT EXISTS idx_ak_global_config_translations_active ON public.ak_global_config_translations(is_active); CREATE INDEX IF NOT EXISTS idx_ak_languages_code ON public.ak_languages(code); CREATE INDEX IF NOT EXISTS idx_ak_languages_active ON public.ak_languages(is_active); -- 5. 安全地插入语言数据(动态构建 INSERT 语句) DO $$ DECLARE has_sort_order BOOLEAN; has_is_default BOOLEAN; has_native_name BOOLEAN; insert_sql TEXT; BEGIN -- 检查字段是否存在 SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'sort_order' ) INTO has_sort_order; SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'is_default' ) INTO has_is_default; SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' AND column_name = 'native_name' ) INTO has_native_name; -- 构建动态 INSERT 语句 insert_sql := 'INSERT INTO public.ak_languages (code, name'; IF has_native_name THEN insert_sql := insert_sql || ', native_name'; END IF; IF has_is_default THEN insert_sql := insert_sql || ', is_default'; END IF; IF has_sort_order THEN insert_sql := insert_sql || ', sort_order'; END IF; insert_sql := insert_sql || ') VALUES '; insert_sql := insert_sql || '(''zh'', ''Chinese Simplified'''; IF has_native_name THEN insert_sql := insert_sql || ', ''简体中文'''; END IF; IF has_is_default THEN insert_sql := insert_sql || ', true'; END IF; IF has_sort_order THEN insert_sql := insert_sql || ', 1'; END IF; insert_sql := insert_sql || '), (''en'', ''English'''; IF has_native_name THEN insert_sql := insert_sql || ', ''English'''; END IF; IF has_is_default THEN insert_sql := insert_sql || ', false'; END IF; IF has_sort_order THEN insert_sql := insert_sql || ', 2'; END IF; insert_sql := insert_sql || ') ON CONFLICT (code) DO UPDATE SET name = EXCLUDED.name'; IF has_native_name THEN insert_sql := insert_sql || ', native_name = EXCLUDED.native_name'; END IF; IF has_is_default THEN insert_sql := insert_sql || ', is_default = EXCLUDED.is_default'; END IF; IF has_sort_order THEN insert_sql := insert_sql || ', sort_order = EXCLUDED.sort_order'; END IF; -- 执行动态 SQL EXECUTE insert_sql; RAISE NOTICE '已安全插入语言数据'; RAISE NOTICE '执行的 SQL: %', insert_sql; END $$; -- 6. 显示最终的表结构确认 DO $$ DECLARE rec RECORD; BEGIN RAISE NOTICE '========================================'; RAISE NOTICE '最终的 ak_languages 表结构:'; FOR rec IN SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'ak_languages' ORDER BY ordinal_position LOOP RAISE NOTICE ' - % (%)', rec.column_name, rec.data_type; END LOOP; RAISE NOTICE '========================================'; RAISE NOTICE '语言数据:'; FOR rec IN SELECT code, name FROM public.ak_languages ORDER BY code LOOP RAISE NOTICE ' - %: %', rec.code, rec.name; END LOOP; RAISE NOTICE '========================================'; END $$;