From 4696ece13904dafa4a5e9b28b628847b04c252ea Mon Sep 17 00:00:00 2001 From: Hera Zhao Date: Thu, 9 Apr 2026 21:29:28 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9D=83=E9=99=90=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E3=80=81=E6=90=9C=E7=B4=A2=E6=94=B9=E8=BF=9B=E3=80=81=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E5=88=87=E6=8D=A2=E3=80=81=E9=80=9A=E7=9F=A5badge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 权限: - viewer 不能编辑公共配方(前端+后端双重限制) - viewer 管理配方页只显示"我的配方" - 取消 token 链接登录,改为自注册+管理员分配角色 - 用户管理页去掉创建用户和复制链接,禁止设管理员 - 修复改权限 API 路径错误 搜索: - 模糊匹配+同义词扩展(37组),精确/相似分层 - 精确匹配不搜精油成分(避免"西班牙牛至"污染) - 所有搜索结果底部加"通知编辑添加"按钮 UI: - 顶部 tab 栏按用户角色显示,切换时居中滚动 - 左右滑动按 visibleTabs 顺序切换 tab - 用户名旁红色通知数 badge Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/main.py | 9 +- frontend/src/App.vue | 124 +++++++++++++----- frontend/src/assets/styles.css | 18 +++ .../src/components/RecipeDetailOverlay.vue | 1 - frontend/src/stores/auth.js | 12 +- frontend/src/views/RecipeManager.vue | 64 ++++----- frontend/src/views/RecipeSearch.vue | 6 +- frontend/src/views/UserManagement.vue | 95 +------------- 8 files changed, 154 insertions(+), 175 deletions(-) diff --git a/backend/main.py b/backend/main.py index 09e827b..d05dbe8 100644 --- a/backend/main.py +++ b/backend/main.py @@ -781,15 +781,15 @@ def create_recipe(recipe: RecipeIn, user=Depends(get_current_user)): def _check_recipe_permission(conn, recipe_id, user): - """Check if user can modify this recipe.""" + """Check if user can modify this recipe. Requires editor+ role.""" row = conn.execute("SELECT owner_id, name FROM recipes WHERE id = ?", (recipe_id,)).fetchone() if not row: raise HTTPException(404, "Recipe not found") if user["role"] in ("admin", "senior_editor"): return row - if row["owner_id"] == user.get("id"): + if user["role"] in ("editor",) and row["owner_id"] == user.get("id"): return row - raise HTTPException(403, "只能修改自己创建的配方") + raise HTTPException(403, "权限不足") @app.put("/api/recipes/{recipe_id}") @@ -974,6 +974,9 @@ def delete_user(user_id: int, user=Depends(require_role("admin"))): def update_user(user_id: int, body: UserUpdate, user=Depends(require_role("admin"))): conn = get_db() if body.role is not None: + if body.role == "admin": + conn.close() + raise HTTPException(403, "不能将用户设为管理员") conn.execute("UPDATE users SET role = ? WHERE id = ?", (body.role, user_id)) if body.display_name is not None: conn.execute("UPDATE users SET display_name = ? WHERE id = ?", (body.display_name, user_id)) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 593f672..0d23ac5 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -15,6 +15,7 @@