diff --git a/web/backend/routers/cookies.py b/web/backend/routers/cookies.py index 6f92915..0d27a5c 100644 --- a/web/backend/routers/cookies.py +++ b/web/backend/routers/cookies.py @@ -139,3 +139,24 @@ def delete_cookie( task.message = "Cookie已清除" db.commit() return {"message": "已删除", "success": True} + + +@router.delete("/batch") +def delete_cookies_batch( + task_ids: str = "", + db: Session = Depends(get_db), + current: User = Depends(require_permission("cookie:export")), +): + """批量删除 Cookie 记录。""" + if not task_ids: + raise HTTPException(status_code=400, detail="请指定记录ID") + ids = [int(x) for x in task_ids.split(",") if x.strip().isdigit()] + if not ids: + raise HTTPException(status_code=400, detail="无效的ID") + tasks = db.query(LoginTask).filter(LoginTask.id.in_(ids)).all() + for t in tasks: + t.cookie = "" + t.status = "failed" + t.message = "Cookie已清除" + db.commit() + return {"message": f"已删除 {len(tasks)} 条", "deleted": len(tasks), "success": True} diff --git a/web/frontend/src/api/cookies.ts b/web/frontend/src/api/cookies.ts index 7f68e0f..1fd4b07 100644 --- a/web/frontend/src/api/cookies.ts +++ b/web/frontend/src/api/cookies.ts @@ -1,8 +1,9 @@ import api from './client'; -import type { CookieItem, MessageResponse } from './types'; +import type { CookieItem, MessageDeletedResponse, MessageResponse } from './types'; export const cookieApi = { list: () => api.get('/cookies'), exportCsv: (format?: string) => api.get('/cookies/export', { responseType: 'blob', params: format ? { format } : {} }), delete: (id: number) => api.delete(`/cookies/${id}`), + deleteBatch: (ids: number[]) => api.delete('/cookies/batch', { params: { task_ids: ids.join(',') } }), }; diff --git a/web/frontend/src/pages/CookiePage.tsx b/web/frontend/src/pages/CookiePage.tsx index a64ac62..fa02f47 100644 --- a/web/frontend/src/pages/CookiePage.tsx +++ b/web/frontend/src/pages/CookiePage.tsx @@ -118,6 +118,22 @@ export default function CookiePage() { } }; + const handleDeleteSelected = async () => { + if (selectedRowKeys.length === 0) { + message.warning('请先选择要删除的 Cookie'); + return; + } + try { + const ids = selectedRowKeys.map((k) => Number(k)); + const res = await cookieApi.deleteBatch(ids); + message.success(res.message); + setSelectedRowKeys([]); + loadCookies(); + } catch (e: unknown) { + message.error(getErrorMessage(e)); + } + }; + // 筛选 const filteredCookies = cookies.filter((c) => { if (!searchText) return true; @@ -199,6 +215,21 @@ export default function CookiePage() { > 复制选中 {selectedRowKeys.length > 0 && `(${selectedRowKeys.length})`} + {canExport && ( + + + + )} {canExport && (