diff --git a/frontend/src/components/RecipeDetailOverlay.vue b/frontend/src/components/RecipeDetailOverlay.vue index a80735d..f83ed52 100644 --- a/frontend/src/components/RecipeDetailOverlay.vue +++ b/frontend/src/components/RecipeDetailOverlay.vue @@ -621,15 +621,10 @@ async function saveToDiary() { } const trimmed = name.trim() const dupDiary = diaryStore.userDiary.some(d => d.name === trimmed) - const dupPublic = recipesStore.recipes.some(r => r.name === trimmed) if (dupDiary) { ui.showToast('我的配方中已有同名配方「' + trimmed + '」') return } - if (dupPublic) { - ui.showToast('公共配方库中已有同名配方「' + trimmed + '」') - return - } try { const payload = { name: name.trim(), diff --git a/frontend/src/views/RecipeManager.vue b/frontend/src/views/RecipeManager.vue index 64a3ce9..2c96e68 100644 --- a/frontend/src/views/RecipeManager.vue +++ b/frontend/src/views/RecipeManager.vue @@ -1210,7 +1210,46 @@ async function removeRecipe(recipe) { } } +function recipesIdentical(a, b) { + if ((a.ingredients || []).length !== (b.ingredients || []).length) return false + const aIngs = [...a.ingredients].sort((x, y) => x.oil.localeCompare(y.oil)) + const bIngs = [...b.ingredients].sort((x, y) => x.oil.localeCompare(y.oil)) + return aIngs.every((ing, i) => ing.oil === bIngs[i].oil && ing.drops === bIngs[i].drops) +} + +function formatIngsCompare(ings) { + return (ings || []).map(i => `${i.oil} ${i.drops}滴`).join('、') +} + async function approveRecipe(recipe) { + const dup = recipeStore.recipes.find(r => r.name === recipe.name && r._id !== recipe._id) + if (dup) { + if (recipesIdentical(recipe, dup)) { + ui.showToast('公共配方库中已有一模一样的配方「' + recipe.name + '」,无需重复采纳') + return + } + // Different content, show comparison + const msg = `公共配方库中已有同名配方「${recipe.name}」但内容不同:\n\n` + + `已有:${formatIngsCompare(dup.ingredients)}\n` + + `新的:${formatIngsCompare(recipe.ingredients)}\n\n` + + `点击"采纳"直接采纳,或"改名"修改新配方名称后采纳` + const action = await showConfirm(msg, { okText: '采纳', cancelText: '改名' }) + if (!action) { + // User wants to rename + const newName = await showPrompt('请输入新名称:', recipe.name) + if (!newName || !newName.trim()) return + try { + await api(`/api/recipes/${recipe._id}`, { + method: 'PUT', + body: JSON.stringify({ name: newName.trim() }), + }) + recipe.name = newName.trim() + } catch { + ui.showToast('改名失败') + return + } + } + } try { const res = await api('/api/recipes/' + recipe._id + '/adopt', { method: 'POST' }) if (res.ok) {