fix: 去重只检查目标库,跳过后继续处理下一条
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Failing after 6s
Test / e2e-test (push) Has been skipped
Test / build-check (push) Successful in 4s
PR Preview / test (pull_request) Failing after 5s
PR Preview / deploy-preview (pull_request) Has been skipped
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Failing after 6s
Test / e2e-test (push) Has been skipped
Test / build-check (push) Successful in 4s
PR Preview / test (pull_request) Failing after 5s
PR Preview / deploy-preview (pull_request) Has been skipped
- checkDupName 接受 target 参数,只查目标库(公共/个人) - 提取 skipCurrentParsed/dedupOrSkip 避免代码重复 - 共享到公共库检查公共库,保存到个人检查个人 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -987,18 +987,18 @@ function toggleFormTag(tag) {
|
||||
* Same name + different content → show diff, prompt rename, loop until unique.
|
||||
* Returns final name or false if cancelled.
|
||||
*/
|
||||
async function checkDupName(name, ings) {
|
||||
async function checkDupName(name, ings, target = 'diary') {
|
||||
let currentName = name
|
||||
while (true) {
|
||||
const pubDup = recipeStore.recipes.find(r => r.name === currentName)
|
||||
const diaryDup = diaryStore.userDiary.find(d => d.name === currentName)
|
||||
const dup = pubDup || diaryDup
|
||||
const dup = target === 'public'
|
||||
? recipeStore.recipes.find(r => r.name === currentName)
|
||||
: diaryStore.userDiary.find(d => d.name === currentName)
|
||||
if (!dup) return currentName
|
||||
|
||||
const dupIngs = (dup.ingredients || []).filter(i => i.oil).sort((a, b) => a.oil.localeCompare(b.oil))
|
||||
const myIngs = ings.filter(i => i.oil).sort((a, b) => a.oil.localeCompare(b.oil))
|
||||
const identical = dupIngs.length === myIngs.length && dupIngs.every((d, i) => d.oil === myIngs[i].oil && d.drops === myIngs[i].drops)
|
||||
const where = pubDup ? '公共配方库' : '我的配方'
|
||||
const where = target === 'public' ? '公共配方库' : '我的配方'
|
||||
|
||||
if (identical) {
|
||||
ui.showToast(`${where}中已有一模一样的配方「${currentName}」`)
|
||||
@@ -1046,45 +1046,6 @@ async function saveCurrentRecipe() {
|
||||
tags: formTags.value,
|
||||
}
|
||||
|
||||
// Dedup check for new recipes (not editing)
|
||||
if (!editingRecipe.value) {
|
||||
const result = await checkDupName(diaryPayload.name, cleanIngs)
|
||||
if (result === false) {
|
||||
// Skipped — but if in multi-recipe queue, load next
|
||||
if (parsedCurrentIndex.value >= 0) {
|
||||
const skipIdx = parsedCurrentIndex.value
|
||||
// Prevent syncFormToParsed from overwriting next recipe
|
||||
parsedCurrentIndex.value = -1
|
||||
parsedRecipes.value.splice(skipIdx, 1)
|
||||
if (parsedRecipes.value.length > 0) {
|
||||
const next = Math.min(skipIdx, parsedRecipes.value.length - 1)
|
||||
parsedCurrentIndex.value = next
|
||||
formName.value = parsedRecipes.value[next].name
|
||||
const cocoIng = parsedRecipes.value[next].ingredients.find(i => i.oil === '椰子油')
|
||||
const eoIngs = parsedRecipes.value[next].ingredients.filter(i => i.oil !== '椰子油')
|
||||
formIngredients.value = eoIngs.length > 0
|
||||
? eoIngs.map(i => ({ ...i, _search: i.oil, _open: false }))
|
||||
: [{ oil: '', drops: 1, _search: '', _open: false }]
|
||||
if (cocoIng) {
|
||||
formCocoRow.value = { oil: '椰子油', drops: cocoIng.drops, _search: '椰子油', _open: false }
|
||||
formVolume.value = 'single'
|
||||
} else {
|
||||
formCocoRow.value = null
|
||||
formVolume.value = ''
|
||||
}
|
||||
ui.showToast('已跳过,请处理下一条')
|
||||
} else {
|
||||
closeOverlay()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (result !== diaryPayload.name) {
|
||||
formName.value = result
|
||||
diaryPayload.name = result
|
||||
}
|
||||
}
|
||||
|
||||
if (editingRecipe.value && editingRecipe.value._diary_id) {
|
||||
// Editing an existing diary recipe
|
||||
try {
|
||||
@@ -1126,14 +1087,15 @@ async function saveCurrentRecipe() {
|
||||
if (auth.canManage) {
|
||||
const toPublic = await showConfirm('保存到哪里?', { okText: '公共配方库', cancelText: '个人配方' })
|
||||
if (toPublic) {
|
||||
const finalName = await dedupOrSkip(diaryPayload.name, cleanIngs, 'public')
|
||||
if (!finalName) return
|
||||
try {
|
||||
const pubPayload = {
|
||||
name: formName.value.trim(),
|
||||
await recipeStore.saveRecipe({
|
||||
name: finalName,
|
||||
ingredients: cleanIngs.map(i => ({ oil_name: i.oil, drops: i.drops })),
|
||||
note: formNote.value,
|
||||
tags: formTags.value,
|
||||
}
|
||||
await recipeStore.saveRecipe(pubPayload)
|
||||
})
|
||||
ui.showToast('已添加到公共配方库')
|
||||
if (!loadNextParsed()) closeOverlay()
|
||||
} catch (e) {
|
||||
@@ -1142,6 +1104,10 @@ async function saveCurrentRecipe() {
|
||||
return
|
||||
}
|
||||
}
|
||||
const finalName = await dedupOrSkip(diaryPayload.name, cleanIngs, 'diary')
|
||||
if (!finalName) return
|
||||
diaryPayload.name = finalName
|
||||
formName.value = finalName
|
||||
try {
|
||||
await diaryStore.createDiary(diaryPayload)
|
||||
ui.showToast('已添加到我的配方')
|
||||
@@ -1180,7 +1146,7 @@ async function saveAllParsed() {
|
||||
const r = parsedRecipes.value[i]
|
||||
if (!r.name.trim() || r.ingredients.length === 0) continue
|
||||
const ings = r.ingredients.map(ing => ({ oil: ing.oil, drops: ing.drops }))
|
||||
const finalName = await checkDupName(r.name.trim(), ings)
|
||||
const finalName = await checkDupName(r.name.trim(), ings, toPublic ? 'public' : 'diary')
|
||||
if (finalName === false) { skipped++; continue }
|
||||
try {
|
||||
if (toPublic) {
|
||||
@@ -1202,6 +1168,48 @@ async function saveAllParsed() {
|
||||
closeOverlay()
|
||||
}
|
||||
|
||||
/** Skip current parsed recipe and load next, or close if none left. */
|
||||
function skipCurrentParsed() {
|
||||
if (parsedCurrentIndex.value < 0) return
|
||||
const skipIdx = parsedCurrentIndex.value
|
||||
parsedCurrentIndex.value = -1
|
||||
parsedRecipes.value.splice(skipIdx, 1)
|
||||
if (parsedRecipes.value.length > 0) {
|
||||
const next = Math.min(skipIdx, parsedRecipes.value.length - 1)
|
||||
parsedCurrentIndex.value = next
|
||||
const r = parsedRecipes.value[next]
|
||||
formName.value = r.name
|
||||
const cocoIng = r.ingredients.find(i => i.oil === '椰子油')
|
||||
const eoIngs = r.ingredients.filter(i => i.oil !== '椰子油')
|
||||
formIngredients.value = eoIngs.length > 0
|
||||
? eoIngs.map(i => ({ ...i, _search: i.oil, _open: false }))
|
||||
: [{ oil: '', drops: 1, _search: '', _open: false }]
|
||||
if (cocoIng) {
|
||||
formCocoRow.value = { oil: '椰子油', drops: cocoIng.drops, _search: '椰子油', _open: false }
|
||||
formVolume.value = 'single'
|
||||
} else {
|
||||
formCocoRow.value = null
|
||||
formVolume.value = ''
|
||||
}
|
||||
ui.showToast('已跳过,请处理下一条')
|
||||
} else {
|
||||
closeOverlay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run dedup check for saveCurrentRecipe. Returns final name or null if should stop.
|
||||
*/
|
||||
async function dedupOrSkip(name, ings, target) {
|
||||
if (editingRecipe.value) return name
|
||||
const result = await checkDupName(name, ings, target)
|
||||
if (result === false) {
|
||||
if (parsedCurrentIndex.value >= 0) skipCurrentParsed()
|
||||
return null
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** After saving, mark current as done and load next. Returns true if there's a next one. */
|
||||
function loadNextParsed() {
|
||||
if (parsedCurrentIndex.value < 0 || parsedRecipes.value.length === 0) return false
|
||||
@@ -1478,7 +1486,7 @@ async function recommendApprove(recipe) {
|
||||
|
||||
async function shareDiaryToPublic(diary) {
|
||||
const ings = (diary.ingredients || []).map(i => ({ oil: i.oil, drops: i.drops }))
|
||||
const result = await checkDupName(diary.name, ings)
|
||||
const result = await checkDupName(diary.name, ings, 'public')
|
||||
if (result === false) return
|
||||
if (result !== diary.name) diary = { ...diary, name: result }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user