feat: 新功能改进 #20

Merged
hera merged 57 commits from feat/next-improvements into main 2026-04-10 20:30:37 +00:00
2 changed files with 25 additions and 10 deletions
Showing only changes of commit b6f8df89ed - Show all commits

View File

@@ -1522,27 +1522,29 @@ def my_contribution(user=Depends(get_current_user)):
return {"adopted_count": 0, "shared_count": 0, "adopted_names": [], "pending_names": []}
conn = get_db()
display = user.get("display_name") or user.get("username")
# adopted: recipes adopted from this user
# adopted: unique recipe names adopted from this user
adopted_rows = conn.execute(
"SELECT target_name FROM audit_log WHERE action = 'adopt_recipe' AND detail LIKE ?",
"SELECT DISTINCT target_name FROM audit_log WHERE action = 'adopt_recipe' AND detail LIKE ?",
(f'%"from_user": "{display}"%',)
).fetchall()
adopted_names = [r["target_name"] for r in adopted_rows if r["target_name"]]
adopted_names = list(set(r["target_name"] for r in adopted_rows if r["target_name"]))
# pending: recipes still owned by user in public library
pending_rows = conn.execute(
"SELECT name FROM recipes WHERE owner_id = ?", (user["id"],)
).fetchall()
pending_names = [r["name"] for r in pending_rows]
# rejected: count recipes rejected from this user (they were deleted but logged)
rejected_count = conn.execute(
"SELECT COUNT(*) FROM audit_log WHERE action = 'reject_recipe' AND detail LIKE ?",
# rejected: unique recipe names rejected (not already adopted or pending)
rejected_rows = conn.execute(
"SELECT DISTINCT target_name FROM audit_log WHERE action = 'reject_recipe' AND detail LIKE ?",
(f'%"from_user": "{display}"%',)
).fetchone()[0]
).fetchall()
rejected_names = set(r["target_name"] for r in rejected_rows if r["target_name"])
# Unique names across all: same recipe rejected then re-submitted counts as 1
all_names = set(adopted_names) | set(pending_names) | rejected_names
conn.close()
total = len(adopted_names) + len(pending_names) + rejected_count
return {
"adopted_count": len(adopted_names),
"shared_count": total,
"shared_count": len(all_names),
"adopted_names": adopted_names,
"pending_names": pending_names,
}

View File

@@ -1181,8 +1181,21 @@ function openRecipeDetail(recipe) {
}
function getDiaryShareStatus(d) {
if (sharedCount.value.adoptedNames.includes(d.name)) return 'shared'
// Check pending first (exact name match in public library owned by user)
if (sharedCount.value.pendingNames.includes(d.name)) return 'pending'
// Check adopted — but if diary content was modified, allow re-sharing
if (sharedCount.value.adoptedNames.includes(d.name)) {
// Compare with the public recipe to see if content changed
const pub = recipeStore.recipes.find(r => r.name === d.name)
if (pub) {
const dIngs = (d.ingredients || []).filter(i => i.oil).sort((a, b) => a.oil.localeCompare(b.oil))
const pIngs = (pub.ingredients || []).filter(i => i.oil).sort((a, b) => a.oil.localeCompare(b.oil))
const same = dIngs.length === pIngs.length && dIngs.every((ing, i) => ing.oil === pIngs[i].oil && ing.drops === pIngs[i].drops)
if (same) return 'shared'
}
// Content changed or public recipe not found — can re-share
return null
}
return null
}