feat(govdoc): 新增内部公文模块全链路(后端58+前端11文件)
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
-- ============================================================================
|
||||
-- govdoc 模块建表 DDL
|
||||
-- 用途:
|
||||
-- 1. 创建 govdoc 模块专用结果域表(run / rule_result / report_artifact)
|
||||
-- 2. 给 leaudit_documents 补充 engine_type 字段
|
||||
-- 3. 幂等执行,重复跑不报错
|
||||
--
|
||||
-- 设计原则:
|
||||
-- - 复用 leaudit_documents / leaudit_document_files 作为文档主档
|
||||
-- - 新建 govdoc 结果域表,不与 leaudit 引擎结果表混用
|
||||
-- - 后续规则平台化时再补 govdoc_rule_sets / govdoc_rule_versions
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. govdoc_runs —— 公文审查运行主表
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS public.govdoc_runs (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
document_id BIGINT NOT NULL ,
|
||||
document_file_id BIGINT,
|
||||
run_no INTEGER NOT NULL DEFAULT 1,
|
||||
trigger_source VARCHAR(64) NOT NULL DEFAULT 'upload',
|
||||
trigger_user_id BIGINT,
|
||||
task_id VARCHAR(128),
|
||||
|
||||
-- 运行状态
|
||||
status VARCHAR(64) NOT NULL DEFAULT 'pending',
|
||||
phase VARCHAR(32),
|
||||
|
||||
-- 引擎快照
|
||||
engine_version VARCHAR(64),
|
||||
llm_provider VARCHAR(64),
|
||||
llm_model VARCHAR(128),
|
||||
|
||||
-- 结果汇总
|
||||
total_score NUMERIC(10, 2),
|
||||
passed_count INTEGER,
|
||||
failed_count INTEGER,
|
||||
skipped_count INTEGER,
|
||||
result_status VARCHAR(32),
|
||||
result_summary_json TEXT,
|
||||
error_message TEXT,
|
||||
|
||||
-- 时间
|
||||
started_at TIMESTAMPTZ,
|
||||
finished_at TIMESTAMPTZ,
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE public.govdoc_runs IS '公文审查运行主表';
|
||||
COMMENT ON COLUMN public.govdoc_runs.id IS '自增主键';
|
||||
COMMENT ON COLUMN public.govdoc_runs.document_id IS '关联 leaudit_documents.id';
|
||||
COMMENT ON COLUMN public.govdoc_runs.document_file_id IS '输入文件 ID,关联 leaudit_document_files.id';
|
||||
COMMENT ON COLUMN public.govdoc_runs.run_no IS '同一文档第几次执行';
|
||||
COMMENT ON COLUMN public.govdoc_runs.trigger_source IS '触发来源:upload/manual/retry/migration';
|
||||
COMMENT ON COLUMN public.govdoc_runs.trigger_user_id IS '触发人 user_id';
|
||||
COMMENT ON COLUMN public.govdoc_runs.task_id IS 'Celery 任务 ID';
|
||||
COMMENT ON COLUMN public.govdoc_runs.status IS 'pending/processing/completed/failed/cancelled';
|
||||
COMMENT ON COLUMN public.govdoc_runs.phase IS '当前阶段:parsing/executing/reporting';
|
||||
COMMENT ON COLUMN public.govdoc_runs.engine_version IS '引擎版本号';
|
||||
COMMENT ON COLUMN public.govdoc_runs.llm_provider IS 'LLM 提供商';
|
||||
COMMENT ON COLUMN public.govdoc_runs.llm_model IS 'LLM 模型名';
|
||||
COMMENT ON COLUMN public.govdoc_runs.total_score IS '总分';
|
||||
COMMENT ON COLUMN public.govdoc_runs.passed_count IS '通过规则数';
|
||||
COMMENT ON COLUMN public.govdoc_runs.failed_count IS '未通过规则数';
|
||||
COMMENT ON COLUMN public.govdoc_runs.skipped_count IS '跳过规则数';
|
||||
COMMENT ON COLUMN public.govdoc_runs.result_status IS '综合结果:pass/fail/partial/error';
|
||||
COMMENT ON COLUMN public.govdoc_runs.result_summary_json IS '结构化结果摘要 JSON';
|
||||
COMMENT ON COLUMN public.govdoc_runs.error_message IS '运行失败时错误描述';
|
||||
COMMENT ON COLUMN public.govdoc_runs.started_at IS '开始执行时间';
|
||||
COMMENT ON COLUMN public.govdoc_runs.finished_at IS '结束执行时间';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_runs_document_id ON public.govdoc_runs(document_id) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_runs_status ON public.govdoc_runs(status) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_runs_trigger_user_id ON public.govdoc_runs(trigger_user_id);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 2. govdoc_rule_results —— 单条规则执行结果
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS public.govdoc_rule_results (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
run_id BIGINT NOT NULL,
|
||||
|
||||
-- 规则标识
|
||||
rule_id VARCHAR(128) NOT NULL,
|
||||
rule_name VARCHAR(256),
|
||||
severity VARCHAR(32),
|
||||
category VARCHAR(128),
|
||||
|
||||
-- 结果内容
|
||||
message TEXT,
|
||||
suggestion TEXT,
|
||||
actual TEXT,
|
||||
expected TEXT,
|
||||
evidence TEXT,
|
||||
|
||||
-- 文档定位
|
||||
paragraph_index INTEGER,
|
||||
paragraph_text TEXT,
|
||||
location_path VARCHAR(512),
|
||||
|
||||
-- 判定
|
||||
result VARCHAR(32) NOT NULL DEFAULT 'pass',
|
||||
score NUMERIC(10, 2),
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE public.govdoc_rule_results IS '公文规则执行结果明细表';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.id IS '自增主键';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.run_id IS '关联 govdoc_runs.id';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.rule_id IS '规则标识';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.rule_name IS '规则名称';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.severity IS '严重等级:error/warning/info';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.category IS '规则分类';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.message IS '结果描述';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.suggestion IS '修改建议';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.actual IS '实际值';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.expected IS '期望值';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.evidence IS '证据文本';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.paragraph_index IS '段落索引';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.paragraph_text IS '段落原文';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.location_path IS '文档结构位置路径';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.result IS '执行结果:pass/fail/skipped/error';
|
||||
COMMENT ON COLUMN public.govdoc_rule_results.score IS '本条得分';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_rule_results_run_id ON public.govdoc_rule_results(run_id) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_rule_results_rule_id ON public.govdoc_rule_results(rule_id) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_rule_results_result ON public.govdoc_rule_results(result) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_rule_results_paragraph ON public.govdoc_rule_results(run_id, paragraph_index) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 3. govdoc_report_artifacts —— 报告产物索引
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS public.govdoc_report_artifacts (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
run_id BIGINT NOT NULL,
|
||||
|
||||
artifact_type VARCHAR(64) NOT NULL,
|
||||
file_name VARCHAR(512) NOT NULL,
|
||||
file_ext VARCHAR(32),
|
||||
mime_type VARCHAR(128),
|
||||
file_size BIGINT,
|
||||
sha256 VARCHAR(64),
|
||||
oss_url VARCHAR(2048),
|
||||
storage_provider VARCHAR(32),
|
||||
description VARCHAR(512),
|
||||
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE public.govdoc_report_artifacts IS '公文审查报告产物索引表';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.id IS '自增主键';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.run_id IS '关联 govdoc_runs.id';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.artifact_type IS '产物类型:html_report/annotated_docx/paragraph_html/json_report/original';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.file_name IS '文件名';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.file_ext IS '扩展名';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.mime_type IS 'MIME 类型';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.file_size IS '文件大小(字节)';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.sha256 IS '文件 SHA256';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.oss_url IS 'OSS 访问地址';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.storage_provider IS '存储提供商:oss/minio/local';
|
||||
COMMENT ON COLUMN public.govdoc_report_artifacts.description IS '产物说明';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_report_artifacts_run_id ON public.govdoc_report_artifacts(run_id) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_govdoc_report_artifacts_type ON public.govdoc_report_artifacts(run_id, artifact_type) WHERE deleted_at IS NULL;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 4. leaudit_documents —— 补充 engine_type 字段
|
||||
-- ---------------------------------------------------------------------------
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_documents'
|
||||
AND column_name = 'engine_type'
|
||||
) THEN
|
||||
ALTER TABLE public.leaudit_documents
|
||||
ADD COLUMN engine_type VARCHAR(32) NOT NULL DEFAULT 'leaudit';
|
||||
COMMENT ON COLUMN public.leaudit_documents.engine_type IS '引擎类型:leaudit/govdoc/rag';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 为 engine_type 加索引,方便按模块过滤文档列表
|
||||
CREATE INDEX IF NOT EXISTS idx_leaudit_documents_engine_type ON public.leaudit_documents(engine_type) WHERE deleted_at IS NULL;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,140 @@
|
||||
-- ============================================================================
|
||||
-- govdoc 模块入口初始化脚本
|
||||
-- 用途:
|
||||
-- 1. 为“内部公文 / govdoc”模块补齐首页入口配置
|
||||
-- 2. 使用幂等写法,重复执行不会产生重复数据
|
||||
-- 3. 兼容历史库中 entry_modules 时间字段命名差异
|
||||
--
|
||||
-- 说明:
|
||||
-- - 当前模块入口统一收口到 /govdoc/list,与模块路由 seed 保持一致。
|
||||
-- - 若后续前端改成其他入口页,请同步更新本脚本中的 v_target_path。
|
||||
-- - 页面访问权限与左侧菜单路由仍依赖 sys_routes / role_route,
|
||||
-- 这部分建议由配套脚本 seed_govdoc_routes.sql 单独维护。
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_name text := '内部公文';
|
||||
v_description text := '内部公文处理与格式审查入口';
|
||||
v_target_path text := '/govdoc/list';
|
||||
v_icon_path text := 'documents/mz/static/img/entry_module_3.png';
|
||||
v_sort_order integer := 30;
|
||||
v_areas jsonb := '[
|
||||
{"area":"梅州","enabled":true,"sort_order":1},
|
||||
{"area":"云浮","enabled":true,"sort_order":2},
|
||||
{"area":"揭阳","enabled":true,"sort_order":3},
|
||||
{"area":"潮州","enabled":true,"sort_order":4},
|
||||
{"area":"省局","enabled":true,"sort_order":5}
|
||||
]'::jsonb;
|
||||
has_created_at boolean;
|
||||
has_updated_at boolean;
|
||||
has_create_time boolean;
|
||||
has_update_time boolean;
|
||||
has_deleted_at boolean;
|
||||
sql_stmt text;
|
||||
BEGIN
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
AND column_name = 'created_at'
|
||||
),
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
AND column_name = 'updated_at'
|
||||
),
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
AND column_name = 'create_time'
|
||||
),
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
AND column_name = 'update_time'
|
||||
),
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
AND column_name = 'deleted_at'
|
||||
)
|
||||
INTO has_created_at, has_updated_at, has_create_time, has_update_time, has_deleted_at;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'leaudit_entry_modules'
|
||||
) THEN
|
||||
RAISE EXCEPTION '表 public.leaudit_entry_modules 不存在,请先执行入口模块建表脚本';
|
||||
END IF;
|
||||
|
||||
sql_stmt := 'INSERT INTO public.leaudit_entry_modules (' ||
|
||||
'name, description, path, icon_path, areas, sort_order, is_enabled';
|
||||
|
||||
IF has_created_at THEN
|
||||
sql_stmt := sql_stmt || ', created_at';
|
||||
ELSIF has_create_time THEN
|
||||
sql_stmt := sql_stmt || ', create_time';
|
||||
END IF;
|
||||
|
||||
IF has_updated_at THEN
|
||||
sql_stmt := sql_stmt || ', updated_at';
|
||||
ELSIF has_update_time THEN
|
||||
sql_stmt := sql_stmt || ', update_time';
|
||||
END IF;
|
||||
|
||||
IF has_deleted_at THEN
|
||||
sql_stmt := sql_stmt || ', deleted_at';
|
||||
END IF;
|
||||
|
||||
sql_stmt := sql_stmt || ') VALUES (' ||
|
||||
'$1, $2, $3, $4, $5, $6, TRUE';
|
||||
|
||||
IF has_created_at OR has_create_time THEN
|
||||
sql_stmt := sql_stmt || ', NOW()';
|
||||
END IF;
|
||||
|
||||
IF has_updated_at OR has_update_time THEN
|
||||
sql_stmt := sql_stmt || ', NOW()';
|
||||
END IF;
|
||||
|
||||
IF has_deleted_at THEN
|
||||
sql_stmt := sql_stmt || ', NULL';
|
||||
END IF;
|
||||
|
||||
sql_stmt := sql_stmt || ') ON CONFLICT (name) DO UPDATE SET ' ||
|
||||
'description = EXCLUDED.description, ' ||
|
||||
'path = EXCLUDED.path, ' ||
|
||||
'icon_path = EXCLUDED.icon_path, ' ||
|
||||
'areas = EXCLUDED.areas, ' ||
|
||||
'sort_order = EXCLUDED.sort_order, ' ||
|
||||
'is_enabled = EXCLUDED.is_enabled';
|
||||
|
||||
IF has_updated_at THEN
|
||||
sql_stmt := sql_stmt || ', updated_at = NOW()';
|
||||
ELSIF has_update_time THEN
|
||||
sql_stmt := sql_stmt || ', update_time = NOW()';
|
||||
END IF;
|
||||
|
||||
IF has_deleted_at THEN
|
||||
sql_stmt := sql_stmt || ', deleted_at = NULL';
|
||||
END IF;
|
||||
|
||||
EXECUTE sql_stmt
|
||||
USING v_name, v_description, v_target_path, v_icon_path, v_areas, v_sort_order;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,138 @@
|
||||
-- ============================================================================
|
||||
-- govdoc 模块权限种子
|
||||
-- 用途:
|
||||
-- 1. 为 govdoc 模块插入权限点到 permissions 表
|
||||
-- 2. 为默认角色分发角色-权限映射到 role_permissions 表
|
||||
-- 3. 幂等执行,重复跑会更新 description / display_name 等可刷新字段
|
||||
--
|
||||
-- 权限键格式:govdoc:{resource}:{action}
|
||||
-- 角色分发遵循《内部公文模块接口与权限设计》§5
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 1. 权限点定义
|
||||
-- ---------------------------------------------------------------------------
|
||||
INSERT INTO permissions (
|
||||
permission_key, module, resource, action, description, display_name,
|
||||
permission_type, is_system, metadata, created_at, updated_at,
|
||||
sort_order, route_id, api_path, api_method
|
||||
)
|
||||
VALUES
|
||||
-- 模块权限
|
||||
('govdoc:module:read', 'govdoc', 'module', 'read', '查看内部公文处理模块菜单', '查看公文模块', 'MENU', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 10, NULL, '/govdoc', 'GET'),
|
||||
|
||||
-- 文档权限
|
||||
('govdoc:document:create', 'govdoc', 'document', 'create', '上传公文文档', '上传公文', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 20, NULL, '/api/govdoc/documents', 'POST'),
|
||||
('govdoc:document:read', 'govdoc', 'document', 'read', '查看公文文档列表与详情', '查看公文', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 21, NULL, '/api/govdoc/documents', 'GET'),
|
||||
('govdoc:document:update', 'govdoc', 'document', 'update', '更新公文文档基础信息', '编辑公文', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 22, NULL, '/api/govdoc/documents/{DocumentId}', 'PATCH'),
|
||||
('govdoc:document:delete', 'govdoc', 'document', 'delete', '删除公文文档', '删除公文', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 23, NULL, '/api/govdoc/documents/{DocumentId}', 'DELETE'),
|
||||
|
||||
-- 审查运行权限
|
||||
('govdoc:run:create', 'govdoc', 'run', 'create', '发起公文格式审查', '发起审查', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 30, NULL, '/api/govdoc/runs', 'POST'),
|
||||
('govdoc:run:read', 'govdoc', 'run', 'read', '查看审查运行状态', '查看审查状态', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 31, NULL, '/api/govdoc/runs/{RunId}', 'GET'),
|
||||
('govdoc:run:retry', 'govdoc', 'run', 'retry', '失败后重试审查', '重试审查', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 32, NULL, '/api/govdoc/runs/{RunId}/retry', 'POST'),
|
||||
|
||||
-- 报告与结果权限
|
||||
('govdoc:report:read', 'govdoc', 'report', 'read', '下载审查报告(HTML/DOCX/原文)', '下载报告', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 40, NULL, '/api/govdoc/runs/{RunId}/report', 'GET'),
|
||||
('govdoc:result:read', 'govdoc', 'result', 'read', '查看审查结果(findings/entities/summary)', '查看审查结果', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 41, NULL, '/api/govdoc/runs/{RunId}/result', 'GET'),
|
||||
|
||||
-- 规则权限
|
||||
('govdoc:rule:read', 'govdoc', 'rule', 'read', '查看公文规则清单与详情', '查看规则', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 50, NULL, '/api/govdoc/rules', 'GET'),
|
||||
('govdoc:rule:manage', 'govdoc', 'rule', 'manage', '发布、更新、切换规则版本', '管理规则', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 51, NULL, '/api/govdoc/rule-versions', 'POST'),
|
||||
|
||||
-- 配置权限(可选)
|
||||
('govdoc:settings:read', 'govdoc', 'settings', 'read', '查看公文模块配置', '查看设置', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 60, NULL, '/api/govdoc/settings', 'GET'),
|
||||
('govdoc:settings:update', 'govdoc', 'settings', 'update', '修改公文模块配置', '修改设置', 'API', TRUE, '{"group":"govdoc"}'::jsonb, NOW(), NOW(), 61, NULL, '/api/govdoc/settings', 'PATCH')
|
||||
ON CONFLICT (permission_key) DO UPDATE SET
|
||||
module = EXCLUDED.module,
|
||||
resource = EXCLUDED.resource,
|
||||
action = EXCLUDED.action,
|
||||
description = EXCLUDED.description,
|
||||
display_name = EXCLUDED.display_name,
|
||||
api_path = EXCLUDED.api_path,
|
||||
api_method = EXCLUDED.api_method,
|
||||
updated_at = NOW();
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 2. 角色权限分发
|
||||
-- ---------------------------------------------------------------------------
|
||||
WITH role_map AS (
|
||||
SELECT id, role_key
|
||||
FROM roles
|
||||
WHERE role_key IN ('super_admin', 'provincial_admin', 'admin', 'common')
|
||||
),
|
||||
perm_map AS (
|
||||
SELECT id, permission_key
|
||||
FROM permissions
|
||||
WHERE permission_key LIKE 'govdoc:%'
|
||||
),
|
||||
seed(role_key, permission_key, grant_type, data_scope) AS (
|
||||
VALUES
|
||||
-- super_admin: 全部权限
|
||||
('super_admin', 'govdoc:module:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:document:create', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:document:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:document:update', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:document:delete', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:run:create', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:run:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:run:retry', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:report:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:result:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:rule:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:rule:manage', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:settings:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'govdoc:settings:update', 'GRANT', 'ALL'),
|
||||
|
||||
-- provincial_admin: 全部业务权限
|
||||
('provincial_admin', 'govdoc:module:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:document:create', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:document:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:document:update', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:document:delete', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:run:create', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:run:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:run:retry', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:report:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:result:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:rule:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:rule:manage', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:settings:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'govdoc:settings:update', 'GRANT', 'ALL'),
|
||||
|
||||
-- admin: 模块读写 + 规则查看,不含规则管理与配置修改
|
||||
('admin', 'govdoc:module:read', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:document:create', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:document:read', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:document:update', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:document:delete', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:run:create', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:run:read', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:run:retry', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:report:read', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:result:read', 'GRANT', 'REGION'),
|
||||
('admin', 'govdoc:rule:read', 'GRANT', 'REGION'),
|
||||
|
||||
-- common: 模块查看 + 文档上传/查看 + 审查发起/查看 + 报告/结果查看 + 规则查看
|
||||
('common', 'govdoc:module:read', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:document:create', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:document:read', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:run:create', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:run:read', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:report:read', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:result:read', 'GRANT', 'OWN'),
|
||||
('common', 'govdoc:rule:read', 'GRANT', 'OWN')
|
||||
)
|
||||
INSERT INTO role_permissions (role_id, permission_id, grant_type, data_scope, created_at, updated_at)
|
||||
SELECT rm.id, pm.id, seed.grant_type, seed.data_scope, NOW(), NOW()
|
||||
FROM seed
|
||||
JOIN role_map rm ON rm.role_key = seed.role_key
|
||||
JOIN perm_map pm ON pm.permission_key = seed.permission_key
|
||||
ON CONFLICT (role_id, permission_id) DO UPDATE SET
|
||||
grant_type = EXCLUDED.grant_type,
|
||||
data_scope = EXCLUDED.data_scope,
|
||||
updated_at = NOW();
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,276 @@
|
||||
BEGIN;
|
||||
|
||||
-- ============================================================================
|
||||
-- govdoc 模块前端路由 / 菜单初始化草案
|
||||
-- 目标:
|
||||
-- 1. 注册 /govdoc 模块根路由与常用子路由
|
||||
-- 2. 尽量兼容当前 sys_routes 的父子层级展示方式
|
||||
-- 3. 为默认角色补齐 role_route 菜单可见性
|
||||
-- 说明:
|
||||
-- - 采用 route_path / route_name / route_title 这一套当前仓库主流字段风格
|
||||
-- - 明细页 / 详情页默认 hidden,避免菜单树出现无意义叶子节点
|
||||
-- - 幂等执行:重复跑会更新标题、父子关系、显示状态
|
||||
-- ============================================================================
|
||||
|
||||
WITH upsert_root AS (
|
||||
INSERT INTO sys_routes (
|
||||
route_path,
|
||||
route_name,
|
||||
component,
|
||||
parent_id,
|
||||
route_title,
|
||||
icon,
|
||||
sort_order,
|
||||
is_hidden,
|
||||
is_cache,
|
||||
meta,
|
||||
status,
|
||||
created_at,
|
||||
updated_at,
|
||||
deleted_at
|
||||
)
|
||||
VALUES (
|
||||
'/govdoc',
|
||||
'govdoc',
|
||||
'govdoc',
|
||||
NULL,
|
||||
'内部公文处理',
|
||||
'ri-file-paper-2-line',
|
||||
80,
|
||||
FALSE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
)
|
||||
ON CONFLICT (route_path) WHERE deleted_at IS NULL
|
||||
DO UPDATE SET
|
||||
route_name = EXCLUDED.route_name,
|
||||
component = EXCLUDED.component,
|
||||
route_title = EXCLUDED.route_title,
|
||||
icon = EXCLUDED.icon,
|
||||
sort_order = EXCLUDED.sort_order,
|
||||
is_hidden = EXCLUDED.is_hidden,
|
||||
is_cache = EXCLUDED.is_cache,
|
||||
meta = EXCLUDED.meta,
|
||||
status = 0,
|
||||
updated_at = NOW(),
|
||||
deleted_at = NULL
|
||||
RETURNING id
|
||||
),
|
||||
root_route AS (
|
||||
SELECT id FROM upsert_root
|
||||
UNION ALL
|
||||
SELECT id
|
||||
FROM sys_routes
|
||||
WHERE route_path = '/govdoc'
|
||||
AND deleted_at IS NULL
|
||||
LIMIT 1
|
||||
)
|
||||
INSERT INTO sys_routes (
|
||||
route_path,
|
||||
route_name,
|
||||
component,
|
||||
parent_id,
|
||||
route_title,
|
||||
icon,
|
||||
sort_order,
|
||||
is_hidden,
|
||||
is_cache,
|
||||
meta,
|
||||
status,
|
||||
created_at,
|
||||
updated_at,
|
||||
deleted_at
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'/govdoc/upload',
|
||||
'govdoc.upload',
|
||||
'govdoc.upload',
|
||||
(SELECT id FROM root_route),
|
||||
'上传公文',
|
||||
'ri-upload-cloud-2-line',
|
||||
1,
|
||||
FALSE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc","page":"upload"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
),
|
||||
(
|
||||
'/govdoc/list',
|
||||
'govdoc.list',
|
||||
'govdoc.list',
|
||||
(SELECT id FROM root_route),
|
||||
'公文列表',
|
||||
'ri-file-list-3-line',
|
||||
2,
|
||||
FALSE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc","page":"list"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
),
|
||||
(
|
||||
'/govdoc/detail',
|
||||
'govdoc.detail',
|
||||
'govdoc.detail',
|
||||
(SELECT id FROM root_route),
|
||||
'公文详情',
|
||||
'ri-file-search-line',
|
||||
3,
|
||||
TRUE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc","page":"detail"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
),
|
||||
(
|
||||
'/govdoc/rules',
|
||||
'govdoc.rules',
|
||||
'govdoc.rules',
|
||||
(SELECT id FROM root_route),
|
||||
'规则配置',
|
||||
'ri-scales-3-line',
|
||||
4,
|
||||
FALSE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc","page":"rules"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
),
|
||||
(
|
||||
'/govdoc/settings',
|
||||
'govdoc.settings',
|
||||
'govdoc.settings',
|
||||
(SELECT id FROM root_route),
|
||||
'模块配置',
|
||||
'ri-settings-3-line',
|
||||
5,
|
||||
FALSE,
|
||||
TRUE,
|
||||
'{"group":"govdoc","module":"govdoc","page":"settings"}'::jsonb,
|
||||
0,
|
||||
NOW(),
|
||||
NOW(),
|
||||
NULL
|
||||
)
|
||||
ON CONFLICT (route_path) WHERE deleted_at IS NULL
|
||||
DO UPDATE SET
|
||||
route_name = EXCLUDED.route_name,
|
||||
component = EXCLUDED.component,
|
||||
parent_id = EXCLUDED.parent_id,
|
||||
route_title = EXCLUDED.route_title,
|
||||
icon = EXCLUDED.icon,
|
||||
sort_order = EXCLUDED.sort_order,
|
||||
is_hidden = EXCLUDED.is_hidden,
|
||||
is_cache = EXCLUDED.is_cache,
|
||||
meta = EXCLUDED.meta,
|
||||
status = 0,
|
||||
updated_at = NOW(),
|
||||
deleted_at = NULL;
|
||||
|
||||
-- 修正旧环境中可能已存在但未正确挂到 /govdoc 下的子路由。
|
||||
UPDATE sys_routes AS child
|
||||
SET
|
||||
parent_id = root.id,
|
||||
route_title = CASE
|
||||
WHEN child.route_path = '/govdoc/upload' THEN '上传公文'
|
||||
WHEN child.route_path = '/govdoc/list' THEN '公文列表'
|
||||
WHEN child.route_path = '/govdoc/detail' THEN '公文详情'
|
||||
WHEN child.route_path = '/govdoc/rules' THEN '规则配置'
|
||||
WHEN child.route_path = '/govdoc/settings' THEN '模块配置'
|
||||
ELSE child.route_title
|
||||
END,
|
||||
is_hidden = CASE
|
||||
WHEN child.route_path = '/govdoc/detail' THEN TRUE
|
||||
ELSE child.is_hidden
|
||||
END,
|
||||
updated_at = NOW()
|
||||
FROM sys_routes root
|
||||
WHERE child.deleted_at IS NULL
|
||||
AND root.deleted_at IS NULL
|
||||
AND root.route_path = '/govdoc'
|
||||
AND child.route_path IN (
|
||||
'/govdoc/upload',
|
||||
'/govdoc/list',
|
||||
'/govdoc/detail',
|
||||
'/govdoc/rules',
|
||||
'/govdoc/settings'
|
||||
);
|
||||
|
||||
-- 根路由标题兜底,避免历史环境残留旧文案。
|
||||
UPDATE sys_routes
|
||||
SET route_title = '内部公文处理',
|
||||
updated_at = NOW()
|
||||
WHERE deleted_at IS NULL
|
||||
AND route_path = '/govdoc';
|
||||
|
||||
WITH role_map AS (
|
||||
SELECT id, role_key
|
||||
FROM roles
|
||||
WHERE role_key IN ('super_admin', 'provincial_admin', 'admin', 'common')
|
||||
),
|
||||
route_map AS (
|
||||
SELECT id, route_path
|
||||
FROM sys_routes
|
||||
WHERE deleted_at IS NULL
|
||||
AND route_path IN (
|
||||
'/govdoc',
|
||||
'/govdoc/upload',
|
||||
'/govdoc/list',
|
||||
'/govdoc/detail',
|
||||
'/govdoc/rules',
|
||||
'/govdoc/settings'
|
||||
)
|
||||
),
|
||||
seed(role_key, route_path, permission, status) AS (
|
||||
VALUES
|
||||
('super_admin', '/govdoc', 'RW', 1),
|
||||
('super_admin', '/govdoc/upload', 'RW', 1),
|
||||
('super_admin', '/govdoc/list', 'RW', 1),
|
||||
('super_admin', '/govdoc/detail', 'RW', 1),
|
||||
('super_admin', '/govdoc/rules', 'RW', 1),
|
||||
('super_admin', '/govdoc/settings', 'RW', 1),
|
||||
|
||||
('provincial_admin', '/govdoc', 'RW', 1),
|
||||
('provincial_admin', '/govdoc/upload', 'RW', 1),
|
||||
('provincial_admin', '/govdoc/list', 'RW', 1),
|
||||
('provincial_admin', '/govdoc/detail', 'RW', 1),
|
||||
('provincial_admin', '/govdoc/rules', 'RW', 1),
|
||||
('provincial_admin', '/govdoc/settings', 'RW', 1),
|
||||
|
||||
('admin', '/govdoc', 'RW', 1),
|
||||
('admin', '/govdoc/upload', 'RW', 1),
|
||||
('admin', '/govdoc/list', 'RW', 1),
|
||||
('admin', '/govdoc/detail', 'RW', 1),
|
||||
('admin', '/govdoc/rules', 'R', 1),
|
||||
|
||||
('common', '/govdoc', 'R', 1),
|
||||
('common', '/govdoc/upload', 'R', 1),
|
||||
('common', '/govdoc/list', 'R', 1),
|
||||
('common', '/govdoc/detail', 'R', 1),
|
||||
('common', '/govdoc/rules', 'R', 1)
|
||||
)
|
||||
INSERT INTO role_route (role_id, route_id, permission, status, created_at, updated_at)
|
||||
SELECT rm.id, tm.id, s.permission, s.status, NOW(), NOW()
|
||||
FROM seed s
|
||||
JOIN role_map rm ON rm.role_key = s.role_key
|
||||
JOIN route_map tm ON tm.route_path = s.route_path
|
||||
ON CONFLICT (role_id, route_id) DO UPDATE SET
|
||||
permission = EXCLUDED.permission,
|
||||
status = EXCLUDED.status,
|
||||
updated_at = NOW();
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user