feat: add tenant-scoped rule and permission management

This commit is contained in:
wren
2026-05-21 22:03:08 +08:00
parent a2c2bf1969
commit 1f1bccf3b3
193 changed files with 64463 additions and 1771 deletions
@@ -7,7 +7,8 @@ class ContractTemplateListQueryDTO(BaseModel):
keyword: str | None = Field(None, description="关键词")
category_id: int | None = Field(None, description="分类ID")
category_name: str | None = Field(None, description="分类名称")
region: str | None = Field(None, description="地区")
region: str | None = Field(None, description="兼容保留字段:租户展示值/旧地区")
tenant_code: str | None = Field(None, description="租户编码")
file_format: str | None = Field(None, description="文件格式")
is_featured: bool | None = Field(None, description="是否推荐")
page: int = Field(1, ge=1, description="页码")
@@ -22,7 +23,8 @@ class ContractTemplateSearchQueryDTO(BaseModel):
q: str = Field(..., min_length=1, description="搜索关键词")
category_id: int | None = Field(None, description="分类ID")
category_name: str | None = Field(None, description="分类名称")
region: str | None = Field(None, description="地区")
region: str | None = Field(None, description="兼容保留字段:租户展示值/旧地区")
tenant_code: str | None = Field(None, description="租户编码")
page: int = Field(1, ge=1, description="页码")
page_size: int = Field(12, ge=1, le=200, description="分页大小")
sort_by: str = Field("updated_at", description="排序字段")
@@ -35,6 +37,7 @@ class ContractTemplateCreateDTO(BaseModel):
title: str = Field(..., min_length=1, max_length=200, description="模板标题")
template_code: str = Field(..., min_length=1, max_length=50, description="模板编码")
category_id: int = Field(..., description="分类ID")
region: str | None = Field(None, description="所属地区")
region: str | None = Field(None, description="兼容保留字段:所属租户展示值/旧地区")
tenant_code: str | None = Field(None, description="所属租户编码")
description: str | None = Field(None, description="模板简介")
is_featured: bool = Field(False, description="是否推荐")
@@ -4,13 +4,22 @@ from pydantic import BaseModel, Field
class EntryModuleAreaDTO(BaseModel):
"""入口模块地区配置。"""
"""入口模块历史地区配置,仅用于兼容旧请求"""
area: str = Field(..., description="地区名称")
enabled: bool = Field(True, description="是否启用")
sort_order: int = Field(0, description="排序号")
class EntryModuleTenantDTO(BaseModel):
"""入口模块租户配置。"""
tenant_code: str = Field(..., description="租户编码")
tenant_name: str | None = Field(None, description="租户名称")
enabled: bool = Field(True, description="是否启用")
sort_order: int = Field(0, description="排序号")
class EntryModuleCreateDTO(BaseModel):
"""创建入口模块请求。"""
@@ -18,7 +27,8 @@ class EntryModuleCreateDTO(BaseModel):
description: str | None = Field(None, description="模块描述")
path: str | None = Field(None, description="前端路由路径")
route_path: str | None = Field(None, description="前端跳转路径")
areas: list[EntryModuleAreaDTO] | None = Field(None, description="地区配置")
areas: list[EntryModuleAreaDTO] | None = Field(None, description="历史地区配置(兼容字段,建议改用 tenants")
tenants: list[EntryModuleTenantDTO] | None = Field(None, description="租户配置")
class EntryModuleUpdateDTO(BaseModel):
@@ -28,4 +38,5 @@ class EntryModuleUpdateDTO(BaseModel):
description: str | None = Field(None, description="模块描述")
path: str | None = Field(None, description="前端路由路径")
route_path: str | None = Field(None, description="前端跳转路径")
areas: list[EntryModuleAreaDTO] | None = Field(None, description="地区配置")
areas: list[EntryModuleAreaDTO] | None = Field(None, description="历史地区配置(兼容字段,建议改用 tenants")
tenants: list[EntryModuleTenantDTO] | None = Field(None, description="租户配置")
@@ -23,6 +23,8 @@ class EvaluationPointBaseDTO(BaseModel):
action_config: str | None = Field(None, description="动作配置")
score: float | int | None = Field(None, description="分值")
area: str | None = Field(None, description="地区")
tenant_code: str | None = Field(None, description="租户编码")
tenant_name: str | None = Field(None, description="租户名称")
class EvaluationPointCreateDTO(EvaluationPointBaseDTO):
@@ -60,3 +60,9 @@ class UserRolesAssignDTO(BaseModel):
"""用户角色分配请求。"""
role_ids: list[int] = Field(default_factory=list, description="角色ID列表")
class UserTenantUpdateDTO(BaseModel):
"""用户租户更新请求。"""
tenant_code: str = Field(..., description="租户编码")
@@ -9,7 +9,7 @@ class RuleBindingCreateDTO(BaseModel):
docTypeId: int = Field(..., description="文档类型ID → leaudit_document_types.id")
docTypeCode: str | None = Field(None, description="文档类型编码(冗余快速匹配)")
ruleSetId: int = Field(..., description="规则集ID → leaudit_rule_sets.id")
region: str = Field("default", description="适用地区")
region: str = Field("公共", description="兼容保留字段:旧地区/租户展示值")
bindingMode: str = Field("explicit", description="绑定模式: explicit / wildcard / fallback")
priority: int = Field(0, description="优先级(数值越大优先级越高)")
note: str | None = Field(None, description="备注说明")
@@ -0,0 +1,51 @@
"""租户主数据 DTO。"""
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
class TenantCreateDTO(BaseModel):
"""创建租户请求。"""
tenant_code: str = Field(..., description="租户编码")
tenant_name: str = Field(..., description="租户名称")
tenant_short_name: str | None = Field(None, description="租户简称")
tenant_type: str = Field("CUSTOM", description="租户类型")
parent_tenant_code: str | None = Field(None, description="父级租户编码")
display_order: int = Field(0, description="显示顺序")
is_enabled: bool = Field(True, description="是否启用")
is_public: bool = Field(False, description="是否公共租户")
can_host_entry_module: bool = Field(True, description="是否可分配入口模块")
can_host_documents: bool = Field(True, description="是否可承载文档")
can_host_rag: bool = Field(True, description="是否可承载知识库")
can_host_templates: bool = Field(True, description="是否可承载模板")
feature_keys: list[str] = Field(default_factory=list, description="功能开关键列表")
alias_values: list[str] = Field(default_factory=list, description="兼容别名列表")
ext: dict[str, Any] | None = Field(None, description="扩展字段")
class TenantUpdateDTO(BaseModel):
"""更新租户请求。"""
tenant_name: str | None = Field(None, description="租户名称")
tenant_short_name: str | None = Field(None, description="租户简称")
tenant_type: str | None = Field(None, description="租户类型")
parent_tenant_code: str | None = Field(None, description="父级租户编码")
display_order: int | None = Field(None, description="显示顺序")
is_public: bool | None = Field(None, description="是否公共租户")
can_host_entry_module: bool | None = Field(None, description="是否可分配入口模块")
can_host_documents: bool | None = Field(None, description="是否可承载文档")
can_host_rag: bool | None = Field(None, description="是否可承载知识库")
can_host_templates: bool | None = Field(None, description="是否可承载模板")
feature_keys: list[str] | None = Field(None, description="功能开关键列表")
alias_values: list[str] | None = Field(None, description="兼容别名列表")
ext: dict[str, Any] | None = Field(None, description="扩展字段")
class TenantStatusUpdateDTO(BaseModel):
"""租户启停请求。"""
is_enabled: bool = Field(..., description="是否启用")