From c78cfc838fb182450a01b720baccb953068afea5 Mon Sep 17 00:00:00 2001 From: marco Date: Wed, 17 Jun 2026 21:43:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(cps):=20=E7=BE=A4/=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4(operator,=E4=BA=8C?= =?UTF-8?q?=E6=AC=A1=E7=A1=AE=E8=AE=A4,=E4=B8=8D=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E5=88=A0=E5=B7=B2=E5=8F=91=E9=93=BE=E6=8E=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - repo delete_group/delete_activity + DELETE /cps/groups/{id} 与 /cps/activities/{id} - 硬删记录但保留 cps_link:已发短链继续可用(落地页不依赖 group/activity 存活) - 写审计 cps.group.delete / cps.activity.delete Co-Authored-By: Claude Opus 4.8 --- app/admin/repositories/cps.py | 18 ++++++++++++++++ app/admin/routers/cps.py | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/app/admin/repositories/cps.py b/app/admin/repositories/cps.py index ee39955..e94fee1 100644 --- a/app/admin/repositories/cps.py +++ b/app/admin/repositories/cps.py @@ -120,6 +120,15 @@ def update_group( return group +def delete_group(db: Session, group: CpsGroup, *, commit: bool = True) -> None: + """硬删群。不级联删已生成的 cps_link(已发链接继续可用);该群历史点击/订单按 sid 仍在库。""" + db.delete(group) + if commit: + db.commit() + else: + db.flush() + + # ───────────── 活动 ───────────── def get_activity(db: Session, activity_id: int) -> CpsActivity | None: return db.get(CpsActivity, activity_id) @@ -170,6 +179,15 @@ def create_activity( return activity +def delete_activity(db: Session, activity: CpsActivity, *, commit: bool = True) -> None: + """硬删活动。不级联删 cps_link(已发链接继续可用;淘宝落地页缺活动时取图走兜底默认图)。""" + db.delete(activity) + if commit: + db.commit() + else: + db.flush() + + # ───────────── 订单(对账) ───────────── def _map_order_fields(r: dict) -> dict: """美团 query_order 单条 dataList → CpsOrder 字段(金额转分、时间转 datetime)。""" diff --git a/app/admin/routers/cps.py b/app/admin/routers/cps.py index 71b7078..08980c1 100644 --- a/app/admin/routers/cps.py +++ b/app/admin/routers/cps.py @@ -122,6 +122,26 @@ def update_group( return CpsGroupOut.model_validate(group) +@router.delete("/groups/{group_id}", summary="删除群") +def delete_group( + group_id: int, + request: Request, + admin: Annotated[AdminUser, Depends(require_role("operator"))], + db: AdminDb, +) -> dict: + group = cps_repo.get_group(db, group_id) + if group is None: + raise HTTPException(status_code=404, detail="群不存在") + write_audit( + db, admin, action="cps.group.delete", target_type="cps_group", target_id=group_id, + detail={"name": group.name, "sid": group.sid, "platforms": list(group.platforms or [])}, + ip=get_client_ip(request), commit=False, + ) + cps_repo.delete_group(db, group, commit=False) + db.commit() + return {"ok": True} + + # ───────────── 活动 ───────────── @router.get("/activities", response_model=CursorPage[CpsActivityOut], summary="活动列表") def list_activities( @@ -190,6 +210,26 @@ def activity_images(db: AdminDb) -> dict: return {"images": cps_repo.list_activity_images(db)} +@router.delete("/activities/{activity_id}", summary="删除活动") +def delete_activity( + activity_id: int, + request: Request, + admin: Annotated[AdminUser, Depends(require_role("operator"))], + db: AdminDb, +) -> dict: + activity = cps_repo.get_activity(db, activity_id) + if activity is None: + raise HTTPException(status_code=404, detail="活动不存在") + write_audit( + db, admin, action="cps.activity.delete", target_type="cps_activity", target_id=activity_id, + detail={"name": activity.name, "platform": activity.platform}, + ip=get_client_ip(request), commit=False, + ) + cps_repo.delete_activity(db, activity, commit=False) + db.commit() + return {"ok": True} + + # ───────────── 生成链接(批量,按平台分支) ───────────── def _gen_one_link(db, group: CpsGroup, activity: CpsActivity): """给一个活动生成一条落地页 link。美团:转链拿短链(需群 sid);淘宝/京东:用 payload。"""