Files
2026-09-13 22:21:49 +08:00

82 lines
2.4 KiB
Python

"""审计台账(PRD §4.6):本人操作记录筛选 + CSV 导出。"""
from __future__ import annotations
import csv
import io
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from model.sys_user import SysUser
from repositories.audit_log import AuditLogRepo
from utils.pagination import normalize_pagination, pagination_result
def _audit_item(a) -> dict:
return {
"id": a.id,
"module": a.module,
"action": a.action,
"target": a.target,
"detail": a.detail,
"trace_id": a.trace_id,
"status": a.status,
"create_time": a.create_time.isoformat() if a.create_time else None,
}
async def list_ledger(
db: AsyncSession,
user: SysUser,
*,
action: str | None = None,
customer_id: int | None = None,
keyword: str | None = None,
start: datetime | None = None,
end: datetime | None = None,
page: int = 1,
page_size: int = 10,
) -> dict:
page, page_size, offset = normalize_pagination(page, page_size)
repo = AuditLogRepo(db)
items = await repo.list_by_advisor(
user_id=user.id, action=action, customer_id=customer_id, keyword=keyword, start=start, end=end,
limit=page_size, offset=offset,
)
total = await repo.count_by_advisor(
user_id=user.id, action=action, keyword=keyword, start=start, end=end
)
return pagination_result(
[_audit_item(a) for a in items], total, page=page, page_size=page_size
)
def _to_csv(rows: list[dict]) -> str:
"""行列表 → CSV 文本(空列表返回空串)。"""
if not rows:
return ""
buf = io.StringIO()
writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
return buf.getvalue()
async def export_ledger(
db: AsyncSession,
user: SysUser,
*,
action: str | None = None,
customer_id: int | None = None,
keyword: str | None = None,
start: datetime | None = None,
end: datetime | None = None,
) -> str:
"""导出本人审计台账为 CSV 文本(全量,不限分页大小,上限 10000 条)。"""
repo = AuditLogRepo(db)
items = await repo.list_by_advisor(
user_id=user.id, action=action, customer_id=customer_id, keyword=keyword, start=start, end=end,
limit=10000, offset=0,
)
return _to_csv([_audit_item(a) for a in items])