From 9f627bbef9390bfe05a2158b9240c86b8d1839ac Mon Sep 17 00:00:00 2001 From: Hera Zhao Date: Sat, 11 Apr 2026 22:08:02 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E9=85=8D=E6=96=B9=E7=BB=9F=E4=B8=80=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=EF=BC=8C=E7=A7=BB=E9=99=A4=E7=94=A8=E6=88=B7=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=92=A4=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit share_recipe/adopt_recipe 统一显示为"共享配方"。 删除用户不可撤销,回退软删除方案。 Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/main.py | 4 +++- frontend/src/views/AuditLog.vue | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/backend/main.py b/backend/main.py index ea7b826..69d872e 100644 --- a/backend/main.py +++ b/backend/main.py @@ -800,7 +800,9 @@ def create_recipe(recipe: RecipeIn, user=Depends(get_current_user)): for tag in recipe.tags: c.execute("INSERT OR IGNORE INTO tags (name) VALUES (?)", (tag,)) c.execute("INSERT OR IGNORE INTO recipe_tags (recipe_id, tag_name) VALUES (?, ?)", (rid, tag)) - log_audit(conn, user["id"], "create_recipe", "recipe", rid, recipe.name) + # Only log for admin/senior_editor direct adds (share); others wait for adopt + if user["role"] in ("admin", "senior_editor"): + log_audit(conn, user["id"], "share_recipe", "recipe", rid, recipe.name) who = user.get("display_name") or user["username"] if user["role"] == "senior_editor": # Senior editor adds directly — just inform admin diff --git a/frontend/src/views/AuditLog.vue b/frontend/src/views/AuditLog.vue index 1dcd140..a4efced 100644 --- a/frontend/src/views/AuditLog.vue +++ b/frontend/src/views/AuditLog.vue @@ -82,10 +82,10 @@ const selectedUser = ref('') const selectedTarget = ref('') const ACTION_MAP = { - create_recipe: '新增配方', + share_recipe: '共享配方', + adopt_recipe: '共享配方', update_recipe: '编辑配方', delete_recipe: '删除配方', - adopt_recipe: '采纳配方', reject_recipe: '拒绝配方', undo_delete_recipe: '恢复配方', upsert_oil: '编辑精油', @@ -105,8 +105,8 @@ const ACTION_MAP = { } const actionGroups = { - '配方': ['create_recipe', 'update_recipe', 'delete_recipe', 'undo_delete_recipe'], - '审核': ['adopt_recipe', 'reject_recipe'], + '配方': ['share_recipe', 'adopt_recipe', 'update_recipe', 'delete_recipe', 'undo_delete_recipe'], + '审核': ['reject_recipe'], '精油': ['upsert_oil', 'delete_oil', 'undo_delete_oil'], '标签': ['create_tag', 'delete_tag'], '用户': ['create_user', 'update_user', 'delete_user', 'undo_delete_user', 'register'], @@ -153,7 +153,7 @@ function actionColorClass(action) { if (action.includes('create') || action.includes('upsert')) return 'color-create' if (action.includes('update')) return 'color-update' if (action.includes('delete') || action.includes('reject')) return 'color-delete' - if (action.includes('adopt') || action.includes('undo')) return 'color-approve' + if (action.includes('adopt') || action.includes('undo') || action.includes('share')) return 'color-approve' return '' } @@ -179,7 +179,7 @@ function parsedDetail(log) { } function canUndo(log) { - return ['delete_recipe', 'delete_user', 'delete_oil'].includes(log.action) + return ['delete_recipe', 'delete_oil'].includes(log.action) } async function undoAction(log) {