diff --git a/web-admin/nutrition/din-ingredient.html b/web-admin/nutrition/din-ingredient.html index 43eb59f..a3ae714 100644 --- a/web-admin/nutrition/din-ingredient.html +++ b/web-admin/nutrition/din-ingredient.html @@ -451,6 +451,10 @@ const FOODS = [ {type:'编辑',title:'调整净菜类型',time:'2026-03-15 10:42',user:'王秀兰',role:'营养师',dept:'营养管理部',summary:'新增「免淘米」净菜规格,出净率 95%。',changes:[{field:'净菜类型',old:'1 项(普洗组)',new:'2 项(普洗组/免淘米)'}]}, {type:'价格调整',title:'更新基础定价',time:'2026-06-05 16:30',user:'张明',role:'采购员',dept:'采购部',summary:'根据 6 月市场行情调整粳米基础定价。',changes:[{field:'基础定价',old:'3.2 元/100g',new:'3.5 元/100g'}]}, {type:'编辑',title:'修订色泽描述',time:'2026-07-21 11:05',user:'李建国',role:'营养师',dept:'营养管理部',summary:'色泽描述语义化,补充感官评级。',changes:[{field:'色泽描述',old:'乳白色,半透明',new:'乳白色,半透明,颗粒饱满'},{field:'感官评级',old:'—',new:'优'}]} + ], + priceHistory:[ + {price:'3.5',time:'2026-06-05 16:30',method:'手工录入',prevPrice:'3.2',operator:'张明'}, + {price:'3.2',time:'2026-03-20 10:00',method:'食材验收价',prevPrice:'3.0',operator:'王芳'} ]}, {name:'猪里脊肉',code:'0201001',alias:'里脊',firstClass:'畜禽肉类',secondClass:'猪肉',icon:'🥩',edible:'100',waterRate:'71.4',dataSource:0,basePrice:'18.8',vegTypes:[ {groupId:'g1',alias:'里脊肉丝',specAlias:'细丝',yieldRate:'92',edibleRate:'100',cutSpec:{shape:'丝',length:10,width:1,height:1,technique:'平刀'}}, @@ -474,6 +478,11 @@ const FOODS = [ {type:'编辑',title:'修正嘌呤数据',time:'2026-05-18 13:20',user:'王秀兰',role:'营养师',dept:'营养管理部',summary:'对齐《中国食物成分表》标准,修正嘌呤相关指标。',changes:[{field:'总嘌呤',old:'118.5 mg',new:'132.6 mg'},{field:'次黄嘌呤',old:'42.1 mg',new:'51.2 mg'}]}, {type:'价格调整',title:'更新基础定价',time:'2026-07-09 17:00',user:'张明',role:'采购员',dept:'采购部',summary:'夏季猪肉行情稳定,微调定价。',changes:[{field:'基础定价',old:'19.2 元/100g',new:'18.8 元/100g'}]}, {type:'编辑',title:'调整慎食人群说明',time:'2026-08-01 10:15',user:'李建国',role:'营养师',dept:'营养管理部',summary:'细化肾病人群慎食提示。',changes:[{field:'人群备注',old:'肾病患者慎食',new:'肾病人群需控制蛋白质摄入'}]} + ], + priceHistory:[ + {price:'18.8',time:'2026-07-09 17:00',method:'手工录入',prevPrice:'19.2',operator:'张明'}, + {price:'19.2',time:'2026-05-30 15:20',method:'食材验收价',prevPrice:'18.8',operator:'王芳'}, + {price:'18.8',time:'2026-04-02 09:10',method:'手工录入',prevPrice:'16.5',operator:'张明'} ]}, {name:'菠菜',code:'0701001',alias:'菠菜',firstClass:'蔬菜类',secondClass:'叶菜类',icon:'🥬',edible:'89',waterRate:'91.2',dataSource:0,basePrice:'4.2',vegTypes:[], nutri:{calorie:24,protein:2.6,fat:0.3,carbohydrate:3.1,dietary_fiber:1.7, @@ -490,6 +499,10 @@ const FOODS = [ {type:'编辑',title:'完善叶酸数据',time:'2026-03-02 14:30',user:'李建国',role:'营养师',dept:'营养管理部',summary:'对齐最新检测数据,叶酸含量上调。',changes:[{field:'叶酸',old:'87 μg',new:'110 μg'}]}, {type:'价格调整',title:'更新基础定价',time:'2026-05-20 11:00',user:'张明',role:'采购员',dept:'采购部',summary:'夏季本地菠菜集中上市,定价下调。',changes:[{field:'基础定价',old:'5.5 元/100g',new:'4.2 元/100g'}]}, {type:'编辑',title:'调整慎食提示',time:'2026-06-12 09:40',user:'王秀兰',role:'营养师',dept:'营养管理部',summary:'明确草酸含量高的人群风险提示。',changes:[{field:'人群备注',old:'—',new:'肾结石人群慎食,草酸含量高'}]} + ], + priceHistory:[ + {price:'4.2',time:'2026-05-20 11:00',method:'食材验收价',prevPrice:'5.5',operator:'张明'}, + {price:'5.5',time:'2026-03-15 09:40',method:'手工录入',prevPrice:'5.0',operator:'王芳'} ]}, {name:'鸡蛋',code:'0401001',alias:'鸡蛋',firstClass:'蛋类',secondClass:'鸡蛋',icon:'🥚',edible:'88',waterRate:'74.1',dataSource:0,basePrice:'6.5',vegTypes:[], nutri:{calorie:144,protein:13.3,fat:8.8,carbohydrate:2.8,dietary_fiber:0, @@ -506,6 +519,10 @@ const FOODS = [ {type:'编辑',title:'完善生物素与胆碱',time:'2026-02-25 16:00',user:'李建国',role:'营养师',dept:'营养管理部',summary:'补充生物素、总胆碱等 4 项指标。',changes:[{field:'生物素',old:'—',new:'20 μg'},{field:'总胆碱',old:'—',new:'294 mg'}]}, {type:'价格调整',title:'更新基础定价',time:'2026-04-18 10:20',user:'张明',role:'采购员',dept:'采购部',summary:'蛋价季节性波动,微调。',changes:[{field:'基础定价',old:'7.0 元/100g',new:'6.5 元/100g'}]}, {type:'编辑',title:'补充碘含量',time:'2026-07-04 14:50',user:'王秀兰',role:'营养师',dept:'营养管理部',summary:'补充碘元素数据,完善矿物质维度。',changes:[{field:'碘',old:'—',new:'27.2 μg'}]} + ], + priceHistory:[ + {price:'6.5',time:'2026-04-18 10:20',method:'手工录入',prevPrice:'7.0',operator:'张明'}, + {price:'7.0',time:'2026-02-20 08:50',method:'食材验收价',prevPrice:'6.8',operator:'王芳'} ]}, {name:'豆腐(北)',code:'0601001',alias:'北豆腐',firstClass:'豆及豆制品',secondClass:'豆制品',icon:'🧈',edible:'100',waterRate:'82.8',dataSource:1,basePrice:'5.0',vegTypes:[ {groupId:'g1',alias:'块类组',specAlias:'大方块',yieldRate:'96',edibleRate:'100',cutSpec:{shape:'块',length:30,width:30,height:20,technique:'直刀'}}, @@ -526,6 +543,10 @@ const FOODS = [ {type:'价格调整',title:'更新基础定价',time:'2026-05-12 09:30',user:'张明',role:'采购员',dept:'采购部',summary:'豆制品批发价上调。',changes:[{field:'基础定价',old:'4.5 元/100g',new:'5.0 元/100g'}]}, {type:'编辑',title:'补充痛风人群提示',time:'2026-06-28 11:45',user:'李建国',role:'营养师',dept:'营养管理部',summary:'新增痛风急性期适量提示。',changes:[{field:'人群备注',old:'—',new:'痛风急性期适量,嘌呤含量偏高'}]}, {type:'编辑',title:'修订矿物质数据',time:'2026-08-05 14:00',user:'陈晓燕',role:'营养师',dept:'营养管理部',summary:'对齐《中国食物成分表》修正钙、镁数据。',changes:[{field:'钙',old:'105 mg',new:'138 mg'},{field:'镁',old:'52 mg',new:'63 mg'}]} + ], + priceHistory:[ + {price:'5.0',time:'2026-05-12 09:30',method:'食材验收价',prevPrice:'4.5',operator:'张明'}, + {price:'4.5',time:'2026-03-01 14:00',method:'手工录入',prevPrice:'4.2',operator:'王芳'} ]} ]; @@ -579,7 +600,8 @@ function renderBasicInfo(f){ html += `
可食部分
${f.edible}%
`; html += `
水分
${f.waterRate}%
`; html += `
数据来源
${sourceLabel}
`; - const priceHint = f.basePrice ? `(2026-06-05 手工录入)` : ''; + const ph0 = (f.priceHistory && f.priceHistory.length) ? f.priceHistory[0] : null; + const priceHint = (f.basePrice && ph0) ? `(${ph0.time.slice(0,10)} ${ph0.method})` : ''; html += `
基础定价
${f.basePrice ? f.basePrice + ' 元/100g' : '—'}${priceHint}
`; let vegTypesValue; if(f.vegTypes && f.vegTypes.length > 0){ @@ -1033,6 +1055,34 @@ function confirmDeleteFood(){ closeDeleteFoodDialog(); alert('已删除该食材'); } + +/* ========== 价格变更历史弹窗 ========== */ +// 打开价格变更历史弹窗,回显当前选中食材的基础定价变更记录 +function openPriceHistoryDialog(){ + var f = FOODS[currentFood]; + var list = f.priceHistory || []; + var body = document.getElementById('priceHistoryBody'); + if(list.length===0){ + body.innerHTML = '暂无价格变更记录'; + } else { + var rows = ''; + list.forEach(function(h){ + rows += ''; + rows += '' + (h.price ? h.price + ' 元/100g' : '—') + ''; + rows += '' + (h.time || '—') + ''; + rows += '' + (h.method || '—') + ''; + rows += '' + (h.prevPrice ? h.prevPrice + ' 元/100g' : '—') + ''; + rows += '' + (h.operator || '—') + ''; + rows += ''; + }); + body.innerHTML = rows; + } + document.getElementById('priceHistoryDialog').classList.add('open'); +} +// 关闭价格变更历史弹窗 +function closePriceHistoryDialog(){ + document.getElementById('priceHistoryDialog').classList.remove('open'); +}
@@ -1103,5 +1153,23 @@ function confirmDeleteFood(){
+ +
+
+
+
价格变更历史
+ +
+
+ + + +
价格更新时间更新方式变更前价格操作人
+
+ +
+
diff --git a/web-admin/nutrition/doc/CHANGELOG.md b/web-admin/nutrition/doc/CHANGELOG.md index 0179086..26342e0 100644 --- a/web-admin/nutrition/doc/CHANGELOG.md +++ b/web-admin/nutrition/doc/CHANGELOG.md @@ -1,5 +1,18 @@ # 营养用餐管理端 CHANGELOG +## [2026-09-21] feat: 净菜订单生成历史双维度全链路对账 + 食物成分价格变更历史弹窗 + +- `prod-clean-order-history.html` 净菜订单生成历史「数据明细」弹窗重构为餐品/食材双维度对账视图: + - 新增维度切换 Tab(🍽️ 餐品维度 / 🥬 食材维度),弹窗加宽至 1240px 并支持横向滚动 + - 餐品维度 12 列双层分组表头:生重环节(推荐生重/下单重量/组配生重)、熟重环节(推荐熟重/烹制熟重)、取餐环节(预测人数/实际人数/取餐重量),三组分色,每个实际值下方带差异率徽标 + - 食材维度 9 列聚合表:同一食材跨餐品合并一行,采供环节(采购数量/实收数量)、加工环节(出净率显式列/净菜产出量)、组配环节(组配实际用量),毛/净口径经出净率换算桥接 + - 食材行可展开查看被哪些餐品使用、各餐品用量贡献与占比;餐品行展开子表列名同步更名 + - 新增 ING_YIELD 出净率表与 COOK_YIELD 熟成率常量,各环节数值由确定性伪随机派生;生成中订单下游环节统一「—」占位 + - 表头文案不含「AI」字样,统一用「推荐生重/推荐熟重/推荐用量」,一级分组表头不带口径后缀 +- `din-ingredient.html` 食物成分: + - 基础定价旁的定价来源提示改为可点击入口,新增「价格变更历史」弹窗(价格/更新时间/更新方式/变更前价格/操作人) + - FOODS 数据模型新增 priceHistory 价格变更记录数组 + ## [2026-09-14] feat: 餐品定价规格拆分为餐品规格与餐品净菜包规格 - `din-dish-add.html` 新增/编辑餐品: diff --git a/web-admin/nutrition/prod-clean-order-history.html b/web-admin/nutrition/prod-clean-order-history.html index 97a6645..aadbd00 100644 --- a/web-admin/nutrition/prod-clean-order-history.html +++ b/web-admin/nutrition/prod-clean-order-history.html @@ -76,12 +76,12 @@ tbody tr:hover{background:#F8FBFF;} /* 弹窗 */ .modal-mask{display:none;position:fixed;inset:0;background:rgba(0,0,0,0.45);z-index:200;align-items:center;justify-content:center;} .modal-mask.show{display:flex;} -.modal{background:#fff;border-radius:var(--radius-lg);width:1100px;max-width:92vw;max-height:88vh;display:flex;flex-direction:column;box-shadow:0 8px 24px rgba(0,0,0,0.15);} +.modal{background:#fff;border-radius:var(--radius-lg);width:1240px;max-width:94vw;max-height:88vh;display:flex;flex-direction:column;box-shadow:0 8px 24px rgba(0,0,0,0.15);} .modal__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 16px;border-bottom:1px solid var(--border);} .modal__title{font-size:var(--font-lg);font-weight:600;} .modal__close{width:32px;height:32px;border:none;background:none;font-size:18px;cursor:pointer;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;color:var(--text-secondary);} .modal__close:hover{background:#f5f5f5;color:var(--text-primary);} -.modal__body{padding:20px 24px;overflow-y:auto;flex:1;} +.modal__body{padding:20px 24px;overflow-y:auto;overflow-x:auto;flex:1;} .modal__footer{display:flex;justify-content:flex-end;gap:8px;padding:16px 24px;border-top:1px solid var(--border);} /* 弹窗概要 */ .detail-summary{display:flex;flex-wrap:wrap;gap:20px 40px;padding:14px 16px;background:#F7F9FC;border-radius:var(--radius-sm);margin-bottom:16px;} @@ -110,6 +110,22 @@ tbody tr:hover{background:#F8FBFF;} .ing-type--main{background:var(--primary-light);color:var(--primary);} .ing-type--aux{background:#F6FFED;color:var(--success);} .ing-type--season{background:#FFF7E6;color:var(--warning);} +/* 维度切换 Tab */ +.dim-tabs{display:flex;gap:8px;margin-bottom:14px;} +.dim-tab{height:34px;padding:0 22px;border-radius:6px;border:1px solid var(--border);background:#fff;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;transition:all .2s;display:inline-flex;align-items:center;gap:6px;} +.dim-tab:hover{color:var(--primary);border-color:var(--primary);} +.dim-tab.active{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:500;} +/* 环节分组表头(生重/熟重/取餐、采供/加工/组配 分色) */ +.dish-table thead th.th-group{font-weight:600;border-bottom:none;} +.dish-table thead th.th-group--raw,.dish-table thead th.th-group--ing-purchase{background:#F0F7FF;color:#1D6FE8;text-align:center;} +.dish-table thead th.th-group--cook,.dish-table thead th.th-group--ing-process{background:#FFF7E6;color:#D48806;text-align:center;} +.dish-table thead th.th-group--pickup,.dish-table thead th.th-group--ing-combo{background:#F6FFED;color:#389E0D;text-align:center;} +/* 预测值/实际值单元格 */ +.val{font-weight:600;} +.val--base{color:var(--primary);} +.val-empty{color:var(--text-placeholder);font-weight:400;} +.val-diff{margin-top:3px;line-height:1;} +.tag--mini{font-size:10px;padding:1px 6px;border-radius:8px;} /* 空态 */ .empty-state{text-align:center;color:var(--text-placeholder);padding:60px 0;font-size:var(--font-sm);} .empty-state .icon{font-size:40px;display:block;margin-bottom:12px;} @@ -140,7 +156,7 @@ tbody tr:hover{background:#F8FBFF;}