fix: 配方保存时持久化volume字段,套装对比页复用容量显示逻辑
Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Successful in 6s
Test / build-check (push) Successful in 4s
PR Preview / test (pull_request) Successful in 6s
PR Preview / deploy-preview (pull_request) Successful in 15s
Test / e2e-test (push) Failing after 7m5s

saveRecipe payload 漏传 selectedVolume 导致编辑器选择的容量从未写入数据库;
套装方案对比页改用与 RecipeCard 一致的 volumeLabel 计算逻辑。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-14 10:42:26 +00:00
parent 616e51f36c
commit f03bf699e5
2 changed files with 30 additions and 2 deletions

View File

@@ -1010,6 +1010,7 @@ async function saveRecipe() {
note: editNote.value.trim(), note: editNote.value.trim(),
tags: editTags.value, tags: editTags.value,
ingredients: allIngs, ingredients: allIngs,
volume: selectedVolume.value || '',
} }
await recipesStore.saveRecipe(payload) await recipesStore.saveRecipe(payload)
// Reload recipes so the data is fresh when re-opened // Reload recipes so the data is fresh when re-opened

View File

@@ -48,7 +48,7 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="r in activeKitData.recipes" :key="r._id"> <tr v-for="r in activeKitData.recipes" :key="r._id">
<td class="td-name">{{ r.name }} <span class="td-volume">{{ r.volume || '单次' }}</span></td> <td class="td-name">{{ r.name }} <span v-if="volumeLabel(r)" class="td-volume">{{ volumeLabel(r) }}</span></td>
<td class="td-times">{{ calcMaxTimes(r) }}</td> <td class="td-times">{{ calcMaxTimes(r) }}</td>
<td class="td-cost">{{ fmtPrice(r.kitCost) }}</td> <td class="td-cost">{{ fmtPrice(r.kitCost) }}</td>
<td class="td-cost original">{{ fmtPrice(r.originalCost) }}</td> <td class="td-cost original">{{ fmtPrice(r.originalCost) }}</td>
@@ -85,7 +85,7 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="row in crossComparison" :key="row.id"> <tr v-for="row in crossComparison" :key="row.id">
<td class="td-name">{{ row.name }} <span class="td-volume">{{ row.volume || '单次' }}</span></td> <td class="td-name">{{ row.name }} <span v-if="volumeLabel(row)" class="td-volume">{{ volumeLabel(row) }}</span></td>
<td v-for="ka in kitAnalysis" :key="ka.id" :class="row.costs[ka.id] != null ? 'td-kit-available' : 'td-kit-na'"> <td v-for="ka in kitAnalysis" :key="ka.id" :class="row.costs[ka.id] != null ? 'td-kit-available' : 'td-kit-na'">
<template v-if="row.costs[ka.id] != null">{{ fmtPrice(row.costs[ka.id]) }}</template> <template v-if="row.costs[ka.id] != null">{{ fmtPrice(row.costs[ka.id]) }}</template>
<template v-else><span class="na"></span></template> <template v-else><span class="na"></span></template>
@@ -120,6 +120,33 @@ const sellingPrices = ref({})
const activeKitData = computed(() => kitAnalysis.value.find(k => k.id === activeKit.value)) const activeKitData = computed(() => kitAnalysis.value.find(k => k.id === activeKit.value))
function volumeLabel(recipe) {
const vol = recipe.volume
if (vol) {
if (vol === 'single') return '单次'
if (vol === 'custom') return ''
if (/^\d+$/.test(vol)) return `${vol}ml`
return vol
}
const ings = recipe.ingredients || []
const coco = ings.find(i => i.oil === '椰子油')
if (coco && coco.drops) {
const totalDrops = ings.reduce((s, i) => s + (i.drops || 0), 0)
const ml = totalDrops / 18.6
if (ml <= 2) return '单次'
return `${Math.round(ml)}ml`
}
let totalMl = 0
let hasProduct = false
for (const ing of ings) {
if (!oils.isPortionUnit(ing.oil)) continue
hasProduct = true
totalMl += ing.drops || 0
}
if (hasProduct && totalMl > 0) return `${Math.round(totalMl)}ml`
return ''
}
onMounted(async () => { onMounted(async () => {
if (!auth.isBusiness && !auth.isAdmin) { if (!auth.isBusiness && !auth.isAdmin) {
router.replace('/projects') router.replace('/projects')