feat: 支持合同模板上传与地区隔离
This commit is contained in:
@@ -164,12 +164,14 @@ def resolve_pdf_path(template: LegacyTemplate, object_keys: set[str]) -> str:
|
||||
|
||||
def build_new_object_keys(template: LegacyTemplate, docx_path: str, pdf_path: str) -> tuple[str, str]:
|
||||
docx_key = OssPathUtils.BuildContractTemplateKey(
|
||||
Region="省级",
|
||||
CategoryName=template.category_name,
|
||||
TemplateCode=template.template_code,
|
||||
FileRole="source",
|
||||
FileName=Path(docx_path).name,
|
||||
)
|
||||
pdf_key = OssPathUtils.BuildContractTemplateKey(
|
||||
Region="省级",
|
||||
CategoryName=template.category_name,
|
||||
TemplateCode=template.template_code,
|
||||
FileRole="preview",
|
||||
|
||||
@@ -3,9 +3,9 @@ BEGIN;
|
||||
-- ============================================================================
|
||||
-- LeAudit Platform Contract Template Schema
|
||||
-- 目标:
|
||||
-- 1. 在主库 leaudit_platform 创建合同模板分类表
|
||||
-- 2. 在主库 leaudit_platform 创建合同模板表
|
||||
-- 3. 补齐索引与基础约束
|
||||
-- 1. 在主库 leaudit_platform 创建 / 升级合同模板分类表
|
||||
-- 2. 在主库 leaudit_platform 创建 / 升级合同模板主表
|
||||
-- 3. 补齐地区字段、审计字段、软删除字段、索引与 updated_at 触发器
|
||||
-- 说明:
|
||||
-- - 本脚本不依赖旧库 docauditai
|
||||
-- - 幂等脚本,可重复执行
|
||||
@@ -17,50 +17,168 @@ CREATE TABLE IF NOT EXISTS public.contract_categories (
|
||||
icon VARCHAR(100) NULL,
|
||||
description TEXT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_by BIGINT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
updated_by BIGINT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_contract_categories_name
|
||||
ON public.contract_categories(name);
|
||||
ALTER TABLE public.contract_categories
|
||||
ADD COLUMN IF NOT EXISTS icon VARCHAR(100),
|
||||
ADD COLUMN IF NOT EXISTS description TEXT,
|
||||
ADD COLUMN IF NOT EXISTS sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS created_by BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ADD COLUMN IF NOT EXISTS updated_by BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.contract_templates (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
template_code VARCHAR(50) NOT NULL,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
category_id INTEGER NOT NULL REFERENCES public.contract_categories(id) ON DELETE RESTRICT,
|
||||
region VARCHAR(50) NOT NULL DEFAULT '省级',
|
||||
description TEXT NULL,
|
||||
file_path VARCHAR(500) NULL,
|
||||
pdf_file_path VARCHAR(500) NULL,
|
||||
file_format VARCHAR(10) NOT NULL,
|
||||
original_file_name VARCHAR(500) NOT NULL DEFAULT '',
|
||||
mime_type VARCHAR(200) NULL,
|
||||
file_size BIGINT NOT NULL DEFAULT 0,
|
||||
pdf_file_size BIGINT NULL,
|
||||
is_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_by BIGINT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_by BIGINT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
pdf_file_path VARCHAR(500) NULL
|
||||
deleted_at TIMESTAMPTZ NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_contract_templates_code
|
||||
ON public.contract_templates(template_code);
|
||||
ALTER TABLE public.contract_templates
|
||||
ADD COLUMN IF NOT EXISTS region VARCHAR(50) NOT NULL DEFAULT '省级',
|
||||
ADD COLUMN IF NOT EXISTS description TEXT,
|
||||
ADD COLUMN IF NOT EXISTS file_path VARCHAR(500),
|
||||
ADD COLUMN IF NOT EXISTS pdf_file_path VARCHAR(500),
|
||||
ADD COLUMN IF NOT EXISTS file_format VARCHAR(10),
|
||||
ADD COLUMN IF NOT EXISTS original_file_name VARCHAR(500) NOT NULL DEFAULT '',
|
||||
ADD COLUMN IF NOT EXISTS mime_type VARCHAR(200),
|
||||
ADD COLUMN IF NOT EXISTS file_size BIGINT NOT NULL DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS pdf_file_size BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS is_featured BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS created_by BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ADD COLUMN IF NOT EXISTS updated_by BIGINT,
|
||||
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_templates_category_id
|
||||
ON public.contract_templates(category_id);
|
||||
UPDATE public.contract_templates
|
||||
SET region = '省级'
|
||||
WHERE region IS NULL OR BTRIM(region) = '';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_templates_updated_at
|
||||
ON public.contract_templates(updated_at DESC);
|
||||
UPDATE public.contract_templates
|
||||
SET original_file_name = COALESCE(NULLIF(original_file_name, ''), title || CASE
|
||||
WHEN file_format IS NOT NULL AND BTRIM(file_format) <> '' THEN '.' || LOWER(file_format)
|
||||
ELSE ''
|
||||
END)
|
||||
WHERE original_file_name IS NULL OR BTRIM(original_file_name) = '';
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_indexes
|
||||
WHERE schemaname = 'public'
|
||||
AND indexname = 'idx_contract_categories_name'
|
||||
) THEN
|
||||
EXECUTE 'DROP INDEX IF EXISTS public.idx_contract_categories_name';
|
||||
END IF;
|
||||
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_indexes
|
||||
WHERE schemaname = 'public'
|
||||
AND indexname = 'idx_contract_templates_code'
|
||||
) THEN
|
||||
EXECUTE 'DROP INDEX IF EXISTS public.idx_contract_templates_code';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_contract_categories_name_active
|
||||
ON public.contract_categories(name)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_categories_sort_active
|
||||
ON public.contract_categories(sort_order)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_contract_templates_region_code_active
|
||||
ON public.contract_templates(region, template_code)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_templates_region_active
|
||||
ON public.contract_templates(region)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_templates_category_active
|
||||
ON public.contract_templates(category_id)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_templates_updated_active
|
||||
ON public.contract_templates(updated_at DESC)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_contract_templates_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
t TEXT;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY['contract_categories', 'contract_templates']
|
||||
LOOP
|
||||
EXECUTE format('DROP TRIGGER IF EXISTS trg_%s_updated_at ON %I', t, t);
|
||||
EXECUTE format(
|
||||
'CREATE TRIGGER trg_%s_updated_at
|
||||
BEFORE UPDATE ON %I
|
||||
FOR EACH ROW EXECUTE FUNCTION update_contract_templates_updated_at()',
|
||||
t, t
|
||||
);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMENT ON TABLE public.contract_categories IS '合同模板分类表';
|
||||
COMMENT ON COLUMN public.contract_categories.name IS '分类名称';
|
||||
COMMENT ON COLUMN public.contract_categories.icon IS '分类图标';
|
||||
COMMENT ON COLUMN public.contract_categories.description IS '分类描述';
|
||||
COMMENT ON COLUMN public.contract_categories.sort_order IS '排序值';
|
||||
COMMENT ON COLUMN public.contract_categories.created_by IS '创建人';
|
||||
COMMENT ON COLUMN public.contract_categories.updated_by IS '更新人';
|
||||
COMMENT ON COLUMN public.contract_categories.deleted_at IS '软删除时间';
|
||||
|
||||
COMMENT ON TABLE public.contract_templates IS '合同模板主表';
|
||||
COMMENT ON COLUMN public.contract_templates.template_code IS '模板编码';
|
||||
COMMENT ON COLUMN public.contract_templates.title IS '模板标题';
|
||||
COMMENT ON COLUMN public.contract_templates.category_id IS '所属分类ID';
|
||||
COMMENT ON COLUMN public.contract_templates.region IS '所属地区,省级模板使用“省级”';
|
||||
COMMENT ON COLUMN public.contract_templates.description IS '模板描述';
|
||||
COMMENT ON COLUMN public.contract_templates.file_path IS '源模板文件路径';
|
||||
COMMENT ON COLUMN public.contract_templates.file_format IS '文件格式';
|
||||
COMMENT ON COLUMN public.contract_templates.is_featured IS '是否推荐模板';
|
||||
COMMENT ON COLUMN public.contract_templates.pdf_file_path IS 'PDF预览文件路径';
|
||||
COMMENT ON COLUMN public.contract_templates.file_format IS '文件格式';
|
||||
COMMENT ON COLUMN public.contract_templates.original_file_name IS '原始上传文件名';
|
||||
COMMENT ON COLUMN public.contract_templates.mime_type IS '文件 MIME 类型';
|
||||
COMMENT ON COLUMN public.contract_templates.file_size IS '主文件大小(字节)';
|
||||
COMMENT ON COLUMN public.contract_templates.pdf_file_size IS '预览 PDF 文件大小(字节)';
|
||||
COMMENT ON COLUMN public.contract_templates.is_featured IS '是否推荐模板';
|
||||
COMMENT ON COLUMN public.contract_templates.created_by IS '创建人';
|
||||
COMMENT ON COLUMN public.contract_templates.updated_by IS '更新人';
|
||||
COMMENT ON COLUMN public.contract_templates.deleted_at IS '软删除时间';
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -3,8 +3,8 @@ BEGIN;
|
||||
-- ============================================================================
|
||||
-- LeAudit Platform Contract Template RBAC Seed
|
||||
-- 目标:
|
||||
-- 1. 补齐合同模板读权限
|
||||
-- 2. 给 super_admin / provincial_admin / admin 分配模板读权限
|
||||
-- 1. 补齐合同模板读写删权限
|
||||
-- 2. 给 super_admin / provincial_admin / admin 分配模板权限
|
||||
-- 说明:
|
||||
-- - 依赖 user_rbac_schema_patch.sql
|
||||
-- - 依赖合同模板前端路由已存在于 sys_routes
|
||||
@@ -62,7 +62,10 @@ FROM (
|
||||
VALUES
|
||||
('contract_template:list:read', 'contract_template', 'list', 'read', '查看合同模板列表', '查看合同模板列表', '/contract-template/list', 310, '/api/v3/contract-templates', 'GET'),
|
||||
('contract_template:search:read', 'contract_template', 'search', 'read', '搜索合同模板', '搜索合同模板', '/contract-template/search', 311, '/api/v3/contract-templates/search','GET'),
|
||||
('contract_template:detail:read', 'contract_template', 'detail', 'read', '查看合同模板详情', '查看合同模板详情', '/contract-template/list', 312, '/api/v3/contract-templates/{id}', 'GET')
|
||||
('contract_template:detail:read', 'contract_template', 'detail', 'read', '查看合同模板详情', '查看合同模板详情', '/contract-template/list', 312, '/api/v3/contract-templates/{id}', 'GET'),
|
||||
('contract_template:create:write', 'contract_template', 'create', 'write', '上传合同模板', '上传合同模板', '/contract-template/list', 313, '/api/v3/contract-templates', 'POST'),
|
||||
('contract_template:update:write', 'contract_template', 'update', 'write', '更新合同模板', '更新合同模板', '/contract-template/list', 314, '/api/v3/contract-templates/{id}', 'PUT'),
|
||||
('contract_template:delete:delete', 'contract_template', 'delete', 'delete', '删除合同模板', '删除合同模板', '/contract-template/list', 315, '/api/v3/contract-templates/{id}', 'DELETE')
|
||||
) AS seed(
|
||||
permission_key,
|
||||
module,
|
||||
@@ -105,14 +108,23 @@ seed(role_key, permission_key, grant_type, data_scope) AS (
|
||||
('super_admin', 'contract_template:list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'contract_template:search:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'contract_template:detail:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'contract_template:create:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'contract_template:update:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'contract_template:delete:delete', 'GRANT', 'ALL'),
|
||||
|
||||
('provincial_admin', 'contract_template:list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'contract_template:search:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'contract_template:detail:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'contract_template:create:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'contract_template:update:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'contract_template:delete:delete', 'GRANT', 'ALL'),
|
||||
|
||||
('admin', 'contract_template:list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'contract_template:search:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'contract_template:detail:read', 'GRANT', 'DEPT')
|
||||
('admin', 'contract_template:detail:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'contract_template:create:write', 'GRANT', 'DEPT'),
|
||||
('admin', 'contract_template:update:write', 'GRANT', 'DEPT'),
|
||||
('admin', 'contract_template:delete:delete', 'GRANT', 'DEPT')
|
||||
)
|
||||
INSERT INTO role_permissions (
|
||||
role_id,
|
||||
|
||||
Reference in New Issue
Block a user