/** * 将管理端保存的营养成分默认值 JSON 合并进 NUTRITION 元素 config(与 Web nutritionManualEntry 字段一致)。 */ 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 }; for (const [k, val] of Object.entries(manual)) { const v = String(val ?? "").trim(); if (k === "calories") { if (v) out.calories = v; continue; } if (k === "servingsPerContainer") { out.servingsPerContainer = v; continue; } if (k === "servingSize") { out.servingSize = v; continue; } if (k.startsWith("extra:") && k.endsWith(":value")) { const id = k.slice("extra:".length, -":value".length); const arr = Array.isArray(out.extraNutrients) ? ([...(out.extraNutrients as Record[])]) : []; const idx = arr.findIndex((row) => String((row as any).id ?? "") === id); if (idx >= 0) { arr[idx] = { ...arr[idx], value: v }; } out.extraNutrients = arr; continue; } const fr = Array.isArray(out.fixedNutrients) ? ([...(out.fixedNutrients as Record[])]) : []; const idx = fr.findIndex((row) => String((row as any).key ?? "").trim() === k); if (idx >= 0) { fr[idx] = { ...fr[idx], value: v }; } else { fr.push({ key: k, label: k, value: v, unit: "" }); } out.fixedNutrients = fr; } return out; }