From c776af598ad54adb61c89543613910f24fde9b49 Mon Sep 17 00:00:00 2001 From: wren <“porlong@qq.com”> Date: Tue, 28 Apr 2026 14:19:29 +0800 Subject: [PATCH] refactor: region from document, not app config - Add region column to leaudit_documents + LeauditDocument model - AuditServiceImpl: read region from document.region, not APP_REGION - RuleServiceImpl: ListBindings/CreateBinding accept Region parameter - RuleBindingCreateDTO: add region field - RuleController: pass region from query param/DTO to service - APP_REGION removed from binding queries; region flows from document Region is now per-document: each document carries its region at upload time, and rules are matched to the document's region at run time. --- .../controllers/ruleController.py | 7 ++- .../domian/Dto/ruleBindingDto.py | 1 + .../fastapi_leaudit/models/leauditDocument.py | 1 + .../services/impl/auditServiceImpl.py | 3 +- .../services/impl/ruleServiceImpl.py | 63 ++++++++++++++++--- .../fastapi_leaudit/services/ruleService.py | 5 +- 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/fastapi_modules/fastapi_leaudit/controllers/ruleController.py b/fastapi_modules/fastapi_leaudit/controllers/ruleController.py index 59016ce..b958201 100644 --- a/fastapi_modules/fastapi_leaudit/controllers/ruleController.py +++ b/fastapi_modules/fastapi_leaudit/controllers/ruleController.py @@ -89,9 +89,9 @@ class RuleController(BaseController): # ── 规则类型绑定 ────────────────────────────────────────── @self.router.get("/bindings", response_model=Result[list[RuleBindingVO]]) - async def ListBindings(ruleType: str | None = None): - """列出规则类型绑定。可按规则类型过滤。""" - Data = await self.RuleService.ListBindings(RuleType=ruleType) + async def ListBindings(ruleType: str | None = None, region: str | None = None): + """列出规则类型绑定。可按规则类型/地区过滤。""" + Data = await self.RuleService.ListBindings(RuleType=ruleType, Region=region) return Result.success(data=Data) @self.router.post("/{RuleType}/bindings", response_model=Result[RuleBindingVO]) @@ -100,6 +100,7 @@ class RuleController(BaseController): Data = await self.RuleService.CreateBinding( DocTypeId=body.docTypeId, RuleSetId=body.ruleSetId, + Region=body.region, BindingMode=body.bindingMode, Priority=body.priority, DocTypeCode=body.docTypeCode, diff --git a/fastapi_modules/fastapi_leaudit/domian/Dto/ruleBindingDto.py b/fastapi_modules/fastapi_leaudit/domian/Dto/ruleBindingDto.py index e73297a..638792d 100644 --- a/fastapi_modules/fastapi_leaudit/domian/Dto/ruleBindingDto.py +++ b/fastapi_modules/fastapi_leaudit/domian/Dto/ruleBindingDto.py @@ -9,6 +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="适用地区") bindingMode: str = Field("explicit", description="绑定模式: explicit / wildcard / fallback") priority: int = Field(0, description="优先级(数值越大优先级越高)") note: str | None = Field(None, description="备注说明") diff --git a/fastapi_modules/fastapi_leaudit/models/leauditDocument.py b/fastapi_modules/fastapi_leaudit/models/leauditDocument.py index 61fb8ed..b6b7d10 100644 --- a/fastapi_modules/fastapi_leaudit/models/leauditDocument.py +++ b/fastapi_modules/fastapi_leaudit/models/leauditDocument.py @@ -22,6 +22,7 @@ class LeauditDocument(BaseModel): typeId: Mapped[int | None] = mapped_column(BigInteger, comment="文档类型ID") processingStatus: Mapped[str | None] = mapped_column(String(64), default="waiting", comment="waiting/processing/completed/failed") currentRunId: Mapped[int | None] = mapped_column(BigInteger, comment="最新有效 run id") + region: Mapped[str] = mapped_column(String(32), default="default", comment="所属地区: mz/yf/jy/cz/default") @classmethod async def get_by_biz_id(cls, session: AsyncSession, bizDocumentId: int) -> "LeauditDocument | None": diff --git a/fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py b/fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py index 7907950..7b9df51 100644 --- a/fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py +++ b/fastapi_modules/fastapi_leaudit/services/impl/auditServiceImpl.py @@ -6,7 +6,6 @@ from datetime import datetime -from fastapi_admin.config import APP_REGION from fastapi_common.fastapi_common_logger import logger from fastapi_common.fastapi_common_sqlalchemy.database import GetAsyncSession from fastapi_common.fastapi_common_web.domain.responses import StatusCodeEnum @@ -78,7 +77,7 @@ class AuditServiceImpl(IAuditService): LIMIT 1 """ ), - {"doc_type_id": document.typeId, "region": APP_REGION}, + {"doc_type_id": document.typeId, "region": document.region}, ) binding = bindingResult.mappings().first() if not binding or not binding["rule_set_id"] or not binding["rule_version_id"]: diff --git a/fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py b/fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py index 837afca..9e865bc 100644 --- a/fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py +++ b/fastapi_modules/fastapi_leaudit/services/impl/ruleServiceImpl.py @@ -3,7 +3,6 @@ from __future__ import annotations import hashlib -from fastapi_admin.config import APP_REGION from fastapi_common.fastapi_common_sqlalchemy.database import GetAsyncSession from fastapi_common.fastapi_common_web.domain.responses import StatusCodeEnum from fastapi_common.fastapi_common_web.exception.LeauditException import LeauditException @@ -341,10 +340,11 @@ class RuleServiceImpl(IRuleService): Rollback=True, ) - async def ListBindings(self, RuleType: str | None = None) -> list[RuleBindingVO]: - """列出规则类型绑定,可按规则类型过滤。""" + async def ListBindings(self, RuleType: str | None = None, Region: str | None = None) -> list[RuleBindingVO]: + """列出规则类型绑定,可按规则类型/地区过滤。""" + region = Region or "" async with GetAsyncSession() as Session: - if RuleType: + if RuleType and region: Result = await Session.execute( text( """ @@ -367,9 +367,9 @@ class RuleServiceImpl(IRuleService): ORDER BY b.priority DESC, b.id DESC """ ), - {"rule_type": RuleType, "region": APP_REGION}, + {"rule_type": RuleType, "region": region}, ) - else: + elif region: Result = await Session.execute( text( """ @@ -391,7 +391,53 @@ class RuleServiceImpl(IRuleService): ORDER BY rs.rule_type, b.priority DESC, b.id DESC """ ), - {"region": APP_REGION}, + {"region": region}, + ) + elif RuleType: + Result = await Session.execute( + text( + """ + SELECT + b.id, + b.doc_type_id, + b.doc_type_code, + b.rule_set_id, + b.binding_mode, + b.priority, + b.is_active, + b.note, + rs.rule_type, + rs.rule_name + FROM leaudit_rule_type_bindings b + JOIN leaudit_rule_sets rs ON rs.id = b.rule_set_id + WHERE rs.rule_type = :rule_type + AND rs.deleted_at IS NULL + ORDER BY b.priority DESC, b.id DESC + """ + ), + {"rule_type": RuleType}, + ) + else: + Result = await Session.execute( + text( + """ + SELECT + b.id, + b.doc_type_id, + b.doc_type_code, + b.rule_set_id, + b.binding_mode, + b.priority, + b.is_active, + b.note, + rs.rule_type, + rs.rule_name + FROM leaudit_rule_type_bindings b + JOIN leaudit_rule_sets rs ON rs.id = b.rule_set_id + WHERE rs.deleted_at IS NULL + ORDER BY rs.rule_type, b.priority DESC, b.id DESC + """ + ), ) return [ RuleBindingVO( @@ -413,6 +459,7 @@ class RuleServiceImpl(IRuleService): self, DocTypeId: int, RuleSetId: int, + Region: str = "default", BindingMode: str = "explicit", Priority: int = 0, DocTypeCode: str | None = None, @@ -473,7 +520,7 @@ class RuleServiceImpl(IRuleService): "rule_set_id": RuleSetId, "binding_mode": BindingMode, "priority": Priority, - "region": APP_REGION, + "region": Region, "note": Note, }, ) diff --git a/fastapi_modules/fastapi_leaudit/services/ruleService.py b/fastapi_modules/fastapi_leaudit/services/ruleService.py index d239b27..21e3bcd 100644 --- a/fastapi_modules/fastapi_leaudit/services/ruleService.py +++ b/fastapi_modules/fastapi_leaudit/services/ruleService.py @@ -66,8 +66,8 @@ class IRuleService(ABC): ... @abstractmethod - async def ListBindings(self, RuleType: str | None = None) -> list[RuleBindingVO]: - """列出规则类型绑定。可按规则类型过滤。""" + async def ListBindings(self, RuleType: str | None = None, Region: str | None = None) -> list[RuleBindingVO]: + """列出规则类型绑定。可按规则类型/地区过滤。""" ... @abstractmethod @@ -75,6 +75,7 @@ class IRuleService(ABC): self, DocTypeId: int, RuleSetId: int, + Region: str = "default", BindingMode: str = "explicit", Priority: int = 0, DocTypeCode: str | None = None,