fix: 贡献统计去重 + 已共享内容变更可重新共享
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Successful in 4s
Test / build-check (push) Successful in 3s
PR Preview / test (pull_request) Successful in 4s
PR Preview / deploy-preview (pull_request) Successful in 16s
Test / e2e-test (push) Failing after 55s
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Successful in 4s
Test / build-check (push) Successful in 3s
PR Preview / test (pull_request) Successful in 4s
PR Preview / deploy-preview (pull_request) Successful in 16s
Test / e2e-test (push) Failing after 55s
贡献统计: - 按配方名去重(拒绝后重新申请不重复计数) - 已采纳+待审核+被拒绝的唯一配方名总数 已共享状态: - 已共享配方修改内容后,对比公共库版本 - 内容不同时"已共享"消失,可重新共享 - 内容相同时保持"已共享" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1522,27 +1522,29 @@ def my_contribution(user=Depends(get_current_user)):
|
|||||||
return {"adopted_count": 0, "shared_count": 0, "adopted_names": [], "pending_names": []}
|
return {"adopted_count": 0, "shared_count": 0, "adopted_names": [], "pending_names": []}
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
display = user.get("display_name") or user.get("username")
|
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(
|
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}"%',)
|
(f'%"from_user": "{display}"%',)
|
||||||
).fetchall()
|
).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: recipes still owned by user in public library
|
||||||
pending_rows = conn.execute(
|
pending_rows = conn.execute(
|
||||||
"SELECT name FROM recipes WHERE owner_id = ?", (user["id"],)
|
"SELECT name FROM recipes WHERE owner_id = ?", (user["id"],)
|
||||||
).fetchall()
|
).fetchall()
|
||||||
pending_names = [r["name"] for r in pending_rows]
|
pending_names = [r["name"] for r in pending_rows]
|
||||||
# rejected: count recipes rejected from this user (they were deleted but logged)
|
# rejected: unique recipe names rejected (not already adopted or pending)
|
||||||
rejected_count = conn.execute(
|
rejected_rows = conn.execute(
|
||||||
"SELECT COUNT(*) FROM audit_log WHERE action = 'reject_recipe' AND detail LIKE ?",
|
"SELECT DISTINCT target_name FROM audit_log WHERE action = 'reject_recipe' AND detail LIKE ?",
|
||||||
(f'%"from_user": "{display}"%',)
|
(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()
|
conn.close()
|
||||||
total = len(adopted_names) + len(pending_names) + rejected_count
|
|
||||||
return {
|
return {
|
||||||
"adopted_count": len(adopted_names),
|
"adopted_count": len(adopted_names),
|
||||||
"shared_count": total,
|
"shared_count": len(all_names),
|
||||||
"adopted_names": adopted_names,
|
"adopted_names": adopted_names,
|
||||||
"pending_names": pending_names,
|
"pending_names": pending_names,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1181,8 +1181,21 @@ function openRecipeDetail(recipe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDiaryShareStatus(d) {
|
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'
|
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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user