feat(huya): 协作台账勾选导出 CK 到剪贴板(单点权限 + 逐行审计)+ 工具区固定两行

This commit is contained in:
yml2213
2026-10-16 22:24:08 +08:00
parent 6ef74c8e45
commit 82c59bb4af
9 changed files with 431 additions and 6 deletions
@@ -1678,6 +1678,90 @@ def list_orders_by_ids(db: Session, ids: Sequence[int]) -> list[HuyaExternalOrde
return [by_id[value] for value in wanted if value in by_id]
# 导出 CK 的审计动作名(导出=把凭据带出系统,必须留痕)
CK_EXPORT_ACTION = "huya:collab:ck_export"
def export_cks(
db: Session,
current: User | None,
orders: Sequence[HuyaExternalOrder],
*,
commit: bool = True,
) -> dict:
"""把勾选行的 **CK 明文**取出来(前端写剪贴板用)。
这是本模块唯一一个把凭据**往外送**的读接口,所以三条约束写死在这里:
1. **权限单独一个点**(``huya:collab:ck_export``,默认只给运营)—— 贴 CK 是「录入」,
导出是「把凭据带走」,两件事不该共用一个权限(口径同 ``huya:cookie:export``);
2. **逐行写审计**(``huya:collab:ck_export``):只记「谁在什么时候导出了哪一单」,
**绝不把 CK 本体写进审计/日志**(列表接口也照旧不返回 cookie);
3. **没 CK 的行显式跳过并回原因**,不静默丢;也不替用户猜 ——
作废/停用的单只要还有 CK 照样导出,界面把状态标出来让人自己判断。
Returns:
``{total, exported, skipped: [{id, order_no, reason}], items: [{..., ck_text}]}``
——只有这个接口会返回 ``ck_text``。
"""
rows = list(orders)
if not rows:
raise CollabError("请先勾选要导出的行", code="ck_export_empty")
if len(rows) > PROBE_BATCH_MAX:
raise CollabError(
f"一次最多导出 {PROBE_BATCH_MAX} 行,请分批操作", code="ck_export_too_large"
)
items: list[dict] = []
skipped: list[dict] = []
for order in rows:
ck_text = str(order.cookie or "").strip()
if not ck_text:
skipped.append(
{
"id": int(order.id),
"order_no": order.order_no,
"reason": "这行还没贴 CK",
}
)
continue
items.append(
{
"id": int(order.id),
"order_no": order.order_no,
"uid": str(order.uid or ""),
"nickname": order.nickname or "",
"status": order.status,
"status_label": ORDER_STATUS_LABELS.get(order.status, order.status),
"ck_status": order.ck_status,
"ck_status_label": CK_STATUS_LABELS.get(
order.ck_status, order.ck_status
),
"ck_text": ck_text,
}
)
record_audit(
db,
current,
action=CK_EXPORT_ACTION,
target=_audit_target(order),
detail={
"order_no": order.order_no,
"uid": str(order.uid or ""),
"ck_status": order.ck_status,
"batch_size": len(rows),
},
)
if commit:
db.commit()
return {
"total": len(rows),
"exported": len(items),
"skipped": skipped,
"items": items,
}
# --------------------------------------------------------------------------
# 店铺字典(新建协作单时点一下选;也支持自定义输入)
# --------------------------------------------------------------------------