feat: add backend rule group and permission support

This commit is contained in:
wren
2026-05-06 09:40:37 +08:00
parent 7acbe0f1d9
commit 76ba7e65ed
45 changed files with 6175 additions and 110 deletions
@@ -39,29 +39,85 @@ class RuleServiceImpl(IRuleService):
text(
"""
SELECT
id,
rule_type,
rule_name,
domain_type,
current_version_id,
status
FROM leaudit_rule_sets
WHERE deleted_at IS NULL
ORDER BY id DESC
rs.id,
rs.rule_type,
rs.rule_name,
rs.domain_type,
rs.current_version_id,
current_rv.id AS usable_current_version_id,
fallback_rv.id AS fallback_version_id,
CASE
WHEN current_rv.id IS NOT NULL OR fallback_rv.id IS NOT NULL THEN TRUE
ELSE FALSE
END AS has_usable_version,
rs.status
FROM leaudit_rule_sets rs
LEFT JOIN leaudit_rule_versions current_rv
ON current_rv.id = rs.current_version_id
AND current_rv.status IN ('published', 'rollback')
LEFT JOIN LATERAL (
SELECT rv.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 rs.deleted_at IS NULL
ORDER BY rs.id DESC
"""
)
)
return [
RuleSetVO(
id=int(Row["id"]),
ruleType=Row["rule_type"],
ruleName=Row["rule_name"],
domainType=Row["domain_type"],
currentVersionId=Row["current_version_id"],
status=Row["status"],
)
for Row in Result.mappings().all()
]
rows = Result.mappings().all()
usable_counts: dict[int, int] = {}
for row in rows:
usable_version_id = row["usable_current_version_id"] or row["fallback_version_id"]
if usable_version_id is not None and int(usable_version_id) not in usable_counts:
usable_counts[int(usable_version_id)] = await self._GetRuleCountByVersionId(int(usable_version_id))
return [
RuleSetVO(
id=int(Row["id"]),
ruleType=Row["rule_type"],
ruleName=Row["rule_name"],
domainType=Row["domain_type"],
currentVersionId=Row["current_version_id"],
fallbackVersionId=Row["fallback_version_id"],
hasUsableVersion=bool(Row["has_usable_version"]),
usableRuleCount=usable_counts.get(int(Row["usable_current_version_id"] or Row["fallback_version_id"]), 0)
if (Row["usable_current_version_id"] or Row["fallback_version_id"]) is not None
else 0,
status=Row["status"],
)
for Row in rows
]
async def _GetRuleCountByVersionId(self, VersionId: int) -> int:
"""读取指定可用规则版本的规则数。"""
async with GetAsyncSession() as Session:
Result = await Session.execute(
text(
"""
SELECT oss_url
FROM leaudit_rule_versions
WHERE id = :version_id
LIMIT 1
"""
),
{"version_id": VersionId},
)
Row = Result.mappings().first()
if not Row or not Row["oss_url"]:
return 0
try:
yaml_text = (await self.OssService.DownloadBytes(Row["oss_url"])).decode("utf-8")
validation = self.Validator.ValidateYaml(yaml_text)
return int(validation.ruleCount or 0)
except Exception:
return 0
async def GetVersions(self, RuleType: str) -> list[RuleVersionVO]:
"""获取规则集的所有版本。"""