diff --git a/backend/main.py b/backend/main.py index 9bfa9fe..0c79e1b 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1438,23 +1438,38 @@ def get_unmatched_searches(days: int = 7, user=Depends(require_role("admin", "se return [dict(r) for r in rows] +# ── Recipe review history ────────────────────────────── +@app.get("/api/recipe-reviews") +def list_recipe_reviews(user=Depends(require_role("admin"))): + conn = get_db() + rows = conn.execute( + "SELECT a.id, a.action, a.target_name, a.detail, a.created_at, " + "u.display_name, u.username " + "FROM audit_log a LEFT JOIN users u ON a.user_id = u.id " + "WHERE a.action IN ('adopt_recipe', 'reject_recipe') " + "ORDER BY a.id DESC LIMIT 100" + ).fetchall() + conn.close() + return [dict(r) for r in rows] + + # ── Contribution stats ───────────────────────────────── @app.get("/api/me/contribution") def my_contribution(user=Depends(get_current_user)): if not user.get("id"): - return {"shared_count": 0} + return {"adopted_count": 0, "shared_count": 0} conn = get_db() - # Count recipes adopted from this user (tracked in audit_log) - count = conn.execute( + # adopted_count: recipes adopted from this user (owner changed to admin) + adopted = conn.execute( "SELECT COUNT(*) FROM audit_log WHERE action = 'adopt_recipe' AND detail LIKE ?", (f'%"from_user": "{user.get("display_name") or user.get("username")}"%',) ).fetchone()[0] - # Also count recipes still owned by user in public library - own_count = conn.execute( + # pending: recipes still owned by user in public library (not yet adopted) + pending = conn.execute( "SELECT COUNT(*) FROM recipes WHERE owner_id = ?", (user["id"],) ).fetchone()[0] conn.close() - return {"shared_count": count + own_count} + return {"adopted_count": adopted, "shared_count": adopted + pending} # ── Notifications ────────────────────────────────────── diff --git a/frontend/src/components/RecipeDetailOverlay.vue b/frontend/src/components/RecipeDetailOverlay.vue index 09e1720..a959d10 100644 --- a/frontend/src/components/RecipeDetailOverlay.vue +++ b/frontend/src/components/RecipeDetailOverlay.vue @@ -400,6 +400,7 @@ const displayRecipe = computed(() => { }) const canEditThisRecipe = computed(() => { + if (props.isDiary) return false if (authStore.canEdit) return true return false }) diff --git a/frontend/src/components/UserMenu.vue b/frontend/src/components/UserMenu.vue index a20abdd..32e5d81 100644 --- a/frontend/src/components/UserMenu.vue +++ b/frontend/src/components/UserMenu.vue @@ -163,11 +163,7 @@ function handleLogout() { auth.logout() ui.showToast('已退出登录') emit('close') - if (router.currentRoute.value.meta.requiresAuth) { - router.push('/') - } else { - window.location.reload() - } + window.location.href = '/' } onMounted(loadNotifications) diff --git a/frontend/src/views/RecipeManager.vue b/frontend/src/views/RecipeManager.vue index 0b6c0af..0d8d43e 100644 --- a/frontend/src/views/RecipeManager.vue +++ b/frontend/src/views/RecipeManager.vue @@ -7,7 +7,7 @@