diff --git a/src/server/main.py b/src/server/main.py index ec572d9..24c7412 100644 --- a/src/server/main.py +++ b/src/server/main.py @@ -1697,6 +1697,9 @@ def validate_save_name(name: str) -> bool: class SaveGameRequest(BaseModel): custom_name: Optional[str] = None # 自定义存档名称 +class DeleteSaveRequest(BaseModel): + filename: str + class LoadGameRequest(BaseModel): filename: str @@ -1752,6 +1755,37 @@ def api_save_game(req: SaveGameRequest): else: raise HTTPException(status_code=500, detail="Save failed") +@app.post("/api/game/delete") +def api_delete_game(req: DeleteSaveRequest): + """删除存档及其关联文件""" + # 安全检查 + if ".." in req.filename or "/" in req.filename or "\\" in req.filename: + raise HTTPException(status_code=400, detail="Invalid filename") + + try: + saves_dir = CONFIG.paths.saves + target_path = saves_dir / req.filename + + # 1. 删除 JSON 存档文件 + if target_path.exists(): + os.remove(target_path) + + # 2. 删除对应的 SQL 数据库文件 + events_db_path = get_events_db_path(target_path) + if os.path.exists(events_db_path): + try: + os.remove(events_db_path) + except Exception as e: + print(f"[Warning] Failed to delete db file {events_db_path}: {e}") + + # 3. 删除可能存在的其他关联文件(如果有) + + return {"status": "ok", "message": "Save deleted"} + except Exception as e: + import traceback + traceback.print_exc() + raise HTTPException(status_code=500, detail=f"Delete failed: {str(e)}") + @app.post("/api/game/load") async def api_load_game(req: LoadGameRequest): """加载游戏(异步,支持进度更新)。""" diff --git a/web/src/api/modules/system.ts b/web/src/api/modules/system.ts index 222fcd5..0cfb78c 100644 --- a/web/src/api/modules/system.ts +++ b/web/src/api/modules/system.ts @@ -26,6 +26,10 @@ export const systemApi = { ); }, + deleteSave(filename: string) { + return httpClient.post<{ status: string; message: string }>('/api/game/delete', { filename }); + }, + loadGame(filename: string) { return httpClient.post<{ status: string; message: string }>('/api/game/load', { filename }); }, diff --git a/web/src/components/game/panels/system/SaveLoadPanel.vue b/web/src/components/game/panels/system/SaveLoadPanel.vue index a3c615b..8402910 100644 --- a/web/src/components/game/panels/system/SaveLoadPanel.vue +++ b/web/src/components/game/panels/system/SaveLoadPanel.vue @@ -112,6 +112,21 @@ async function handleLoad(filename: string) { } } +async function handleDelete(filename: string) { + if (!confirm(t('save_load.delete_confirm', { filename }))) return + + loading.value = true + try { + await systemApi.deleteSave(filename) + message.success(t('save_load.delete_success')) + await fetchSaves() + } catch (e) { + message.error(t('save_load.delete_failed')) + } finally { + loading.value = false + } +} + // 格式化保存时间 function formatSaveTime(isoTime: string): string { if (!isoTime) return '' @@ -199,7 +214,22 @@ onMounted(() => { v{{ save.version }} -