From c090e5f3d62eb156e7f1129fd3e0ac684b2f978e Mon Sep 17 00:00:00 2001 From: Hera Zhao Date: Mon, 13 Apr 2026 23:55:50 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=85=8D=E6=96=B9=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=AE=B9=E9=87=8F=E5=92=8C=E5=8F=AF=E5=81=9A=E6=AC=A1=E6=95=B0?= =?UTF-8?q?=EF=BC=9B=E5=A5=97=E8=A3=85=E6=88=90=E6=9C=AC=E4=B8=8D=E8=B6=85?= =?UTF-8?q?=E8=BF=87=E5=8D=95=E4=B9=B0=E4=BB=B7=EF=BC=88=E9=85=8D=E4=BB=B6?= =?UTF-8?q?=E8=A7=86=E4=B8=BA=E8=B5=A0=E5=93=81=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 每个配方名后显示容量(单次/5ml/10ml等) - 新增可做次数列(按最先用完的精油计算) - 套装成本分摊使用 min(套装价, 油瓶总价),避免含配件的套装算出比单买贵 Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/composables/useKitCost.js | 7 +++++-- frontend/src/views/KitExport.vue | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/frontend/src/composables/useKitCost.js b/frontend/src/composables/useKitCost.js index adfc194..3ddf351 100644 --- a/frontend/src/composables/useKitCost.js +++ b/frontend/src/composables/useKitCost.js @@ -35,12 +35,14 @@ export function useKitCost() { } if (totalBottlePrice === 0) return {} - // Proportional allocation + // Proportional allocation — kit accessories treated as freebies, + // so oil cost = min(kit price, sum of bottle prices) + const effectivePrice = Math.min(kit.price, totalBottlePrice) const perDrop = {} for (const name of resolved) { const meta = oils.oilsMeta[name] const bp = oilBottlePrices[name] - const kitCostForOil = (bp / totalBottlePrice) * kit.price + const kitCostForOil = (bp / totalBottlePrice) * effectivePrice const drops = meta ? meta.dropCount : 1 perDrop[name] = drops > 0 ? kitCostForOil / drops : 0 } @@ -124,6 +126,7 @@ export function useKitCost() { id, name: recipe.name, tags: recipe.tags, + volume: recipe.volume, ingredients: recipe.ingredients, originalCost: recipe.originalCost, costs, diff --git a/frontend/src/views/KitExport.vue b/frontend/src/views/KitExport.vue index e65b0f1..9aebec9 100644 --- a/frontend/src/views/KitExport.vue +++ b/frontend/src/views/KitExport.vue @@ -39,6 +39,7 @@ 配方名 + 可做次数 套装成本 原价成本 售价 @@ -47,7 +48,8 @@ - {{ r.name }} + {{ r.name }} {{ r.volume || '单次' }} + {{ calcMaxTimes(r) }} {{ fmtPrice(r.kitCost) }} {{ fmtPrice(r.originalCost) }} @@ -83,7 +85,7 @@ - {{ row.name }} + {{ row.name }} {{ row.volume || '单次' }} @@ -142,6 +144,20 @@ function saveSellingPrices() { localStorage.setItem(STORAGE_KEY, JSON.stringify(sellingPrices.value)) } +// Calculate how many times a recipe can be made with the kit (limited by the oil that runs out first) +function calcMaxTimes(recipe) { + const ings = (recipe.ingredients || []).filter(i => i.oil && i.oil !== '椰子油' && i.drops > 0) + if (!ings.length) return '—' + let minTimes = Infinity + for (const ing of ings) { + const meta = oils.oilsMeta[ing.oil] + if (!meta || !meta.dropCount) return '—' + const times = Math.floor(meta.dropCount / ing.drops) + if (times < minTimes) minTimes = times + } + return minTimes === Infinity ? '—' : minTimes + '次' +} + function getSellingPrice(recipeId) { return sellingPrices.value[recipeId] ?? 0 } @@ -394,6 +410,8 @@ async function exportExcel(mode) { .td-cost.original { color: #999; font-weight: 400; } .td-profit { font-weight: 600; color: #4a9d7e; } .td-profit.negative { color: #ef5350; } +.td-volume { font-size: 10px; color: #b0aab5; margin-left: 4px; } +.td-times { color: #6b6375; font-size: 12px; } .td-kit-available { font-weight: 500; color: #4a9d7e; background: #f0faf5; } .td-kit-na { background: #fafafa; } .na { color: #ddd; }