feat: migrate rule bindings to group-based flow
This commit is contained in:
@@ -44,6 +44,67 @@ def _normalize_speed(speed: str | None) -> str:
|
||||
class AuditServiceImpl(IAuditService):
|
||||
"""评查服务实现。"""
|
||||
|
||||
async def _resolve_rule_binding_from_group(self, session, group_id: int | None) -> dict | None:
|
||||
"""按二级分组解析正式规则绑定。"""
|
||||
if not group_id:
|
||||
return None
|
||||
result = await session.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT
|
||||
rs.id AS rule_set_id,
|
||||
COALESCE(rs.current_version_id, fallback_rv.id) AS rule_version_id,
|
||||
COALESCE(current_rv.oss_url, fallback_rv.oss_url) AS rule_source_oss_url,
|
||||
COALESCE(current_rv.file_sha256, fallback_rv.file_sha256) AS rule_source_sha256,
|
||||
COALESCE(current_rv.metadata_type_id, fallback_rv.metadata_type_id) AS rule_type_id
|
||||
FROM leaudit_rule_group_bindings rgb
|
||||
JOIN leaudit_rule_sets rs ON rs.id = rgb.rule_set_id
|
||||
LEFT JOIN leaudit_rule_versions current_rv ON current_rv.id = rs.current_version_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
rv.id,
|
||||
rv.oss_url,
|
||||
rv.file_sha256,
|
||||
rv.metadata_type_id
|
||||
FROM leaudit_rule_versions rv
|
||||
WHERE rv.rule_set_id = rs.id
|
||||
AND rv.status IN ('published', 'rollback')
|
||||
ORDER BY rv.version_seq DESC, rv.id DESC
|
||||
LIMIT 1
|
||||
) fallback_rv ON TRUE
|
||||
WHERE rgb.group_id = :group_id
|
||||
AND rgb.is_active = TRUE
|
||||
AND rgb.deleted_at IS NULL
|
||||
ORDER BY rgb.priority DESC, rgb.id ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
),
|
||||
{"group_id": int(group_id)},
|
||||
)
|
||||
return result.mappings().first()
|
||||
|
||||
async def _resolve_unique_group_binding_by_doc_type(self, session, doc_type_id: int | None) -> dict | None:
|
||||
"""当文档尚未落 group_id 时,按文档类型唯一子组兜底解析正式绑定。"""
|
||||
if not doc_type_id:
|
||||
return None
|
||||
group_row = (
|
||||
await session.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT CASE WHEN COUNT(*) = 1 THEN MIN(id) END AS group_id
|
||||
FROM leaudit_evaluation_point_groups
|
||||
WHERE document_type_id = :doc_type_id
|
||||
AND deleted_at IS NULL
|
||||
AND is_enabled = TRUE
|
||||
AND COALESCE(pid, 0) <> 0
|
||||
"""
|
||||
),
|
||||
{"doc_type_id": int(doc_type_id)},
|
||||
)
|
||||
).mappings().first()
|
||||
resolved_group_id = int(group_row["group_id"]) if group_row and group_row.get("group_id") is not None else None
|
||||
return await self._resolve_rule_binding_from_group(session, resolved_group_id)
|
||||
|
||||
async def Run(
|
||||
self,
|
||||
DocumentId: int,
|
||||
@@ -125,44 +186,14 @@ class AuditServiceImpl(IAuditService):
|
||||
)
|
||||
latestRunNo = runNoResult.scalar_one_or_none() or 0
|
||||
|
||||
binding = None
|
||||
if getattr(document, "groupId", None):
|
||||
groupBindingResult = await session.execute(
|
||||
text(
|
||||
"""
|
||||
SELECT
|
||||
rs.id AS rule_set_id,
|
||||
COALESCE(rs.current_version_id, fallback_rv.id) AS rule_version_id,
|
||||
COALESCE(current_rv.oss_url, fallback_rv.oss_url) AS rule_source_oss_url,
|
||||
COALESCE(current_rv.file_sha256, fallback_rv.file_sha256) AS rule_source_sha256,
|
||||
COALESCE(current_rv.metadata_type_id, fallback_rv.metadata_type_id) AS rule_type_id
|
||||
FROM leaudit_rule_group_bindings rgb
|
||||
JOIN leaudit_rule_sets rs ON rs.id = rgb.rule_set_id
|
||||
LEFT JOIN leaudit_rule_versions current_rv ON current_rv.id = rs.current_version_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
rv.id,
|
||||
rv.oss_url,
|
||||
rv.file_sha256,
|
||||
rv.metadata_type_id
|
||||
FROM leaudit_rule_versions rv
|
||||
WHERE rv.rule_set_id = rs.id
|
||||
AND rv.status IN ('published', 'rollback')
|
||||
ORDER BY rv.version_seq DESC, rv.id DESC
|
||||
LIMIT 1
|
||||
) fallback_rv ON TRUE
|
||||
WHERE rgb.group_id = :group_id
|
||||
AND rgb.is_active = TRUE
|
||||
AND rgb.deleted_at IS NULL
|
||||
ORDER BY rgb.priority DESC, rgb.id ASC
|
||||
LIMIT 1
|
||||
"""
|
||||
),
|
||||
{"group_id": int(document.groupId)},
|
||||
)
|
||||
binding = groupBindingResult.mappings().first()
|
||||
binding = await self._resolve_rule_binding_from_group(session, getattr(document, "groupId", None))
|
||||
if binding is None:
|
||||
binding = await self._resolve_unique_group_binding_by_doc_type(session, getattr(document, "typeId", None))
|
||||
if binding and getattr(document, "groupId", None) is None:
|
||||
logger.info("文档未显式记录 group_id,已按文档类型唯一子组解析正式规则绑定")
|
||||
if not binding or not binding["rule_set_id"] or not binding["rule_version_id"]:
|
||||
raise LeauditException(StatusCodeEnum.HTTP_400_BAD_REQUEST, "当前子类型未绑定可执行规则集,请先检查二级分组规则配置")
|
||||
if getattr(document, "groupId", None):
|
||||
raise LeauditException(StatusCodeEnum.HTTP_400_BAD_REQUEST, "当前子类型未绑定可执行规则集,请先检查二级分组规则配置")
|
||||
|
||||
if binding is None:
|
||||
bindingResult = await session.execute(
|
||||
|
||||
Reference in New Issue
Block a user