454 lines
16 KiB
PL/PgSQL
454 lines
16 KiB
PL/PgSQL
BEGIN;
|
|
|
|
-- ============================================================================
|
|
-- High Risk Tenant Code Phase 1
|
|
-- 目标:
|
|
-- 1. 为高风险核心业务表补 tenant_code / tenant 快照字段
|
|
-- 2. 补基础索引,支持后续 service 改为 tenant_code 主链
|
|
-- 3. 基于 sys_tenant_aliases / sys_tenants 做第一轮历史回填
|
|
-- 说明:
|
|
-- - 本脚本只做“补列 + 建索引 + 回填”
|
|
-- - 不在本阶段强制 NOT NULL
|
|
-- - 不在本阶段删除旧 region/area 字段
|
|
-- ============================================================================
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 1. leaudit_documents
|
|
-- --------------------------------------------------------------------------
|
|
ALTER TABLE public.leaudit_documents
|
|
ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64);
|
|
|
|
COMMENT ON COLUMN public.leaudit_documents.tenant_code IS '所属租户编码:高风险阶段新增,后续替代 region 作为真实归属主字段';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_leaudit_documents_tenant_code
|
|
ON public.leaudit_documents(tenant_code)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_leaudit_documents_type_tenant_name_latest
|
|
ON public.leaudit_documents(type_id, tenant_code, normalized_name, is_latest_version)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 2. contract_templates
|
|
-- --------------------------------------------------------------------------
|
|
ALTER TABLE public.contract_templates
|
|
ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
|
|
ADD COLUMN IF NOT EXISTS tenant_name VARCHAR(128);
|
|
|
|
COMMENT ON COLUMN public.contract_templates.tenant_code IS '所属租户编码:高风险阶段新增,后续替代 region 作为真实归属主字段';
|
|
COMMENT ON COLUMN public.contract_templates.tenant_name IS '所属租户名称:展示字段,和 tenant_code 配套回填';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_contract_templates_tenant_code_active
|
|
ON public.contract_templates(tenant_code)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_contract_templates_tenant_code_code_active
|
|
ON public.contract_templates(tenant_code, template_code)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 3. usage_login_events
|
|
-- --------------------------------------------------------------------------
|
|
ALTER TABLE public.usage_login_events
|
|
ADD COLUMN IF NOT EXISTS tenant_code_snapshot VARCHAR(64),
|
|
ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(128);
|
|
|
|
COMMENT ON COLUMN public.usage_login_events.tenant_code_snapshot IS '登录时租户编码快照';
|
|
COMMENT ON COLUMN public.usage_login_events.tenant_name_snapshot IS '登录时租户名称快照';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_usage_login_events_tenant_code
|
|
ON public.usage_login_events(tenant_code_snapshot, login_time DESC);
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 4. rag_dataset
|
|
-- --------------------------------------------------------------------------
|
|
ALTER TABLE public.rag_dataset
|
|
ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64);
|
|
|
|
COMMENT ON COLUMN public.rag_dataset.tenant_code IS '所属租户编码:高风险阶段新增,后续替代 area 作为真实归属主字段';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_rag_dataset_tenant_code
|
|
ON public.rag_dataset(tenant_code)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 5. rag_chat_app
|
|
-- --------------------------------------------------------------------------
|
|
ALTER TABLE public.rag_chat_app
|
|
ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64);
|
|
|
|
COMMENT ON COLUMN public.rag_chat_app.tenant_code IS '所属租户编码:高风险阶段新增,后续替代 area 作为真实归属主字段';
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_rag_chat_app_tenant_code
|
|
ON public.rag_chat_app(tenant_code)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 6. 公共 / 省级规范租户兜底
|
|
-- --------------------------------------------------------------------------
|
|
INSERT INTO public.sys_tenants (
|
|
tenant_code, tenant_name, tenant_short_name, tenant_type,
|
|
parent_tenant_code, is_enabled, is_public, display_order, ext,
|
|
created_at, updated_at, deleted_at
|
|
)
|
|
SELECT
|
|
'PUBLIC', '公共资源域', '公共', 'PUBLIC',
|
|
NULL, TRUE, TRUE, 0, '{}'::jsonb,
|
|
NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM public.sys_tenants WHERE tenant_code = 'PUBLIC'
|
|
);
|
|
|
|
INSERT INTO public.sys_tenants (
|
|
tenant_code, tenant_name, tenant_short_name, tenant_type,
|
|
parent_tenant_code, is_enabled, is_public, display_order, ext,
|
|
created_at, updated_at, deleted_at
|
|
)
|
|
SELECT
|
|
'PROVINCIAL', '省级统管域', '省级', 'GOV',
|
|
NULL, TRUE, FALSE, 1, '{}'::jsonb,
|
|
NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM public.sys_tenants WHERE tenant_code = 'PROVINCIAL'
|
|
);
|
|
|
|
INSERT INTO public.sys_tenant_aliases (
|
|
tenant_code, alias_type, alias_value, is_enabled, created_at, updated_at, deleted_at
|
|
)
|
|
SELECT 'PUBLIC', 'DISPLAY', '公共', TRUE, NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM public.sys_tenant_aliases
|
|
WHERE tenant_code = 'PUBLIC'
|
|
AND alias_value = '公共'
|
|
AND deleted_at IS NULL
|
|
);
|
|
|
|
INSERT INTO public.sys_tenant_aliases (
|
|
tenant_code, alias_type, alias_value, is_enabled, created_at, updated_at, deleted_at
|
|
)
|
|
SELECT 'PUBLIC', 'LEGACY_REGION', 'default', TRUE, NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM public.sys_tenant_aliases
|
|
WHERE tenant_code = 'PUBLIC'
|
|
AND alias_value = 'default'
|
|
AND deleted_at IS NULL
|
|
);
|
|
|
|
INSERT INTO public.sys_tenant_aliases (
|
|
tenant_code, alias_type, alias_value, is_enabled, created_at, updated_at, deleted_at
|
|
)
|
|
SELECT 'PROVINCIAL', 'DISPLAY', '省级', TRUE, NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM public.sys_tenant_aliases
|
|
WHERE tenant_code = 'PROVINCIAL'
|
|
AND alias_value = '省级'
|
|
AND deleted_at IS NULL
|
|
);
|
|
|
|
INSERT INTO public.sys_tenant_aliases (
|
|
tenant_code, alias_type, alias_value, is_enabled, created_at, updated_at, deleted_at
|
|
)
|
|
SELECT 'PROVINCIAL', 'LEGACY_REGION', '省局', TRUE, NOW(), NOW(), NULL
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM public.sys_tenant_aliases
|
|
WHERE tenant_code = 'PROVINCIAL'
|
|
AND alias_value = '省局'
|
|
AND deleted_at IS NULL
|
|
);
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 7. 第一轮历史回填:优先按别名表映射
|
|
-- --------------------------------------------------------------------------
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_documents AS (
|
|
SELECT
|
|
d.id,
|
|
COALESCE(
|
|
NULLIF(BTRIM(d.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN d.region IS NULL OR BTRIM(d.region) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(d.region)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(d.region) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(d.region) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code
|
|
FROM public.leaudit_documents d
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(d.region, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(d.region, ''))) = tn.normalized_tenant_name
|
|
WHERE d.deleted_at IS NULL
|
|
AND (d.tenant_code IS NULL OR BTRIM(d.tenant_code) = '')
|
|
)
|
|
UPDATE public.leaudit_documents d
|
|
SET tenant_code = rd.resolved_tenant_code
|
|
FROM resolved_documents rd
|
|
WHERE d.id = rd.id
|
|
AND rd.resolved_tenant_code IS NOT NULL;
|
|
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_templates AS (
|
|
SELECT
|
|
t.id,
|
|
COALESCE(
|
|
NULLIF(BTRIM(t.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN t.region IS NULL OR BTRIM(t.region) = '' THEN 'PROVINCIAL'
|
|
WHEN LOWER(BTRIM(t.region)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(t.region) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(t.region) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code,
|
|
COALESCE(
|
|
NULLIF(BTRIM(t.tenant_name), ''),
|
|
NULLIF(BTRIM(t.region), ''),
|
|
st.tenant_name,
|
|
CASE
|
|
WHEN t.region IS NULL OR BTRIM(t.region) = '' THEN '省级'
|
|
WHEN LOWER(BTRIM(t.region)) = 'default' THEN '公共'
|
|
WHEN BTRIM(t.region) = '公共' THEN '公共'
|
|
WHEN BTRIM(t.region) IN ('省级', '省局') THEN '省级'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_name
|
|
FROM public.contract_templates t
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(t.region, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(t.region, ''))) = tn.normalized_tenant_name
|
|
LEFT JOIN public.sys_tenants st
|
|
ON st.tenant_code = COALESCE(
|
|
NULLIF(BTRIM(t.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN t.region IS NULL OR BTRIM(t.region) = '' THEN 'PROVINCIAL'
|
|
WHEN LOWER(BTRIM(t.region)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(t.region) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(t.region) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
)
|
|
AND st.deleted_at IS NULL
|
|
AND st.is_enabled = TRUE
|
|
WHERE t.deleted_at IS NULL
|
|
AND (
|
|
t.tenant_code IS NULL
|
|
OR BTRIM(t.tenant_code) = ''
|
|
OR t.tenant_name IS NULL
|
|
OR BTRIM(t.tenant_name) = ''
|
|
)
|
|
)
|
|
UPDATE public.contract_templates t
|
|
SET tenant_code = COALESCE(t.tenant_code, rt.resolved_tenant_code),
|
|
tenant_name = COALESCE(NULLIF(BTRIM(t.tenant_name), ''), rt.resolved_tenant_name)
|
|
FROM resolved_templates rt
|
|
WHERE t.id = rt.id
|
|
AND (
|
|
rt.resolved_tenant_code IS NOT NULL
|
|
OR rt.resolved_tenant_name IS NOT NULL
|
|
);
|
|
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_rag_dataset AS (
|
|
SELECT
|
|
d.id,
|
|
COALESCE(
|
|
NULLIF(BTRIM(d.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN d.area IS NULL OR BTRIM(d.area) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(d.area)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(d.area) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(d.area) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code
|
|
FROM public.rag_dataset d
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(d.area, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(d.area, ''))) = tn.normalized_tenant_name
|
|
WHERE d.deleted_at IS NULL
|
|
AND (d.tenant_code IS NULL OR BTRIM(d.tenant_code) = '')
|
|
)
|
|
UPDATE public.rag_dataset d
|
|
SET tenant_code = rrd.resolved_tenant_code
|
|
FROM resolved_rag_dataset rrd
|
|
WHERE d.id = rrd.id
|
|
AND rrd.resolved_tenant_code IS NOT NULL;
|
|
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_rag_chat_app AS (
|
|
SELECT
|
|
a.id,
|
|
COALESCE(
|
|
NULLIF(BTRIM(a.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN a.area IS NULL OR BTRIM(a.area) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(a.area)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(a.area) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(a.area) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code
|
|
FROM public.rag_chat_app a
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(a.area, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(a.area, ''))) = tn.normalized_tenant_name
|
|
WHERE a.deleted_at IS NULL
|
|
AND (a.tenant_code IS NULL OR BTRIM(a.tenant_code) = '')
|
|
)
|
|
UPDATE public.rag_chat_app a
|
|
SET tenant_code = rca.resolved_tenant_code
|
|
FROM resolved_rag_chat_app rca
|
|
WHERE a.id = rca.id
|
|
AND rca.resolved_tenant_code IS NOT NULL;
|
|
|
|
WITH user_tenant_map AS (
|
|
SELECT
|
|
u.id AS user_id,
|
|
COALESCE(
|
|
NULLIF(BTRIM(u.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN u.area IS NULL OR BTRIM(u.area) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(u.area)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(u.area) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(u.area) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code,
|
|
COALESCE(
|
|
NULLIF(BTRIM(u.tenant_name), ''),
|
|
t.tenant_name,
|
|
NULLIF(BTRIM(u.area), ''),
|
|
CASE
|
|
WHEN u.area IS NULL OR BTRIM(u.area) = '' THEN '公共资源域'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_name
|
|
FROM public.sso_users u
|
|
LEFT JOIN public.sys_tenant_aliases sa
|
|
ON LOWER(BTRIM(COALESCE(u.area, ''))) = LOWER(BTRIM(sa.alias_value))
|
|
AND sa.deleted_at IS NULL
|
|
AND sa.is_enabled = TRUE
|
|
LEFT JOIN public.sys_tenants t
|
|
ON t.tenant_code = COALESCE(NULLIF(BTRIM(u.tenant_code), ''), sa.tenant_code)
|
|
AND t.deleted_at IS NULL
|
|
AND t.is_enabled = TRUE
|
|
LEFT JOIN (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
) am
|
|
ON LOWER(BTRIM(COALESCE(u.area, ''))) = am.normalized_alias_value
|
|
LEFT JOIN (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
) tn
|
|
ON LOWER(BTRIM(COALESCE(u.area, ''))) = tn.normalized_tenant_name
|
|
WHERE u.deleted_at IS NULL
|
|
)
|
|
UPDATE public.usage_login_events e
|
|
SET tenant_code_snapshot = COALESCE(e.tenant_code_snapshot, utm.resolved_tenant_code),
|
|
tenant_name_snapshot = COALESCE(e.tenant_name_snapshot, utm.resolved_tenant_name)
|
|
FROM user_tenant_map utm
|
|
WHERE e.deleted_at IS NULL
|
|
AND e.user_id = utm.user_id
|
|
AND (
|
|
e.tenant_code_snapshot IS NULL
|
|
OR BTRIM(e.tenant_code_snapshot) = ''
|
|
OR e.tenant_name_snapshot IS NULL
|
|
OR BTRIM(e.tenant_name_snapshot) = ''
|
|
);
|
|
|
|
COMMIT;
|