/** * 将管理端保存的营养成分默认值 JSON 合并进 NUTRITION 元素 config(与 Web nutritionManualEntry 字段一致)。 * `<` 前缀由模板 config 决定,录入 JSON 不包含 LessThan 字段。 */ import { NUTRITION_FACTS_LAYOUT_ROWS } from '../nutritionFactsLayout' function fixedLabelForKey(key: string): string { const hit = NUTRITION_FACTS_LAYOUT_ROWS.find((x) => x.key === key) return hit?.label ?? key } function pickManual(manual: Record, subKey: string): string { return String(manual[subKey] ?? '').trim() } export function applyNutritionDefaultJsonToConfig( baseCfg: Record, jsonStr: string, ): Record { const t = String(jsonStr ?? '').trim() if (!t.startsWith('{')) return baseCfg let manual: Record = {} try { manual = JSON.parse(t) as Record } catch { return baseCfg } const out: Record = { ...baseCfg } const baseFixed = Array.isArray(baseCfg.fixedNutrients) ? (baseCfg.fixedNutrients as Record[]) : [] const cal = pickManual(manual, 'calories') if (cal) out.calories = cal else { delete out.calories delete out.Calories } out.servingsPerContainer = pickManual(manual, 'servingsPerContainer') out.servingSize = pickManual(manual, 'servingSize') const keysInOrder = [...NUTRITION_FACTS_LAYOUT_ROWS.map((r) => r.key)] for (const row of baseFixed) { const key = String(row.key ?? '').trim() if (key && !keysInOrder.includes(key)) keysInOrder.push(key) } const fixedArr: Record[] = [] for (const key of keysInOrder) { const baseRow = baseFixed.find((r) => String(r.key ?? '').trim() === key) const layout = NUTRITION_FACTS_LAYOUT_ROWS.find((r) => r.key === key) const v = pickManual(manual, key) const pct = pickManual(manual, `${key}Percent`) const lessThan = Boolean(baseRow?.lessThan ?? baseCfg[`${key}LessThan`]) const label = String(baseRow?.label ?? layout?.label ?? fixedLabelForKey(key)) fixedArr.push({ key, label, value: v, unit: '', dailyValuePercent: pct, lessThan, }) if (v) out[key] = v else delete out[key] delete out[`${key}Unit`] out[`${key}Percent`] = pct out[`${key}LessThan`] = lessThan } out.fixedNutrients = fixedArr const newExtras: Array<{ id: string; name: string; value: string; unit: string }> = [] for (const k of Object.keys(manual)) { if (!k.startsWith('extra:') || !k.endsWith(':value')) continue const id = k.slice('extra:'.length, -':value'.length) newExtras.push({ id, name: String( (Array.isArray(out.extraNutrients) ? (out.extraNutrients as Record[]).find((row) => String(row.id ?? '') === id) : undefined)?.name ?? 'Other', ), value: pickManual(manual, k), unit: '', }) out[`extra:${id}:percent`] = pickManual(manual, `extra:${id}:percent`) out[`extra:${id}:lessThan`] = Boolean(baseCfg[`extra:${id}:lessThan`]) } if (newExtras.length > 0) out.extraNutrients = newExtras delete out.ingredientsText delete out.IngredientsText return out }