382 lines
16 KiB
PL/PgSQL
382 lines
16 KiB
PL/PgSQL
-- ===================================================================
|
||
-- ak_topics 多语言支持扩展
|
||
-- ===================================================================
|
||
|
||
-- 专题多语言翻译表
|
||
CREATE TABLE IF NOT EXISTS public.ak_topic_translations (
|
||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
topic_id uuid NOT NULL REFERENCES public.ak_topics(id) ON DELETE CASCADE,
|
||
language_code VARCHAR(10) NOT NULL, -- 如 'zh-CN', 'en', 'ja', 'zh-TW'
|
||
title VARCHAR(255) NOT NULL,
|
||
description TEXT,
|
||
meta_description TEXT,
|
||
meta_keywords TEXT[],
|
||
translation_method VARCHAR(32) DEFAULT 'ai', -- 'ai', 'human', 'hybrid'
|
||
ai_provider VARCHAR(32), -- 'openai', 'google', 'baidu', 'custom'
|
||
quality_score FLOAT,
|
||
ai_confidence FLOAT,
|
||
human_verified BOOLEAN DEFAULT false,
|
||
human_verified_by uuid, -- 参考 ak_users 表
|
||
human_verified_at TIMESTAMP WITH TIME ZONE,
|
||
tokens_used INTEGER,
|
||
processing_time_ms INTEGER,
|
||
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||
UNIQUE(topic_id, language_code)
|
||
);
|
||
|
||
-- 专题翻译索引
|
||
CREATE INDEX IF NOT EXISTS idx_topic_translations_topic ON public.ak_topic_translations(topic_id);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_translations_language ON public.ak_topic_translations(language_code);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_translations_method ON public.ak_topic_translations(translation_method);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_translations_quality ON public.ak_topic_translations(quality_score DESC);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_translations_verified ON public.ak_topic_translations(human_verified);
|
||
|
||
COMMENT ON TABLE public.ak_topic_translations IS '专题多语言翻译表';
|
||
COMMENT ON COLUMN public.ak_topic_translations.language_code IS '语言代码,如zh-CN、en、ja、zh-TW';
|
||
COMMENT ON COLUMN public.ak_topic_translations.translation_method IS '翻译方式:ai=AI翻译,human=人工翻译,hybrid=混合翻译';
|
||
COMMENT ON COLUMN public.ak_topic_translations.quality_score IS '翻译质量评分(0-1)';
|
||
|
||
-- ===================================================================
|
||
-- ak_topic_contents 多语言支持扩展
|
||
-- ===================================================================
|
||
|
||
-- 专题内容关联多语言翻译表
|
||
CREATE TABLE IF NOT EXISTS public.ak_topic_content_translations (
|
||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
topic_content_id uuid NOT NULL REFERENCES public.ak_topic_contents(id) ON DELETE CASCADE,
|
||
language_code VARCHAR(10) NOT NULL,
|
||
editor_note TEXT, -- 多语言编辑说明
|
||
translation_method VARCHAR(32) DEFAULT 'ai',
|
||
ai_provider VARCHAR(32),
|
||
quality_score FLOAT,
|
||
human_verified BOOLEAN DEFAULT false,
|
||
human_verified_by uuid,
|
||
human_verified_at TIMESTAMP WITH TIME ZONE,
|
||
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||
UNIQUE(topic_content_id, language_code)
|
||
);
|
||
|
||
-- 专题内容翻译索引
|
||
CREATE INDEX IF NOT EXISTS idx_topic_content_translations_content ON public.ak_topic_content_translations(topic_content_id);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_content_translations_language ON public.ak_topic_content_translations(language_code);
|
||
CREATE INDEX IF NOT EXISTS idx_topic_content_translations_quality ON public.ak_topic_content_translations(quality_score DESC);
|
||
|
||
COMMENT ON TABLE public.ak_topic_content_translations IS '专题内容关联多语言翻译表';
|
||
|
||
-- ===================================================================
|
||
-- 多语言专题视图和函数
|
||
-- ===================================================================
|
||
|
||
-- 多语言专题视图
|
||
CREATE OR REPLACE VIEW public.vw_multilingual_topics AS
|
||
SELECT
|
||
t.id,
|
||
t.title as original_title,
|
||
t.description as original_description,
|
||
t.topic_type,
|
||
t.status,
|
||
t.cover_image_url,
|
||
t.creator_id,
|
||
t.content_count,
|
||
t.view_count,
|
||
t.like_count,
|
||
t.share_count,
|
||
t.comment_count,
|
||
t.subscriber_count,
|
||
t.priority_level,
|
||
t.tags,
|
||
t.created_at,
|
||
t.updated_at,
|
||
-- 聚合翻译信息
|
||
COALESCE(
|
||
json_agg(
|
||
json_build_object(
|
||
'language_code', tt.language_code,
|
||
'title', tt.title,
|
||
'description', tt.description,
|
||
'meta_description', tt.meta_description,
|
||
'meta_keywords', tt.meta_keywords,
|
||
'quality_score', tt.quality_score,
|
||
'translation_method', tt.translation_method,
|
||
'human_verified', tt.human_verified
|
||
)
|
||
) FILTER (WHERE tt.id IS NOT NULL),
|
||
'[]'::json
|
||
) as translations
|
||
FROM public.ak_topics t
|
||
LEFT JOIN public.ak_topic_translations tt ON t.id = tt.topic_id
|
||
WHERE t.status IN ('active', 'featured')
|
||
GROUP BY t.id, t.title, t.description, t.topic_type, t.status, t.cover_image_url,
|
||
t.creator_id, t.content_count, t.view_count, t.like_count, t.share_count,
|
||
t.comment_count, t.subscriber_count, t.priority_level, t.tags,
|
||
t.created_at, t.updated_at;
|
||
|
||
COMMENT ON VIEW public.vw_multilingual_topics IS '多语言专题聚合视图';
|
||
|
||
-- 获取指定语言的专题列表函数
|
||
CREATE OR REPLACE FUNCTION public.get_topics_by_language(
|
||
p_language_code VARCHAR(10) DEFAULT 'zh-CN',
|
||
p_topic_type VARCHAR(32) DEFAULT NULL,
|
||
p_status VARCHAR(32) DEFAULT 'active',
|
||
p_limit INTEGER DEFAULT 20,
|
||
p_offset INTEGER DEFAULT 0
|
||
)
|
||
RETURNS TABLE (
|
||
topic_id uuid,
|
||
title VARCHAR(255),
|
||
description TEXT,
|
||
topic_type VARCHAR(32),
|
||
status VARCHAR(32),
|
||
cover_image_url TEXT,
|
||
content_count INTEGER,
|
||
view_count INTEGER,
|
||
like_count INTEGER,
|
||
share_count INTEGER,
|
||
comment_count INTEGER,
|
||
subscriber_count INTEGER,
|
||
priority_level INTEGER,
|
||
tags TEXT[],
|
||
translation_quality FLOAT,
|
||
created_at TIMESTAMP WITH TIME ZONE,
|
||
updated_at TIMESTAMP WITH TIME ZONE
|
||
) AS $$
|
||
BEGIN
|
||
RETURN QUERY
|
||
SELECT
|
||
t.id,
|
||
COALESCE(tt.title, t.title) as title,
|
||
COALESCE(tt.description, t.description) as description,
|
||
t.topic_type,
|
||
t.status,
|
||
t.cover_image_url,
|
||
t.content_count,
|
||
t.view_count,
|
||
t.like_count,
|
||
t.share_count,
|
||
t.comment_count,
|
||
t.subscriber_count,
|
||
t.priority_level,
|
||
t.tags,
|
||
tt.quality_score as translation_quality,
|
||
t.created_at,
|
||
t.updated_at
|
||
FROM public.ak_topics t
|
||
LEFT JOIN public.ak_topic_translations tt ON t.id = tt.topic_id
|
||
AND tt.language_code = p_language_code
|
||
WHERE (p_topic_type IS NULL OR t.topic_type = p_topic_type)
|
||
AND (p_status IS NULL OR t.status = p_status)
|
||
ORDER BY t.priority_level DESC, t.updated_at DESC
|
||
LIMIT p_limit OFFSET p_offset;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
COMMENT ON FUNCTION public.get_topics_by_language IS '获取指定语言的专题列表';
|
||
|
||
-- 获取专题详情(多语言)函数
|
||
CREATE OR REPLACE FUNCTION public.get_topic_detail(
|
||
p_topic_id uuid,
|
||
p_language_code VARCHAR(10) DEFAULT 'zh-CN'
|
||
)
|
||
RETURNS TABLE (
|
||
topic_id uuid,
|
||
title VARCHAR(255),
|
||
description TEXT,
|
||
meta_description TEXT,
|
||
meta_keywords TEXT[],
|
||
topic_type VARCHAR(32),
|
||
status VARCHAR(32),
|
||
cover_image_url TEXT,
|
||
creator_id uuid,
|
||
editor_id uuid,
|
||
content_count INTEGER,
|
||
view_count INTEGER,
|
||
like_count INTEGER,
|
||
share_count INTEGER,
|
||
comment_count INTEGER,
|
||
subscriber_count INTEGER,
|
||
priority_level INTEGER,
|
||
tags TEXT[],
|
||
seo_slug VARCHAR(255),
|
||
translation_quality FLOAT,
|
||
is_translated BOOLEAN,
|
||
created_at TIMESTAMP WITH TIME ZONE,
|
||
updated_at TIMESTAMP WITH TIME ZONE,
|
||
contents JSON
|
||
) AS $$
|
||
BEGIN
|
||
RETURN QUERY
|
||
SELECT
|
||
t.id,
|
||
COALESCE(tt.title, t.title) as title,
|
||
COALESCE(tt.description, t.description) as description,
|
||
COALESCE(tt.meta_description, t.meta_description) as meta_description,
|
||
COALESCE(tt.meta_keywords, t.meta_keywords) as meta_keywords,
|
||
t.topic_type,
|
||
t.status,
|
||
t.cover_image_url,
|
||
t.creator_id,
|
||
t.editor_id,
|
||
t.content_count,
|
||
t.view_count,
|
||
t.like_count,
|
||
t.share_count,
|
||
t.comment_count,
|
||
t.subscriber_count,
|
||
t.priority_level,
|
||
t.tags,
|
||
t.seo_slug,
|
||
tt.quality_score as translation_quality,
|
||
(tt.id IS NOT NULL) as is_translated,
|
||
t.created_at,
|
||
t.updated_at,
|
||
-- 聚合该专题下的内容
|
||
COALESCE(
|
||
(SELECT json_agg(
|
||
json_build_object(
|
||
'content_id', tc.content_id,
|
||
'display_order', tc.display_order,
|
||
'editor_note', COALESCE(tct.editor_note, tc.editor_note),
|
||
'is_featured', tc.is_featured,
|
||
'added_at', tc.added_at
|
||
)
|
||
ORDER BY tc.display_order, tc.added_at
|
||
)
|
||
FROM public.ak_topic_contents tc
|
||
LEFT JOIN public.ak_topic_content_translations tct
|
||
ON tc.id = tct.topic_content_id AND tct.language_code = p_language_code
|
||
WHERE tc.topic_id = t.id),
|
||
'[]'::json
|
||
) as contents
|
||
FROM public.ak_topics t
|
||
LEFT JOIN public.ak_topic_translations tt ON t.id = tt.topic_id
|
||
AND tt.language_code = p_language_code
|
||
WHERE t.id = p_topic_id;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
COMMENT ON FUNCTION public.get_topic_detail IS '获取专题详情(多语言支持)';
|
||
|
||
-- ===================================================================
|
||
-- 初始化示例数据
|
||
-- ===================================================================
|
||
|
||
-- 创建示例专题(如果不存在)
|
||
INSERT INTO public.ak_topics (title, description, topic_type, status, priority_level, tags)
|
||
VALUES
|
||
('人工智能发展趋势', '探讨2024年人工智能技术的最新发展趋势和应用前景', 'analysis', 'active', 5, ARRAY['AI', '人工智能', '技术趋势']),
|
||
('科技创新专题', '汇聚最新的科技创新成果和突破性技术', 'series', 'featured', 8, ARRAY['科技', '创新', '技术']),
|
||
('数字化转型指南', '企业数字化转型的完整指导和最佳实践', 'guide', 'active', 6, ARRAY['数字化', '转型', '企业'])
|
||
ON CONFLICT DO NOTHING;
|
||
|
||
-- 为示例专题添加多语言翻译
|
||
INSERT INTO public.ak_topic_translations (topic_id, language_code, title, description, translation_method, quality_score)
|
||
SELECT
|
||
t.id,
|
||
'en',
|
||
CASE
|
||
WHEN t.title = '人工智能发展趋势' THEN 'AI Development Trends'
|
||
WHEN t.title = '科技创新专题' THEN 'Technology Innovation Topics'
|
||
WHEN t.title = '数字化转型指南' THEN 'Digital Transformation Guide'
|
||
ELSE t.title
|
||
END,
|
||
CASE
|
||
WHEN t.description LIKE '%人工智能%' THEN 'Exploring the latest AI technology trends and application prospects in 2024'
|
||
WHEN t.description LIKE '%科技创新%' THEN 'Gathering the latest technological innovations and breakthrough technologies'
|
||
WHEN t.description LIKE '%数字化转型%' THEN 'Complete guidance and best practices for enterprise digital transformation'
|
||
ELSE t.description
|
||
END,
|
||
'ai',
|
||
0.85
|
||
FROM public.ak_topics t
|
||
WHERE t.title IN ('人工智能发展趋势', '科技创新专题', '数字化转型指南')
|
||
ON CONFLICT (topic_id, language_code) DO NOTHING;
|
||
|
||
-- 添加日文翻译
|
||
INSERT INTO public.ak_topic_translations (topic_id, language_code, title, description, translation_method, quality_score)
|
||
SELECT
|
||
t.id,
|
||
'ja',
|
||
CASE
|
||
WHEN t.title = '人工智能发展趋势' THEN 'AI発展トレンド'
|
||
WHEN t.title = '科技创新专题' THEN 'テクノロジーイノベーション特集'
|
||
WHEN t.title = '数字化转型指南' THEN 'デジタル変革ガイド'
|
||
ELSE t.title
|
||
END,
|
||
CASE
|
||
WHEN t.description LIKE '%人工智能%' THEN '2024年のAI技術の最新発展トレンドと応用展望を探る'
|
||
WHEN t.description LIKE '%科技创新%' THEN '最新の技術革新成果と画期的技術を集約'
|
||
WHEN t.description LIKE '%数字化转型%' THEN '企業のデジタル変革の完全ガイドとベストプラクティス'
|
||
ELSE t.description
|
||
END,
|
||
'ai',
|
||
0.80
|
||
FROM public.ak_topics t
|
||
WHERE t.title IN ('人工智能发展趋势', '科技创新专题', '数字化转型指南')
|
||
ON CONFLICT (topic_id, language_code) DO NOTHING;
|
||
|
||
-- ===================================================================
|
||
-- 更新现有ak_languages表以支持专题翻译
|
||
-- ===================================================================
|
||
|
||
-- 为专题翻译启用RLS策略
|
||
ALTER TABLE public.ak_topic_translations ENABLE ROW LEVEL SECURITY;
|
||
ALTER TABLE public.ak_topic_content_translations ENABLE ROW LEVEL SECURITY;
|
||
|
||
-- 专题翻译访问策略(所有人可读)
|
||
DROP POLICY IF EXISTS "topic_translations_select_policy" ON public.ak_topic_translations;
|
||
CREATE POLICY "topic_translations_select_policy" ON public.ak_topic_translations
|
||
FOR SELECT USING (true);
|
||
|
||
-- 专题翻译插入策略(认证用户可插入)
|
||
DROP POLICY IF EXISTS "topic_translations_insert_policy" ON public.ak_topic_translations;
|
||
CREATE POLICY "topic_translations_insert_policy" ON public.ak_topic_translations
|
||
FOR INSERT WITH CHECK (auth.uid() IS NOT NULL);
|
||
|
||
-- 专题内容翻译访问策略
|
||
DROP POLICY IF EXISTS "topic_content_translations_select_policy" ON public.ak_topic_content_translations;
|
||
CREATE POLICY "topic_content_translations_select_policy" ON public.ak_topic_content_translations
|
||
FOR SELECT USING (true);
|
||
|
||
DROP POLICY IF EXISTS "topic_content_translations_insert_policy" ON public.ak_topic_content_translations;
|
||
CREATE POLICY "topic_content_translations_insert_policy" ON public.ak_topic_content_translations
|
||
FOR INSERT WITH CHECK (auth.uid() IS NOT NULL);
|
||
|
||
-- ===================================================================
|
||
-- 完成信息
|
||
-- ===================================================================
|
||
|
||
DO $$
|
||
BEGIN
|
||
RAISE NOTICE '===================================================================';
|
||
RAISE NOTICE 'ak_topics 多语言支持扩展完成!';
|
||
RAISE NOTICE '===================================================================';
|
||
RAISE NOTICE '新增表:';
|
||
RAISE NOTICE '- ak_topic_translations: 专题多语言翻译表';
|
||
RAISE NOTICE '- ak_topic_content_translations: 专题内容关联多语言翻译表';
|
||
RAISE NOTICE '===================================================================';
|
||
RAISE NOTICE '新增函数:';
|
||
RAISE NOTICE '- get_topics_by_language(): 获取指定语言的专题列表';
|
||
RAISE NOTICE '- get_topic_detail(): 获取专题详情(多语言支持)';
|
||
RAISE NOTICE '===================================================================';
|
||
RAISE NOTICE '新增视图:';
|
||
RAISE NOTICE '- vw_multilingual_topics: 多语言专题聚合视图';
|
||
RAISE NOTICE '===================================================================';
|
||
RAISE NOTICE '特性支持:';
|
||
RAISE NOTICE '- 专题标题和描述多语言翻译';
|
||
RAISE NOTICE '- 专题内容编辑说明多语言支持';
|
||
RAISE NOTICE '- AI和人工翻译质量评分';
|
||
RAISE NOTICE '- SEO元数据多语言支持';
|
||
RAISE NOTICE '- 翻译质量追踪和审核机制';
|
||
RAISE NOTICE '- 与现有ak_content_translations架构一致';
|
||
RAISE NOTICE '===================================================================';
|
||
END
|
||
$$;
|
||
|
||
ALTER TABLE public.ak_contents
|
||
ADD COLUMN cid BIGSERIAL UNIQUE;
|
||
|
||
-- 或更推荐(PostgreSQL 10+,标准写法):
|
||
-- ALTER TABLE public.ak_contents
|
||
-- ADD COLUMN cid BIGINT GENERATED ALWAYS AS IDENTITY |