feat(huya): 协作台账勾选导出 CK 到剪贴板(单点权限 + 逐行审计)+ 工具区固定两行
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 店铺字典(新建协作单时点一下选;也支持自定义输入)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user