From 4fd44f1005bb55777d196e5cebef0041f6e496ca Mon Sep 17 00:00:00 2001 From: fengpu <18691763612@163.com> Date: Wed, 5 Aug 2026 09:57:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=84=E6=A0=BC=E4=BD=93=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=8C=96=E9=98=B6=E6=AE=B5=E5=9B=9B=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=AB=AF=20+=20=E9=98=B6=E6=AE=B5=E4=BA=94=E8=BE=85?= =?UTF-8?q?=E5=8A=A9=E9=A1=B5=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 设备端 9 任务 14 文件:毛菜验收/加工秤、净菜组配/包装秤、净菜加工秤设置统一为克存储 + formatGram 展示层兼容 + cutSpec/packSpec 结构化 - 辅助页 3 任务 6 文件:质控同步真落地 + 菜品下拉跨页共享 + 同步日志驱动 + 分析页字典语义对齐 + 净菜进柜 spec 多形态结构化 - 新增 spec-utils-reference.md 权威源、改造任务清单与研发同步说明 - 删除旧的部门下周工作计划文档 Co-Authored-By: Claude Opus 4.7 --- .../01-orders.html | 122 +- .../02-labeling.html | 90 +- .../label-preview.html | 124 +- .../clean-veg-ratio-scale/03-settings.html | 20 +- .../ratio-scale/01-packing-tasks.html | 108 +- .../ratio-scale/02-weighing-packing.html | 126 +- .../ratio-scale/03-verify-history.html | 87 +- .../01-verify-inspection.html | 70 +- .../01-washing-tasks.html | 53 +- .../02-batch-weighing.html | 75 +- .../03-batch-washing.html | 84 +- .../raw-veg-processing-scale/04-history.html | 48 +- web-admin/nutrition/din-dict-config.html | 95 +- web-admin/nutrition/din-dict-mgmt.html | 32 +- web-admin/nutrition/din-dish-add.html | 54 +- web-admin/nutrition/din-dish-all.html | 44 +- web-admin/nutrition/din-dish-own.html | 21 +- web-admin/nutrition/din-ingredient-add.html | 49 +- web-admin/nutrition/din-ingredient.html | 29 +- web-admin/nutrition/doc/CHANGELOG.md | 96 ++ .../screenshots/prod-clean-order-modal-cp.png | Bin 0 -> 124491 bytes .../nutrition/doc/spec-utils-reference.md | 207 ++++ ...周工作计划(2026年8月3日-7日)最终版-ty.md | 150 --- .../doc/规格体系统一化改造-研发同步说明.md | 257 ++++ .../doc/规格体系统一化改造任务清单.md | 1094 +++++++++++++++++ .../doc/规格管理体系分析与设计方案.md | 993 +++++++++++---- web-admin/nutrition/farm-purchase.html | 55 +- web-admin/nutrition/prod-clean-order.html | 240 +++- web-admin/nutrition/prod-proc-cabinet.html | 90 +- web-admin/nutrition/prod-proc-combo.html | 113 +- web-admin/nutrition/prod-proc-cook.html | 90 +- .../nutrition/prod-qc-nutrition-add.html | 40 +- .../nutrition/prod-qc-nutrition-sync.html | 250 +++- web-admin/nutrition/prod-qc-nutrition.html | 126 +- web-admin/nutrition/sup-biz-analysis.html | 12 +- web-admin/nutrition/sup-clean-external.html | 122 +- web-admin/nutrition/sup-clean-internal.html | 126 +- web-admin/nutrition/sup-in-clean.html | 12 +- web-admin/nutrition/sup-in-cleanin.html | 66 +- web-admin/nutrition/sup-in-raw.html | 18 +- web-admin/nutrition/sup-pkg-label.html | 107 +- web-admin/nutrition/sup-process-analysis.html | 44 +- 42 files changed, 4738 insertions(+), 901 deletions(-) create mode 100644 web-admin/nutrition/doc/screenshots/prod-clean-order-modal-cp.png create mode 100644 web-admin/nutrition/doc/spec-utils-reference.md delete mode 100644 web-admin/nutrition/doc/智能部下周工作计划(2026年8月3日-7日)最终版-ty.md create mode 100644 web-admin/nutrition/doc/规格体系统一化改造-研发同步说明.md create mode 100644 web-admin/nutrition/doc/规格体系统一化改造任务清单.md diff --git a/other-module/canteen-device/clean-veg-packaging-labeler/01-orders.html b/other-module/canteen-device/clean-veg-packaging-labeler/01-orders.html index ffe52ac..e16c633 100644 --- a/other-module/canteen-device/clean-veg-packaging-labeler/01-orders.html +++ b/other-module/canteen-device/clean-veg-packaging-labeler/01-orders.html @@ -228,6 +228,80 @@ +``` + +**注意**: +- 按需选取,不必全量复制(例如只用 `formatCutSpec` 的页面,只内联这一个函数) +- 复制后不得修改函数实现(确保所有页面一致) +- 如需新函数或修改现有函数,**先在本文件修改**,再同步复制到所有页面 + +--- + +## 四、维护说明 + +1. 本文件是**唯一权威源**,任何函数修改都先在这里进行 +2. 修改后,**同步更新所有引用该函数的页面**(可通过 grep 搜索函数名定位) +3. 建议在每次改造任务完成后,运行一次全文检索,确认所有页面的函数实现一致 + +--- + +## 五、版本记录 + +| 版本 | 日期 | 变更内容 | +|------|------|---------| +| v1.0 | 2026-08-04 | 初版,12 个工具函数(任务 1.1 交付) | diff --git a/web-admin/nutrition/doc/智能部下周工作计划(2026年8月3日-7日)最终版-ty.md b/web-admin/nutrition/doc/智能部下周工作计划(2026年8月3日-7日)最终版-ty.md deleted file mode 100644 index 955db63..0000000 --- a/web-admin/nutrition/doc/智能部下周工作计划(2026年8月3日-7日)最终版-ty.md +++ /dev/null @@ -1,150 +0,0 @@ -# 智能部下周工作计划(2026年8月3日 — 8月7日)最终版 - -> **依据**:(1)7月28日开业筹备第一次碰头会会议报告 + 老徐手记;(2)《智养餐饮平台系统反馈报告》156条业务反馈;(3)8月1日营养管理专项问题梳理;(4)8月2日开业碰头会第二次会议调整意见 -> **用途**:8月3日(周一)晨会任务下发,每项预留负责人与完成时间,晨会时补充填写 - ---- - -## 一、P0:最高优先级(阻塞试营业,下周必须攻克) - -> 以下任务为试营业的硬阻塞项,压倒一切,必须在本周内完成或取得决定性进展。 - -| 编号 | 任务 | 负责人 | 完成时间 | 说明 | 备注 | -|------|------|--------|----------|------|----------| -| **P0-1** | **全链路定价体系建设** | | | 🆕 **今日会议最高优先级新增,本周必须攻克**。打通从采购到售卖的全链条价格体系,分六个环节逐级传导——**①毛菜采购价**:实付金额÷验收重量=核算单价(自动计算,不可手动改),同时保留供应商报价单价字段供对比核查;**②毛菜入库价**:核算单价随毛菜入库延续,入库即带价;**③净菜价**:按净菜率从毛菜入库价折算净菜成本单价;**④餐品净菜包成本价**:根据餐品构成中各净菜用量与净菜单价汇总计算;**⑤餐品制作实际成本价**:对接配比秤实际投料数据(主辅料+调料用量+熟重),对比理论成本与实际成本偏差,以实际投料为准更新成本;**⑥餐品最终定价**:经营人员逐菜品设定毛利率→系统自动生成售卖价。先做应急版(跳过净菜中间加价环节,直接毛菜采购价→餐品成本→毛利率→售价,确保能卖饭),后续迭代完善全链条 | 产品设计 | -| **P0-2** | **餐品库体系改造** | | 8.3 | 🆕 **整合原P0-2/P1-16/P2-1三条任务,提至最高优先级,周一必须完成**。改造现有单一餐品库为两级架构——**①系统级餐品总库**:包含两类餐品,须在设计上严格区分、不可混用:(a)正规流程餐品——通过系统标准流程维护,具备完整食材构成与配比重量数据,用于餐厅经营、净菜组配、成本核算等全部业务环节;(b)第三方餐品库——来自个人端小程序"自记餐"功能导入的外部餐品数据,缺失餐品构成信息,餐品本身直接设定营养数据(热量/蛋白质/脂肪等),仅供自记餐场景使用,不得混入经营流程。**②餐厅/食堂餐品库**:从系统级总库中选取本餐厅使用的餐品形成子集。餐厅提交餐品净菜包订单时,必须将餐品构成信息(用料清单+配比重量)附加到订单上,净菜加工场组配时按构成信息进行组配。同步完善:分类管理增删改查、餐品名称同组织唯一性校验、搜索食材功能修复。**周一必须完成现有200+菜品录入**(含食材构成+配比重量),食材库缺失的原材料可自己加(营养数据可缺失但重量价格必须有)。徐总带2-3个示范后交王喜团队批量完成 | 产品已补全设计 | -| **P0-3** | **支付功能修复与完善** | | | ⬆ **今日会议提级**。两项——(1)联合支付已修复但APP未更新,尽快更新上线;(2)余额支付功能下周内完成开发。先把联合支付修复上线,内部测试版随时升级 | 产品设计/已完成 | -| **P0-4** | **结算台问题专项修复** | | | 三项——(1)吐盘机人脸识别成功但餐线不显示打餐数据,导致无法结账;(2)付款后界面仍停留在未支付状态;(3)实际取餐信息与结算台显示不对应 | | -| **P0-5** | **营养秤重量失真修复** | | | 打餐重量严重失真(实际100g→系统显示620g),疑为未识别人脸时压秤后补识别导致。需根因分析+修复 | | -| **P0-6** | **营养秤人脸识别不稳定修复** | | | 3号营养秤人员识别不上;不同秤之间人脸数据未同步。需逐台验证+修复同步机制 | | -| **P0-7** | **试营业模拟问题即刻修复** | | | 员工参与试营业模拟过程中发现的系统问题第一时间修复:小问题当日修复,大问题提至最高优先级处理。小问题不过夜 | | -| **P0-8** | **配比秤餐品制作数据全量存储** | | | 配比秤接入后,餐品制作全过程关键数据(主辅料清单及用量、调料清单及用量、餐品熟重)后台必须完整存储。当前菜品构成数据缺失严重,此项是后续更新菜品构成的唯一可靠数据来源,同时为P0-1第⑤环节提供实际成本数据 | 验证 | -| **P0-9** | **部署独立开发与测试环境** | | | 现有智养餐饮平台环境作为试营业生产环境,需尽快部署独立的开发、测试环境,与生产环境隔离 | | -| **P0-10** | **清理现有环境测试数据** | | | 将当前环境的旧测试数据(菜品定价、用户记录、交易流水、"内部供应商"等)彻底清理,确保试营业数据真实准确 | | -| **P0-11** | **组配秤任务逻辑修复** | | | 三项——(1)实际配比4道菜系统显示7道;(2)实际完成4道但显示已完成3道,计数不同步;(3)称重接近目标时未去皮导致实际重量偏小 | | -| **P0-12** | **取餐"价格=重量"BUG修复** | | | 🆕 营养管理专项P0。取餐记录中价格等于重量、热量等于重量,缺少乘以单价逻辑,直接影响收费 | | -| **P0-13** | **食谱规划/管理菜单位置调整** | | | 🆕 营养管理专项P0。当前菜单顺序反了:应是"营养用餐(定食堂+人数+食谱)→下达生产部门→健康生产(按食谱+人数计算食材用量)",不是现在的"健康生产→食谱规划→营养用餐" | 优先级放后 | -| **P0-14** | **53条手动食物数据逐条核实** | | | 🆕 营养管理专项P0。可食部为空、颜色千篇一律、味道/口感写死等数据质量问题,必须逐条核实补全:可食部+营养成分+颜色+味道 | | -| **P0-15** | **3429条内置食物数据来源核查启动** | | | 🆕 营养管理专项P0。声称"中国营养学会"但混入肯德基、麦当劳、九珍果汁等商业产品数据,需核查并去除。坚果等基本品类缺失需补全。本周启动 | | -| **P0-16** | **毛菜存储增加取用变化记录** | | | 🆕 营养管理专项P0。当前溯源只显示概要("入库3.4公斤,余量2.1公斤,已领用0——少的1.4公斤去哪了?"),需记录完整变化过程:时间+取走多少+取走人 | 优先级放后 | -| **P0-17** | **规格/单位字段拆分** | | | 🆕 营养管理专项P0。当前规格与单位混淆("规格都是斤,数量是1"),需拆分为三个字段:规格(克重)+单位(袋/瓶/筐/批)+数量 | 产品设计 | -| **P0-18** | **每日经营统计功能开发** | | | 至少实现通过数据库查询每日导出当日经营统计结果(就餐人数、收入、菜品销量等核心指标) | 产品设计 | -| | 小程序查看餐线订单 | | | 支持查看餐线订单 | 产品设计 /已完成 | -| | 小程序支持人脸录入、授权手机号 | | | 对比人脸信息,关联临时用户 | 产品设计 /已完成 | -| | 净菜厨房柜 | | | 厨房净菜柜对接、确认 | | -| | 净菜柜、毛菜柜 | | | 确认多台的影响范围 | | -| | 小程序屏蔽功能 | | | 订餐、点餐、净菜包购买 | | -| | | | | | | -| | | | | | | - ---- - -## 二、P1:高优先级(影响核心业务流程,本周全力推进) - -| 编号 | 任务 | 负责人 | 完成时间 | 说明 | 备注 | -|------|------|--------|----------|------|------| -| **P1-1** | **后厨补餐屏接入试营业系统** | | | 补餐屏(小米电视)已放置后厨,需完成程序接入并确定安装位置(建议挂厨师附近墙上) | 1 | -| **P1-2** | **食谱→净菜→毛菜采购量自动生成** | | | 🆕 王喜团队反馈三大核心需求之一。下食谱后系统自动生成净菜需求量,净菜量自动反算毛菜采购量。已有钱博士提供的算法,王喜先手算验证几次再开发 | 优先级放后 | -| **P1-3** | **净菜数据维护配合** | | | 🆕 放开权限给王喜团队维护净菜名称。每个毛菜下挂多种净菜(如青椒→青椒丝/段/块),只维护实际用到的几十到一百种。徐总带2-3个示范后交团队 | 1 | -| **P1-4** | **取餐屏APP改造(支持视频播放)** | | | 🆕 黄总团队制作菜品AI生成视频,需改造APP待机画面支持播放视频(从后台下载),支持操作人员随时更换。黄总每天发视频素材,这边对接上线 | 产品设计/已完成 | -| **P1-5** | **算力与存储采购推进** | | | 🆕 会上被点名批评"不要再拖了"。大半年前提出按10倍储备采购,至今未执行。让小江尽快确认需求,确认后立即采购。存储和算力价格在上涨 | | -| **P1-6** | **结算后营养小票打印功能** | | | 第一阶段:终端侧按既定模板打印结算信息与营养信息 | 产品设计 | -| **P1-7** | **大厅排行榜APP接入试营业系统** | | | 排行榜展示APP接入试营业系统环境,显示实时排行数据,带一屏改版数字调整 | 产品设计/已完成 | -| **P1-8** | **餐线上方带鱼屏改版** | | | 需求及界面效果已完成,显示内容调整为"菜品价格+热量信息",因屏幕清晰度一般不做复杂展示 | 产品设计/已完成 | -| **P1-9** | **毛菜验收秤校验修复** | | | 四项——(1)未全部验收即可提交,缺少必验校验;(2)缺少重量校验导致0重量也可验收;(3)多次拍照建模触发闪退;(4)错误识别菜品重量覆盖其他菜品 | | -| **P1-10** | **净菜加工秤数据修复** | | | 两项——(1)毛菜足量但净菜加工后显示"还需0.0千克";(2)清除库存不足任务后仍出现库存不足,后台数据未正常同步 | | -| **P1-11** | **毛菜加工时间记录修正** | | | 三项——(1)开始时间为统一提交时间而非首次放置时间;(2)同种蔬菜重复出现两次记录(应合并相同食材);(3)加工秤应只读取主辅材数据 | | -| **P1-12** | **取餐管理功能修复** | | | 三项——(1)数据分页选择100行实际只展示30行;(2)用户取餐但未得分;(3)无法通过用户名查询取餐记录 | | -| **P1-13** | **后台数据展示修复** | | | 四项——(1)净菜订单数据看板"已完成"恒为0;(2)毛菜入库后后台显示未入库(含存放区域缺失);(3)入库时间显示为非最终入柜时间;(4)毛菜入库排序逻辑正序改倒序 | | -| **P1-14** | **环境更新与回退机制建立** | | | 对试营业生产环境的更新操作须慎重,每次更新前做好备份,确保出现问题可回退至上一版本。本周完成方案并持续执行 | | -| **P1-15** | **食物成分数据规范** | | | 四项——(1)宏量营养素改为必填项;(2)食材名称增加唯一性校验;(3)净材率去掉最大值校验(干木耳泡发场景); | | -| **P1-16** | **各节点补齐关键信息字段** | | | 🆕 营养管理专项P1。每个业务节点统一补齐:时间+操作人+设备编号+重量变化+单价。补齐缺失字段:采购人、入库人/验收人、审核人。本周设计、下周开发 | | -| **P1-17** | **食材统一加"国家营养库食材编码"字段** | | | 🆕 营养管理专项P1。为后续数据溯源和权威性验证打基础 | | -| **P1-18** | **补全基本品类食材数据** | | | 🆕 营养管理专项P1。坚果等基本品类在3429条内置数据中缺失,需补全 | | -| **P1-19** | **库存负值保护** | | | 🆕 营养管理专项P1。取格子时小于等于0一律等于0,程序加保护逻辑 | | -| **P1-20** | **页面返回逻辑修复** | | | 🆕 营养管理专项P1。"明明在A页面,返回后跳到B",全局排查修复 | | -| **P1-21** | **菜品数据梳理核对** | | | 现有菜品数据(构成、营养信息、定价)多为随手录入,需逐一核对核实,配合菜品成本核算工作。完成首轮核对 | | -| **P1-22** | **小程序发布准备** | | | (1)确定小程序名称和图标设计;(2)梳理腾讯小程序上架审核所需资质(如ICP经营许可证等),列出缺失项并启动办理流程。等资质到位后发布正式版 | | - ---- - -## 三、P2:中等优先级(提升易用性与规范化) - -| 编号 | 任务 | 负责人 | 完成时间 | 说明 | -|------|------|--------|----------|------| -| **P2-1** | **采购单来源与规格修正** | | | 采购单来源仅支持手动/内供/外售(去掉食谱搭配来源),规格改为下拉菜单 | -| **P2-2** | **净菜加工字段清理** | | | 删除无实际功能的质检结果字段;开始/结束时间清晰命名 | -| **P2-3** | **65寸广告机使用方式交接** | | | 将65寸广告机(柱子广告机)的日常操作方式(开关机、内容更新、轮播设置等)交接给餐厅工作人员 | -| **P2-4** | **界面优化(序号/折叠/去重)** | | | 🆕 营养管理专项P3提至P2。所有列表统一加序号、左侧菜单支持折叠、入库信息去重显示、"食材溯源"等冗余标题去除 | -| **P2-5** | **UI数据字段修正** | | | 🆕 营养管理专项。年龄自动计算(输入身份证号/出生日期→自动算年龄)、毛菜类型修正("面片"标为毛菜需修正)、养殖/种植分类修正("辣椒"标为"养殖"需改为"种植") | -| **P2-6** | **视频/图片字段预留** | | | 🆕 营养管理专项。各业务节点预留视频/图片字段 | -| **P2-7** | **AI辅助食材用量计算验证** | | | 🆕 输入"食谱+人数"让AI算食材用量,验证可行性 | - ---- - -## 四、持续配合事项 - -| 编号 | 任务 | 负责人 | 完成时间 | 说明 | -|------|------|--------|----------|------| -| **C-1** | **配合菜品成本核算** | | | 配合王喜、吕学锋、唐修哲完成200个菜品的成本核算与试营业定价,从后台捋价格,提供系统侧数据支持 | -| **C-2** | **每日参加开业筹备例会** | | | 暂定每天10:30召开,汇报技术侧进展与阻塞问题 | -| **C-3** | **业务反馈问题持续跟踪** | | | 每日跟进业务反馈清单中"待处理"问题,更新解决状态;当天新反馈的BUG当日响应 | -| **C-4** | **餐盘柜接入试营业系统** | | | 优先级较低,其他任务完成后推进 | - ---- - -## 五、优先级汇总 - -| 优先级 | 任务数 | 任务编号 | -|--------|--------|----------| -| **P0(最高)** | 18 | P0-1~P0-18 | -| **P1(高)** | 22 | P1-1~P1-22 | -| **P2(中)** | 7 | P2-1~P2-7 | -| **持续配合** | 4 | C-1~C-4 | -| **合计** | **51** | — | - -> ⚠️ 本周任务总数51项,其中P0级18项为试营业硬阻塞项,必须全力保障、逐项销号。 -> **两大头号工程**:P0-1(全链路定价)合并了原五条价格任务,覆盖毛菜采购价→入库价→净菜价→净菜包成本→实际制作成本→最终定价;P0-2(餐品库改造)合并了原三条餐品库任务,建立"系统级总库(正规流程+自记餐第三方)→餐厅餐品库(订单附加构成信息)"两级架构。 - ---- - -## 六、今日(8月2日)待办 - -| # | 事项 | 要求 | -|---|------|------| -| 1 | **问题全量汇集** | 把昨天会上的问题+今天会上提的所有问题,全部重新汇集整理成清单,今晚发到群里 | -| 2 | **大分工+小分工** | 大分工=各模块负责人(抓落实),小分工=具体操作执行人。今天下午叫上杨幂、张传志等相关人员一起梳理 | -| 3 | **核心问题重点落实** | 定价问题和餐品库改造是头号紧急事项,必须下周攻克 | - ---- - - - -## 附:业务反馈问题待处理跟进清单(本周重点销项) - -| 序号 | 模块 | 核心问题 | 状态 | 对应任务 | -|------|------|----------|------|----------| -| 1 | 结算台 | 吐盘机人脸识别成功但餐线不显示打餐数据 | 待审核 | P0-4 | -| 2 | 结算台 | 付款后界面仍停留在未支付状态 | 待审核 | P0-4 | -| 3 | 结算台 | 实际取餐信息与结算台显示不对应 | 待审核 | P0-4 | -| 4 | 营养秤 | 打餐重量失真(100g→620g) | 待审核 | P0-5 | -| 5 | 营养秤 | 人员打餐信息与实际操作人员不符 | 待处理 | P0-6 | -| 6 | 营养秤 | 3号秤人员识别不上 | 待处理 | P0-6 | -| 7 | 毛菜/净菜货柜 | 放置时间应取最近一次数据 | 待审核 | P1-13 | -| 8 | 组配秤 | 去皮缺失/任务计数错误(3条) | 待处理 | P0-11 | -| 9 | 毛菜验收秤 | 未验收可提交/0重量验收/拍照闪退/重量覆盖 | 待处理 | P1-9 | -| 10 | 净菜加工秤 | 显示错误/库存数据异常 | 待处理 | P1-10 | -| 11 | 取餐管理 | 分页bug/未得分/查询失效 | 待处理 | P1-12 | -| 12 | 后台-健康生产 | 净菜订单看板统计失效 | 待处理 | P1-13 | -| 13 | 营养管理-全链路定价 | 采购单价=手动输入不可靠;入库后无价格;缺少净菜成本/制作成本/自动定价 | 待处理 | **P0-1** | -| 14 | 营养管理-餐品库 | 单一餐品库无层级区分;缺少自记餐第三方餐品隔离;订单未附加构成信息 | 待处理 | **P0-2** | -| 15 | 营养管理-取餐 | "价格=重量""热量=重量"数据BUG | 待处理 | P0-12 | -| 16 | 营养管理-食谱 | 食谱规划→健康生产菜单顺序反了 | 待处理 | P0-13 | -| 17 | 营养管理-食物库 | 53条手动数据可食部/颜色/味道随意填写 | 待处理 | P0-14 | -| 18 | 营养管理-食物库 | 3429条内置数据混入肯德基/麦当劳等商业数据 | 待处理 | P0-15 | -| 19 | 营养管理-溯源 | 毛菜存储缺少取用变化记录(入库3.4→余2.1→领用0,少1.4去向不明) | 待处理 | P0-16 | - ---- - -*整理时间:2026年8月2日* -*下发时间:2026年8月3日(周一)晨会* diff --git a/web-admin/nutrition/doc/规格体系统一化改造-研发同步说明.md b/web-admin/nutrition/doc/规格体系统一化改造-研发同步说明.md new file mode 100644 index 0000000..2484c98 --- /dev/null +++ b/web-admin/nutrition/doc/规格体系统一化改造-研发同步说明.md @@ -0,0 +1,257 @@ +# 规格体系统一化改造 · 研发同步说明 + +> 撰写日期:2026-08-05 | 适用范围:营养管理模块(管理端 + 食堂设备端) | 目的:产品→研发的需求同步 + +--- + +## 一、改造背景(一句话说明) + +原系统中"规格"信息分散在 30+ 个页面,存在 **3 套互不一致的写死规格字典**、**"斤/克"单位不统一**、**份型/切配参数与餐品脱钩**、**包装规格无法跨页传递** 等问题。本次改造将所有规格信息统一为同一套口径,并打通"餐品总库 → 下游所有页面"的规格数据流。 + +--- + +## 二、整体改动概览 + +| 端 | 改动菜单数 | 涉及核心场景 | +|----|-----------|-------------| +| 管理端(营养管理) | 19 个菜单 | 食材档案、餐品档案、字典、订单、加工、包装、质控、分析 | +| 设备端(食堂设备) | 7 个设备模块(共 14 个页面) | 验收秤、毛菜加工秤、净菜加工秤、包装贴标秤、组配秤 | + +--- + +## 三、管理端改动清单(营养管理) + +### 1. 食材档案 + +#### 1.1 食材档案 - 新增/编辑 +- 净菜子项录入表由原来的 2 列(净菜名称、出净率)扩展为 7 列,新增"切配形状、长/宽/高(毫米)、刀工"5 个录入项 +- 切配形状与刀工以下拉框形式选择,选项来源于字典管理页的"切配类型字典" +- 录入时会同时保存每条净菜子项的完整切配参数(形状、尺寸、刀工) + +#### 1.2 食材档案 - 详情/列表 +- 详情面板的净菜子项展示新增"切配规格"列,以可读文本统一展示(例:`15×15×15mm · 丁 · 直刀`) +- 默认展开"猪里脊"示例,便于业务方理解切配规格的展示效果 + +--- + +### 2. 餐品档案 + +#### 2.1 餐品总库 +- 每个餐品的"份型规格"统一为"克重 + 包装单位 + 份型名"三要素(例:`200g / 标准份`) +- 份型下拉的选项来源改为字典管理页的"份型字典",不再使用页内写死数据 +- **新增"营养规格"信息位**(承接营养质控的回写) +- **新增跨页共享能力**:页面打开时,会将本页所有餐品的规格信息持久化到浏览器本地,作为下游所有页面(订单/加工/包装/质控等)的统一数据源 + +#### 2.2 餐品总库 - 新增/编辑 +- 份型录入行改为"左克重输入框 + 右份型下拉框"连体组件 +- 展示格式统一为 `克重g/份型` + +#### 2.3 我的餐品 +- 同 2.2,份型录入与展示统一为连体组件格式 + +--- + +### 3. 字典管理 + +#### 3.1 字典管理 +- 新增"规格"Tab 页签 + +#### 3.2 字典配置 +- "规格"Tab 下挂 4 套独立字典,共 42 个字典项: + - **包装单位字典**(首期 9 项:散装、件、袋、盒、箱、盘、份、瓶、罐;目标态 15 项) + - **切配类型字典**(8 项:丁、丝、片、块、段、末、泥、条,每项含默认尺寸与刀工) + - **份型字典**(5 项:标准份、小份、大份、迷你份、加大份,每项含默认克重) + - **包装方式字典**(6 项:真空、气调、普通、冷鲜、保鲜盒、散装托盘) + +--- + +### 4. 净菜加工与入库 + +#### 4.1 净菜加工批次 +- 删除页内写死的"食材→净菜类型"映射表,改为从食材档案动态读取 +- 净菜类型下拉显示从"只显示名称"升级为"名称 + 切配规格"(便于业务方识别) +- 表格新增"切配规格"列 +- 出净率改为真实计算(净菜产出 ÷ 毛菜投入),支持反向推导(输入净菜需求量自动算毛菜重量) + +#### 4.2 净菜入库 +- 删除页内写死的净菜类型清单 +- 入库规格下拉统一为"克重 + 包装单位"格式(如 `500g/袋`) +- 新增"切配规格"只读回显字段 +- 与上游净菜加工批次页之间通过页面跳转参数传递切配规格 + +#### 4.3 采供下单 +- 采购规格从原来的"自由文本输入"改为按食材自动带出(来源:食材档案的采购级规格) +- 液体类食材单位修正(如花生油 `5L/桶` → `5kg/桶`,按 1ml≈1g 换算) + +#### 4.4 毛菜入库 +- 入库规格从"7 种固定下拉选项"改为自动从采购订单继承,无需重选 + +--- + +### 5. 订单与配送 + +#### 5.1 净菜订单 +- 删除两套页内写死的规格字典(普通模式一份、餐品模式一份、汇总表一份,三套数据互不一致) +- 订单行的份型规格统一为"克重 + 单位/份型"组合,以连体组件录入(左克重 + 右单位/份型) +- 餐品模式下,选择餐品后,份型下拉会动态加载该餐品在总库中维护的份型列表(不再固定) +- 重量计算公式修正:考虑包装单位的容量换算 +- 单位下拉选项来源:字典管理页的"包装单位字典" + +#### 5.2 外售 +- 同 5.1,删除页内写死的规格字典 +- 录入与展示格式统一 +- 默认包装单位为"箱"(下单偏批量) + +#### 5.3 内供 +- 同 5.1,删除页内写死的规格字典 +- 录入与展示格式统一 +- 默认包装单位为"盘"(食堂内部配送常用) + +--- + +### 6. 生产加工 + +#### 6.1 净菜组配 +- 删除"3 个全局固定份型选项"(小份/标准份/大份),原下拉与所选餐品完全脱钩 +- 改为餐品级联动:选择餐品后,份型下拉动态加载该餐品在总库的份型列表 +- 选中份型后自动带出对应克重与单位 + +#### 6.2 按单烹制 +- 规格字段改为只读回显(从上游组配单继承,本页不再允许编辑规格) +- 规格展示统一为 `克重g/份型` +- **新增"生熟比"自动计算**:输入生重后,熟重按出净率自动计算(向上取整),出净率从食材档案关联读取 + +#### 6.3 净菜进柜 +- 进柜记录的"包装规格"字段原有多种自由文本形态(如 `5kg/袋`、`标准份(500g)`、`6份/箱`),统一结构化 +- 抽屉详情回显与餐品下拉的规格展示统一为同一格式 + +--- + +### 7. 包装与标签 + +#### 7.1 包装标签 +- **净菜包规格**:从"纯数字输入(无单位)"升级为"左克重 + 右单位"连体组件 +- **餐品包规格**:删除"2 个全局固定选项"(与具体餐品无关),改为按当前餐品动态生成份型选项 +- 包装方式(真空袋/保鲜盒/散装托盘/冷鲜袋)独立为单独字段 +- 与设备端"净菜包装贴标秤"的口径完全对齐 + +--- + +### 8. 营养质控 + +#### 8.1 营养质控 +- "同步检验均值→餐品总库"按钮真落地(原为假操作) +- 同步操作会把检验均值(8 项营养指标 + 4 类感官评级)写入餐品总库对应餐品的"营养规格"字段 +- 同步记录持久化保存,供"营养质控同步记录"页面读取 + +#### 8.2 营养质控 - 新增检验 +- 删除页内写死的餐品清单 +- 改为从餐品总库动态读取,按食堂餐线分组展示 +- 三级联动保留(场所 → 餐线 → 餐品) +- 无数据时回退到内置示例,保证页面可用 + +#### 8.3 营养质控 - 同步记录 +- 数据源改为读取真实的同步记录(由 8.1 写入) +- 无记录时回退到内置示例展示 + +--- + +## 四、设备端改动清单(食堂设备) + +### 10. 毛菜验收秤 + +#### 10.1 验收检验 +- 食材目录 20 项食材默认标记为"称重验收"(按重量过磅) +- 调料目录 8 项调料默认标记为"点收验收"(按件数清点) +- 单位下拉按验收类型自动过滤:称重类只显示重量单位(斤/公斤/克/千克),点收类只显示计数单位(袋/瓶/箱/桶等) +- **关键变更**:验收重量的存储单位统一为"克",展示层仍兼容"斤"显示(如 2000g 显示为"4 斤"),业务方无感知 + +--- + +### 11. 毛菜加工秤(4 个页面) + +#### 11.1 清洗任务列表 +- 任务卡片中的重量信息统一改为克存储,展示层自动还原"斤"显示 + +#### 11.2 批次称重 +- 批次重量数据统一改为克存储 +- 所有重量相关的文本节点(需 X 斤 / 已录 X 斤 / 总重量)自动按克→斤换算展示 + +#### 11.3 批次清洗 +- 同 11.2,存储改克、展示兼容斤 +- 清洗后的出净率字段补齐(每项食材默认出净率 85%~95%) + +#### 11.4 清洗历史 +- 同 11.2,存储改克、展示兼容斤 +- 修复原有的展示层语法错误 + +--- + +### 12. 净菜加工秤 - 设置 + +#### 12.1 加工参数设置 +- 删除"重量单位"下拉(与设备端"克存储"统一方向冲突),改为说明文字提示(由系统自动还原"斤"显示) +- 滚刀块大小的单位统一为毫米(原厘米枚举值统一换算:`2cm → 20mm`、`3cm → 30mm`、`5cm → 50mm`) +- 加工参数区新增说明:切配参数的默认值来源于食材档案,本设置仅作覆盖 + +--- + +### 13. 净菜包装贴标秤(3 个页面)⭐ 最复杂 + +#### 13.1 包装订单 / 13.2 贴标作业 / 13.3 标签预览 +- **字段名统一**:三个页面原有的不同字段名统一为同一套命名 +- **历史 4 种字符串格式兼容**:不同页面原有 4 种不同的切配规格字符串写法(分隔符、空格、全角字符各异),本次全部兼容,统一解析为结构化对象 +- **包装规格结构化**:从自由文本(如 `500g`、`大份800g`、`真空包装`)统一拆解为"克重 + 单位 + 份型 + 包装方式"四要素 +- **"真空包装"等纯描述无克重场景**:作为独立的"包装方式"字段处理,不再混入规格字段 +- 三套示例数据全部结构化改造 +- 展示层统一格式输出 + +--- + +### 14. 净菜组配秤(3 个页面) + +#### 14.1 组配任务 / 14.2 称重包装 / 14.3 校验历史 +- 包装规格从描述性字符串(如 `大份800g`)统一结构化为"份型 + 克重 + 单位"三要素 +- 切配规格字符串统一结构化,展示层统一格式输出 +- **接入餐品总库**:组配任务页启动时从餐品总库加载餐品清单与份型选项,不再使用页内写死数据 +- 与"净菜包装贴标秤"口径完全对齐 + +--- + +## 五、给研发的关键提示 + +### 5.1 数据存储统一原则 +- **所有重量字段的存储单位必须是"克(g)"**,数据库字段、接口入参/返参均以克为单位 +- "斤"仅作为设备端验收秤的展示层兼容,业务方看到的"4 斤"在系统中存储为 2000g + +### 5.2 跨页数据共享机制 +- 原型阶段使用浏览器本地存储(localStorage)模拟"餐品总库 → 下游页面"的数据流 +- **研发落地时需替换为后端接口**,建议提供"餐品规格全量查询"接口 + 前端缓存层 +- 关键操作前需校验数据时效(避免下游页读到过期数据) + +### 5.3 字典落地 +- 4 套字典(包装单位 / 切配类型 / 份型 / 包装方式)已落地到字典管理页 +- 研发需建字典主表 + 字典项表,按字典编码过滤加载 +- 首期落地的字典项数(见 3.2 节)为最小可用集,后续可由业务方在字典管理页扩展 + +### 5.4 历史数据迁移 +- 设备端原有 4 种切配规格字符串格式必须全部兼容(否则历史数据会丢失切配参数) +- 建议提供统一的"历史规格字符串 → 结构化对象"解析工具,所有页面共用 + +### 5.5 已消除的隐患 +- 原系统 3 套互不一致的写死规格字典(订单页一份、外售页一份、汇总表一份)已全部删除,统一数据源为"餐品总库" +- 原设备端"斤"作为存储单位导致的下游断链问题已修复 + +--- + +## 六、配套文档 + +| 文档 | 用途 | +|------|------| +| 规格管理体系分析与设计方案 | 设计方案权威文档(架构与决策) | +| 规格体系统一化改造任务清单 | 24 个改造任务的执行手册(含精确文件定位与核查记录) | +| CHANGELOG | 本次变更的完整变更日志 | + +--- + +> 本文档为产品→研发的需求同步说明,仅描述"改了哪些功能",不涉及具体字段名/方法名。研发评估工作量与数据契约时,请结合"改造任务清单"与"设计方案"两份文档对照查阅。 diff --git a/web-admin/nutrition/doc/规格体系统一化改造任务清单.md b/web-admin/nutrition/doc/规格体系统一化改造任务清单.md new file mode 100644 index 0000000..f91eeb0 --- /dev/null +++ b/web-admin/nutrition/doc/规格体系统一化改造任务清单.md @@ -0,0 +1,1094 @@ +# 规格体系统一化改造任务清单 + +> 撰写日期:2026-08-04 | 修订日期:2026-08-04 | 配套文档:[规格管理体系分析与设计方案](./规格管理体系分析与设计方案.md)(v3.1) | 状态:**阶段一、二已完成,阶段三~五方案 v2 修订(基于实际落地核查)** +> +> **v2 修订说明**:阶段一、二落地后,经全面核查发现原方案与现状存在 9 处偏差,涉及跨页数据共享、字段映射、cutSpec 多格式兼容、字典语义错配等。本次重写阶段三~五部分,补充前置任务 3.0、拆分复杂任务、明确字段映射规则。阶段一、二部分保持不变。 +> +> 本文档将设计方案落地为具体可执行的改造任务,按三阶段迁移策略组织,每个任务标注文件路径、改造类型、依赖关系、工作量预估、精确定位。 + +--- + +## 一、总览 + +### 任务统计 + +| 阶段 | 任务数 | 文件数 | 工作量 | 说明 | +|------|-------|--------|--------|------| +| 阶段一 基础设施 | 3 | 3 | ★★★★☆ | 核心前置,需仔细(**已完成**) | +| 阶段二 核心业务 | 4 | 5 | ★★★★☆ | 核心业务页改造(**已完成**) | +| 阶段三 订单包装 | 5(含 3.0 前置) | 7 | ★★★★☆ | 订单与包装链路(v2 新增 3.0 跨页共享前置) | +| 阶段四 设备端 | 9(原 5 拆分) | 14 | ★★★★★ | 最复杂,尤其 4.4(v2 拆分 4.1/4.2) | +| 阶段五 辅助页 | 3 | 5 | ★★☆☆☆ | 可选,低优先级 | +| **合计** | **24 个任务** | **34 个文件** | — | +1 个工具函数文件 | + +### 执行顺序 + +``` +第一批(并行,阶段一全部): + 任务1.1 spec-utils.js (无依赖) + 任务1.2 din-dict-mgmt 新增Tab(无依赖) + 任务1.3 vegTypes 扩展 (依赖1.2,可先做结构,字典数据后填) + +第二批(并行,阶段二核心): + 任务2.1 餐品总库 specs + 任务2.2 sup-in-clean (核心) + 任务2.4 采供/毛菜入库 + +第二批半(阶段三前置,串行): + 任务3.0 跨页 specs 共享机制 ← 阻塞阶段三所有 cp 任务 + +第三批(并行,阶段三): + 任务3.1 净菜订单(依赖 3.0) + 任务3.2 外售/内供(依赖 3.0、3.1) + 任务3.3a 净菜组配(依赖 3.0) + 任务3.3b 按单烹制生熟比(独立) + 任务3.4 包装标签(依赖 3.0) + +第四批(并行,阶段四设备端): + 任务4.1a/4.1b 毛菜验收秤 + 任务4.2a/4.2b/4.2c 毛菜加工秤(斤→克) + 任务4.3 净菜加工秤设置 + 任务4.4 净菜包装贴标秤(最复杂) + 任务4.5 净菜组配秤 + +第五批(可选,阶段五): + 任务5.1 营养质控(依赖 3.0) + 任务5.2 分析页(字典语义修复) + 任务5.3 净菜进柜 +``` + +--- + +--- + +## 二、任务依赖关系图 + +``` +阶段一(基础设施) +───────────────── +任务1.1 spec-utils.js ─┬─→ 任务4.2 raw-veg-processing-scale(用formatGramForCanteen) + └─→ 任务4.4 clean-veg-packaging-labeler(用formatCutSpec) + +任务1.2 din-dict-mgmt ─┬─→ 任务2.1 餐品总库(份型字典) + ├─→ 任务2.4 采供/毛菜入库(包装单位字典) + ├─→ 任务3.1 净菜订单(包装单位字典) + ├─→ 任务3.4 包装标签(包装单位字典) + ├─→ 任务4.1 毛菜验收秤(包装单位字典) + └─→ 任务5.2 分析页(切配类型字典) + +任务1.3 vegTypes 扩展 ─┬─→ 任务2.2 sup-in-clean(核心依赖) + ├─→ 任务2.3 sup-in-cleanin + ├─→ 任务2.4 采供/毛菜入库(L1采购规格) + ├─→ 任务4.3 clean-veg-ratio-scale(默认值) + └─→ 任务3.3 prod-proc-cook(出净率) + + +阶段二(核心业务) +───────────────── +任务2.1 餐品总库 ──────┬─→ 任务3.1 净菜订单(cp下拉) + ├─→ 任务3.3 净菜组配/烹制(餐品L4) + ├─→ 任务4.5 ratio-scale(餐品净菜包) + └─→ 任务5.1 prod-qc-nutrition(同步目标) + +任务2.2 sup-in-clean ─→ 任务2.3 sup-in-cleanin(URL参数) + + +阶段三(订单/组配/包装) +───────────────────── +任务3.1 净菜订单 ─────→ 任务3.2 外售/内供 +任务3.1 净菜订单 ─────→ 任务3.3 组配/烹制(部分依赖) + + +阶段四(设备端) +────────────── +任务4.4 包装贴标秤 ────→ 任务3.4 sup-pkg-label(口径统一) + + +阶段五(辅助页) +────────────── +任务5.1/5.2/5.3 可最后做,不阻塞主流程 +``` + +--- + +## 三、阶段一:基础设施(前置必做) + +### 任务 1.1:抽离统一规格工具函数 `spec-utils.js` ⭐ + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/js/spec-utils.js`(新增) | +| **改造类型** | 新建 | +| **依赖** | 无 | +| **工作量** | 中(约 200 行代码) | +| **优先级** | 🔴 高(基础设施) | + +**交付物**:以下 7 个工具函数 + +```javascript +// 1. 克重展示格式化:500→"500g", 1500→"1.5kg", 25000→"25kg" +function formatGram(g) { + if (g >= 1000 && g % 1000 === 0) return (g / 1000) + 'kg'; + if (g >= 1000) return (g / 1000).toFixed(1) + 'kg'; + return g + 'g'; +} + +// 2. 规格标签格式化:{baseGram:500,unit:'袋'} → "500g/袋" +function formatSpec(spec) { + const w = formatGram(spec.baseGram); + if (spec.unit === '散装') return '散装/' + w; + return w + '/' + spec.unit; +} + +// 3. 切配规格展示:{length:20,width:1,height:1,shape:'丝(细)',technique:'平刀'} +// → "20×1×1mm · 丝(细) · 平刀" +function formatCutSpec(cut) { + if (!cut) return '—'; + const dims = [cut.length, cut.width, cut.height].filter(v => v !== undefined && v !== null && v !== ''); + const dimStr = dims.length ? `${dims.join('×')}mm · ` : ''; + const shapeStr = cut.shape || ''; + const techStr = cut.technique ? ` · ${cut.technique}` : ''; + return `${dimStr}${shapeStr}${techStr}`; +} + +// 4. 历史字符串解析(迁移用): +// "3.5mm*3.5mm*50mm·细丝·平刀" (无空格,* 分隔) +// "20mm*1mm*1mm · 细丝 · 平刀" (带空格,* 分隔) +// "20mm×1mm×1mm · 细丝 · 平刀" (带空格,× 分隔) +// → {length,width,height,shape,technique} +function parseLegacyCutSpec(s) { + if (!s) return null; + // 归一化分隔符:×→*,去掉所有空格 + const normalized = s.replace(/×/g, '*').replace(/\s/g, ''); + // 正则:可选尺寸 · 形状 · 刀工 + const m = normalized.match(/^(?:(\d+(?:\.\d+)?)mm\*(\d+(?:\.\d+)?)mm\*(\d+(?:\.\d+)?)mm)?·?([^·]+)·?([^·]+)?$/); + if (!m) return { shape: s }; // 无法解析则整体作为 shape + return { + length: m[1] ? parseFloat(m[1]) : undefined, + width: m[2] ? parseFloat(m[2]) : undefined, + height: m[3] ? parseFloat(m[3]) : undefined, + shape: m[4] || '', + technique: m[5] || '' + }; +} + +// 5. 向上取整除法(决策点 #5 统一向上取整) +function ceilDiv(numerator, denominator) { + if (!denominator) return 0; + return Math.ceil(numerator / denominator); +} + +// 6. 计算总克重:calcTotalGram({baseGram:500,unitCapacity:1}, qty=10) = 5000 +function calcTotalGram(spec, qty) { + const cap = spec.unitCapacity || 1; + return spec.baseGram * cap * qty; +} + +// 7. 跨单位换算:convertSpec({baseGram:5000,unit:'箱'}, '袋', 500) = 10 (袋) +// 返回:目标单位的数量(向上取整) +function convertSpec(srcSpec, targetUnit, targetCapacity) { + const srcTotal = calcTotalGram(srcSpec, 1); // 单位总量 + const targetBase = targetCapacity || 1; + return ceilDiv(srcTotal, srcSpec.baseGram * 0 + targetBase); // 简化:srcTotal / targetBase +} + +// 8. 验收秤场景兼容"斤"显示:500→"1斤", 25000→"50斤" +function formatGramForCanteen(g) { + if (g % 500 === 0) return (g / 500) + '斤'; + return formatGram(g); +} +``` + +**实施要求**: +- 文件路径:`web-admin/nutrition/js/spec-utils.js` +- 在需要的页面通过 `` 引入 +- 由于本项目是墨刀导入兼容原型,需确认是否允许引用独立 JS 文件;如不允许,则改为在每个页面内联(会增加重复代码,但符合墨刀约束) + +**待确认**:墨刀兼容约束是否允许引用独立 JS?(CLAUDE.md 项目约束提及"禁止外部引用") + +--- + +### 任务 1.2:字典管理页新增"规格"Tab `din-dict-mgmt.html` ⭐ + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/din-dict-mgmt.html`(修改,389 行) | +| **改造类型** | 新增 Tab + 3 个字典区块 | +| **依赖** | 无 | +| **工作量** | 中 | +| **优先级** | 🔴 高(基础设施) | + +**精确定位**(基于核查): +- 第 199 行后追加 `.page-tab`(在 `.page-tabs` 容器内) +- 第 334 行前追加 `.tab-panel`(参考第 312-334 行"业务"Tab 模板,最简洁) +- 第 352 行 `tabNames` 数组追加 `'规格'` + +**交付物**:在字典管理页新增"规格"Tab,下挂 3 个独立字典区块: + +``` +┌─ 规格 Tab ────────────────────────────────────────┐ +│ ▸ 字典 1: 包装单位字典(code=spec_unit) │ +│ 散装 | 件 | 袋 | 盒 | 箱 | 盘 | 份 | 筐 │ +│ 瓶 | 罐 | 桶 | 把 | 个 | 只 | 条 │ +│ 字段:unit / 默认unitCapacity / 是否液体类 │ +│ │ +│ ▸ 字典 2: 切配类型字典(code=spec_cut_shape) │ +│ 丁 | 丝 | 片 | 块 | 段 | 末 | 泥 | 条 │ +│ 字段:shape / 默认尺寸mm / 默认刀工 │ +│ │ +│ ▸ 字典 3: 份型字典(code=spec_portion) │ +│ 标准份 | 小份 | 大份 | 迷你份 | 加大份 │ +│ 字段:specName / 默认baseGram │ +└────────────────────────────────────────────────────┘ +``` + +**实施要求**: +- 沿用现有"字典名称/字典编码/字典分类/描述/创建时间/操作"列结构 +- 每个字典项的"字典配置"链接指向 `din-dict-config.html?code=xxx` +- 当前 `din-dict-mgmt.html` 是静态 HTML(无 JS 数组),新增 Tab 直接复制 HTML 块即可 + +**初始字典数据草案**(待业务方确认): + +| 字典 | 编码 | 字典项(初始) | +|------|------|---------------| +| 包装单位 | spec_unit | 散装/件/袋/盒/箱/盘/份/筐/瓶/罐/桶/把/个/只/条(共15项) | +| 切配类型 | spec_cut_shape | 丁(15mm/直刀)/丝(3mm/斜刀)/片(2mm/平刀)/块(20mm/直刀)/段(50mm/直刀)/末/泥/条(50mm/斜刀)(共8项) | +| 份型 | spec_portion | 标准份(300g)/小份(150g)/大份(500g)/迷你份(100g)/加大份(700g)(共5项) | + +--- + +### 任务 1.3:食材档案 vegTypes 字段扩展 ⭐⭐(核心前置) + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/din-ingredient-add.html`(修改,1000 行)
`web-admin/nutrition/din-ingredient.html`(修改,只读展示) | +| **改造类型** | 字段结构扩展 + 录入表格改造 | +| **依赖** | 任务 1.2(切配类型字典,用于 shape 下拉) | +| **工作量** | 大 | +| **优先级** | 🔴 高(基础设施,后续核心改造的前置) | + +#### A. `din-ingredient-add.html` 改造点 + +##### A1. vegTypes 数据结构扩展 + +影响位置(多处): +- 第 423 行:`var vegTypes = []` 全局声明 +- 第 518/531/537 行:`{name:'',yieldRate:''}` 初始化 +- 第 546 行:push 对象 +- 第 693/704/715/726/737 行:mock 数据(5 个食材) + +```javascript +// 旧:{name:'',yieldRate:''} +// 新:{name:'',yieldRate:'',cutSpec:{shape:'',length:'',width:'',height:'',technique:''}} +``` + +##### A2. 录入表格 HTML 模板扩展(第 520-526 行) + +当前: +```javascript +vegTypes.forEach(function(item,i){ + html += '
'; + html += ''; + html += ''; + html += ''; + html += '
'; +}); +``` + +改造后(6 列): +```javascript +vegTypes.forEach(function(item,i){ + html += '
'; + html += ''; + html += ''; + // 新增:切配形状下拉(从切配类型字典读取) + html += ''; + // 新增:尺寸(3 个数字,部分形状只用1个) + html += ''; + html += ''; + html += ''; + // 新增:刀工下拉 + html += ''; + html += ''; + html += '
'; +}); +``` + +##### A3. saveVegTypes 函数扩展(第 540-548 行) + +增加对新字段的读取与持久化: +```javascript +function saveVegTypes(){ + vegTypes = []; + document.querySelectorAll('#vegTypeRows .dynamic-row').forEach(function(row){ + vegTypes.push({ + name: row.querySelector('.veg-name').value.trim(), + yieldRate: row.querySelector('.veg-yield').value.trim(), + cutSpec: { + shape: row.querySelector('.veg-shape').value, + length: row.querySelector('.veg-len').value ? parseInt(row.querySelector('.veg-len').value) : undefined, + width: row.querySelector('.veg-wid').value ? parseInt(row.querySelector('.veg-wid').value) : undefined, + height: row.querySelector('.veg-hei').value ? parseInt(row.querySelector('.veg-hei').value) : undefined, + technique: row.querySelector('.veg-tech').value + } + }); + }); +} +``` + +##### A4. CSS 调整(第 107-113 行) + +`.dynamic-row` 当前是 flex 布局,所有 `.form-input` 均 `flex:1` 等宽。改造后需支持不等宽列: +```css +/* name 列宽,yieldRate 列窄,shape/size/technique 列中等 */ +.dynamic-row .veg-name { flex: 2; } +.dynamic-row .veg-yield { flex: 1; } +.dynamic-row .veg-shape, +.dynamic-row .veg-tech { flex: 1.2; } +.dynamic-row .veg-len, +.dynamic-row .veg-wid, +.dynamic-row .veg-hei { flex: 0.8; } +``` + +##### A5. Mock 数据补充(第 693/704/715/726/737 行) + +示例(猪里脊): +```javascript +vegTypes:[ + {name:'肉丁', yieldRate:'92', cutSpec:{shape:'丁',length:15,width:15,height:15,technique:'直刀'}}, + {name:'肉丝', yieldRate:'95', cutSpec:{shape:'丝',length:50,width:3,height:3,technique:'斜刀'}}, + {name:'肉片', yieldRate:'97', cutSpec:{shape:'片',length:undefined,width:undefined,height:2,technique:'平刀'}} +] +``` + +#### B. `din-ingredient.html` 改造点 + +详情面板的 vegTypes 只读展示(renderBasicInfo,第 462-468 行): +- 当前:显示 `{name}({yieldRate}%)` 两列 +- 改造后:增加切配规格列,用 `formatCutSpec(cutSpec)` 格式化 + +--- + +## 四、阶段二:核心业务页改造 + +### 任务 2.1:餐品总库 specs 统一 `din-dish-all.html` + `din-dish-add.html` + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/din-dish-all.html`(998 行)
`web-admin/nutrition/din-dish-add.html` | +| **改造类型** | 字段语义统一(保留旧名作别名) | +| **依赖** | 任务 1.2(份型字典) | +| **工作量** | 中 | +| **优先级** | 🔴 高 | + +**改造点**: +- DISHES 数组(第 381/392/403/414/425 行):specs 增加 `baseGram` 字段(保留 `weight` 作兼容别名) +- `renderBasic` 函数(第 472-507 行):表头(第 494 行)增加列,数据行(第 473-479 行)增加对应 `` +- 份型 name 字段从"份型字典"读取(下拉选项来源) +- 预留营养规格字段(承接 prod-qc-nutrition 同步,暂不落地) + +**示例改造**: +```javascript +// 旧: +specs:[ + {name:'标准份', weight:200, price:12, cleanPrice:9, cleanSale:false, isDefault:true} +] +// 新: +specs:[ + {name:'标准份', baseGram:200, weight:200, price:12, cleanPrice:9, cleanSale:false, isDefault:true} + // weight 保留作别名,baseGram 为统一字段 +] +``` + +--- + +### 任务 2.2:净菜加工批次改造 `sup-in-clean.html` ⭐⭐(核心) + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/sup-in-clean.html`(432 行) | +| **改造类型** | 删除硬编码 + 接入食材档案 | +| **依赖** | 任务 1.3(vegTypes 扩展) | +| **工作量** | 中 | +| **优先级** | 🔴 高(核心规格枢纽) | + +**改造点**: + +1. **删除 `FOOD_VEG_MAP` 硬编码**(第 350-355 行): + ```javascript + // 删除: + var FOOD_VEG_MAP={ + '土豆':['土豆丝','土豆片','土豆泥','土豆块'], + ... + }; + ``` + +2. **`onFoodChange()` 改造**(第 356-369 行): + - 数据源从 `FOOD_VEG_MAP[food]` 改为从食材档案按 foodName 查询 vegTypes + - 净菜类型下拉显示从纯字符串改为 `{name} - {formatCutSpec(cutSpec)}`(展示切配参数) + +3. **出净率真实计算**:当前 readonly 输入框(未实现),改造为 `⌈净菜产出/毛菜 × 100⌉` + +4. **反向推导**:输入"净菜需求量"时,自动算出"毛菜重量 = ⌈净菜需求量 / yieldRate⌉` + +5. **表格列改造**(第 216 行表头、第 220-238 行数据行): + - "净菜类型"列可拆分为"净菜类型"+"切配规格"两列(可选,看展示需求) + +6. **`confirmGenStock` 函数**(第 372-384 行): + - 当前基于列索引 `tds[3]` 读取"净菜类型",若列顺序变化需同步更新第 380 行 + +--- + +### 任务 2.3:净菜入库改造 `sup-in-cleanin.html` + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/sup-in-cleanin.html` | +| **改造类型** | 删除硬编码 + 接入食材档案 + UnifiedSpec | +| **依赖** | 任务 1.3(vegTypes 扩展) | +| **工作量** | 中 | +| **优先级** | 🔴 高 | + +**改造点**: +- 删除 `cleanFoodTypeOptions` 硬编码:食材→净菜类型联动改为从 vegTypes 读取 +- 入库规格下拉(`袋装/500g` / `盒装/300g` 等)改为 `baseGram + unit` 结构,从"包装单位字典"读取 unit 选项 +- 接收上游 `sup-in-clean.html` 的 URL 参数增加 cutSpec 字段 + +--- + +### 任务 2.4:采供/毛菜入库改造 `farm-purchase.html` + `sup-in-raw.html` + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/farm-purchase.html`
`web-admin/nutrition/sup-in-raw.html` | +| **改造类型** | 规格字段结构化 + 跨页继承 | +| **依赖** | 任务 1.3(食材档案 L1 采购规格) | +| **工作量** | 中 | +| **优先级** | 🟡 中 | + +**改造点**: +- `farm-purchase.html`:规格从自由文本改为 L1 自动带出(`baseGram + unit`),从食材档案读取 +- `sup-in-raw.html`:入库规格从 7 种固定下拉改为从采购订单继承 L1,无需重选 + +--- + +## 五、阶段三:订单/组配/包装改造(v2 修订) + +> **v2 修订背景**:核查发现 3 套互不相同的 cp 规格硬编码字典(`cpSpecOptions`/`cpSpecOptsExt`/`DISH_SPEC`),且 prod-proc-combo/cook 的规格下拉是"全局固定选项"与所选餐品完全脱钩,原方案的"从总库读取"缺数据接入路径。本阶段新增**任务 3.0 跨页共享前置**,并把 3.3 拆分为 3.3a/3.3b。 + +### 任务 3.0:跨页 specs 共享机制 ⭐⭐(阶段三前置必做,v2 新增) + +| 项 | 内容 | +|---|---| +| **文件** | `web-admin/nutrition/din-dish-all.html`(写入侧)
阶段三 6 个下游页(读取侧) | +| **改造类型** | 新增数据共享层 | +| **依赖** | 任务 2.1(餐品 specs) | +| **工作量** | 中 | +| **优先级** | 🔴 高(阻塞阶段三所有 cp 任务、阶段五 5.1) | + +**改造点**: + +1. **din-dish-all.html 写入 localStorage**(DISHES 渲染后追加): + ```javascript + // 将 DISHES 数组的规格信息序列化到 localStorage,供下游页面读取 + function persistDishSpecs(){ + try { + var simplified = DISHES.map(function(d){ + return { + id: d.id, + name: d.name, + category: d.category, + specs: (d.specs||[]).map(function(s){ + return {portion:s.portion, baseGram:s.baseGram, unit:s.unit||'份'}; + }), + cookedWeight: d.cookedWeight, + yieldRate: d.yieldRate + }; + }); + localStorage.setItem('dish_specs_v1', JSON.stringify({version:1, dishes:simplified, updatedAt:Date.now()})); + } catch(e){ console.warn('persistDishSpecs failed', e); } + } + persistDishSpecs(); // 页面加载后立即执行 + ``` + +2. **下游页封装工具函数**(内联到每个页面 ` diff --git a/web-admin/nutrition/sup-pkg-label.html b/web-admin/nutrition/sup-pkg-label.html index 0dddf44..83bed74 100644 --- a/web-admin/nutrition/sup-pkg-label.html +++ b/web-admin/nutrition/sup-pkg-label.html @@ -108,6 +108,10 @@ tbody tr:hover td.td-actions{background:#F8FBFF;} .form-item textarea{height:auto;min-height:36px;padding:8px 12px;resize:vertical;} .form-item input:focus,.form-item select:focus,.form-item textarea:focus{border-color:var(--primary);} .form-item select{appearance:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;padding-right:28px;} +/* 任务 3.4:规格连体组件(左克重 + 右单位) */ +.spec-input-group{display:flex;align-items:center;gap:0;} +.spec-input-group input{flex:1;border-radius:4px 0 0 4px;} +.spec-input-group select{width:90px;min-width:60px;max-width:110px;border-radius:0 4px 4px 0;margin-left:-1px;} /* 食材动态行 */ .ingredient-list{display:flex;flex-direction:column;gap:8px;} .ingredient-row{display:flex;gap:8px;align-items:center;} @@ -226,12 +230,12 @@ tbody tr:hover td.td-actions{background:#F8FBFF;} 包装批次号溯源码净菜名称包装方式包装规格包装份数包装日期保质期至存放温度(℃)包装人操作类型终端设备操作 - BATCH-NC-20260415-01NC-PROC-BOCA-20260415-01土豆-土豆丝真空袋500202026-04-152026-04-174.1李包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 - BATCH-NC-20260415-01NC-PROC-BOCA-20260415-01土豆-土豆丝真空袋500202026-04-152026-04-174.1李包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 - BATCH-NC-20260415-02NC-PROC-HLUB-20260415-01土豆-土豆丝保鲜盒1000152026-04-152026-04-184.2王包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 - BATCH-NC-20260415-02NC-PROC-HLUB-20260415-01土豆-土豆丝保鲜盒1000152026-04-152026-04-184.2王包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 - BATCH-NC-20260415-03NC-PROC-XGUO-20260415-01土豆-土豆丝散装托盘200082026-04-152026-04-174.0张包装人工录入查看视频 编辑 删除 - BATCH-NC-20260415-04NC-PROC-LAJP-20260415-01土豆-土豆丝真空袋1000122026-04-152026-04-174.3李包装设备自动
真空机-2号
PKG-T02
查看视频 编辑 删除 + BATCH-NC-20260415-01NC-PROC-BOCA-20260415-01土豆-土豆丝真空袋500g/袋202026-04-152026-04-174.1李包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 + BATCH-NC-20260415-01NC-PROC-BOCA-20260415-01土豆-土豆丝真空袋500g/袋202026-04-152026-04-174.1李包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 + BATCH-NC-20260415-02NC-PROC-HLUB-20260415-01土豆-土豆丝保鲜盒1000g/箱152026-04-152026-04-184.2王包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 + BATCH-NC-20260415-02NC-PROC-HLUB-20260415-01土豆-土豆丝保鲜盒1000g/箱152026-04-152026-04-184.2王包装设备自动
真空机-1号
PKG-T01
查看视频 编辑 删除 + BATCH-NC-20260415-03NC-PROC-XGUO-20260415-01土豆-土豆丝散装托盘2000g/箱82026-04-152026-04-174.0张包装人工录入查看视频 编辑 删除 + BATCH-NC-20260415-04NC-PROC-LAJP-20260415-01土豆-土豆丝真空袋1000g/袋122026-04-152026-04-174.3李包装设备自动
真空机-2号
PKG-T02
查看视频 编辑 删除 @@ -351,7 +355,10 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
包装规格*
- +
+ + +
包装份数*
@@ -397,11 +404,11 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
包装餐品*
- +
包装规格*
- +
包装方式*
@@ -528,6 +535,60 @@ document.querySelectorAll('.modal-mask').forEach(m=>{ m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show');}); }); +/* ========== 跨页 specs 共享工具(任务 3.0) ========== */ +function loadDishSpecs(){ + try{ + var raw=localStorage.getItem('dish_specs_v1'); + if(!raw)return null; + var data=JSON.parse(raw); + return (data&&data.dishes)?data.dishes:null; + }catch(e){return null;} +} +function getSpecsByDish(name){ + var dishes=loadDishSpecs(); + if(!dishes)return []; + var d=dishes.find(function(x){return x.name===name;}); + return d?(d.specs||[]):[]; +} +function getAllDishNames(){ + var dishes=loadDishSpecs(); + return dishes?dishes.map(function(d){return d.name;}):[]; +} +/* 包装单位字典(与 spec_unit 字典一致) */ +var SPEC_UNIT_OPTIONS=['克','袋','箱','份','把','瓶','罐','桶','散装']; +function buildUnitOptions(selected){ + var html=''; + SPEC_UNIT_OPTIONS.forEach(function(u){html+='';}); + return html; +} +/* 包装页兜底:若总库未覆盖,用页内默认 */ +var PKG_FALLBACK_DISHES={ + '宫保鸡丁':[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}], + '清蒸鱼':[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}], + '蒜蓉菠菜':[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}], + '炒胡萝卜':[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}], + '红烧排骨':[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}] +}; +function getSpecsByDishWithFallback(name){ + var specs=getSpecsByDish(name); + if(specs&&specs.length>0)return specs; + return PKG_FALLBACK_DISHES[name]||[{portion:'标准份',baseGram:500,unit:'份'},{portion:'大份',baseGram:800,unit:'份'}]; +} +function getDishNamesWithFallback(){ + var names=getAllDishNames(); + if(names&&names.length>0)return names; + return Object.keys(PKG_FALLBACK_DISHES); +} +/* 任务 3.4:按当前餐品动态生成餐品净菜包规格下拉 */ +function buildDishSpecOptions(dishName){ + var specs=getSpecsByDishWithFallback(dishName); + var html=''; + specs.forEach(function(s){ + html+=''; + }); + return html; +} + /* ========== 餐品食材数据 ========== */ var cleanPackFoodTypeOptions={ '土豆':['土豆丝','土豆块','土豆泥'], @@ -574,7 +635,15 @@ function renderOptions(selectEl, placeholder, options){ } function initCleanPackOptions(){ renderOptions(document.getElementById('cleanFoodSelect'),'请选择食材',Object.keys(cleanPackFoodTypeOptions)); + /* 初始化净菜包装单位下拉默认"袋" */ + document.getElementById('cleanPackUnitSelect').innerHTML=buildUnitOptions('袋'); updateCleanPackTypeOptions(); + /* 初始化餐品名下拉(任务 3.4:从总库读取) */ + var dishSel=document.getElementById('dishSelect'); + var names=getDishNamesWithFallback(); + var html=''; + names.forEach(function(n){html+='';}); + dishSel.innerHTML=html; } function updateCleanPackTypeOptions(selectedType){ var foodSelect=document.getElementById('cleanFoodSelect'); @@ -635,12 +704,22 @@ function updateIngredientCleanTypeOptions(foodSelect, selectedType){ var cleanTypeSelect=row.children[2].querySelector('select'); cleanTypeSelect.innerHTML=buildTypeOptions(foodSelect.value, selectedType); } -// 餐品选择变化 → 自动填充食材表格 +// 餐品选择变化 → 自动填充食材表格 + 同步餐品规格下拉 function onDishChange(val){ var ings=dishIngredients[val]||[]; var tbody=document.getElementById('ingFormBody'); - if(ings.length===0){tbody.innerHTML=buildIngRow('','','','','');return;} - tbody.innerHTML=ings.map(function(i){return buildIngRow(i.trace,i.name,i.cleanType,i.type,i.amount);}).join(''); + if(ings.length===0){tbody.innerHTML=buildIngRow('','','','','');}else{ + tbody.innerHTML=ings.map(function(i){return buildIngRow(i.trace,i.name,i.cleanType,i.type,i.amount);}).join(''); + } + /* 任务 3.4:同步餐品净菜包规格下拉 */ + var specSel=document.getElementById('dishPackSpecSelect'); + if(!val){ + specSel.disabled=true; + specSel.innerHTML=''; + }else{ + specSel.disabled=false; + specSel.innerHTML=buildDishSpecOptions(val); + } } // 添加食材行 function addIngRow(){ @@ -669,12 +748,16 @@ function openCleanPackModal(){ document.getElementById('cleanFoodSelect').selectedIndex=0; updateCleanPackTypeOptions(); document.getElementById('cleanPackSpecInput').value=''; + document.getElementById('cleanPackUnitSelect').innerHTML=buildUnitOptions('袋'); openModal('modal-nc'); } function openDishPackModal(){ document.getElementById('modalDhTitle').textContent='新增餐品净菜包'; document.getElementById('dishSelect').selectedIndex=0; document.getElementById('ingFormBody').innerHTML=buildIngRow('','','','',''); + var specSel=document.getElementById('dishPackSpecSelect'); + specSel.disabled=true; + specSel.innerHTML=''; openModal('modal-dh'); } // 新增时重置弹窗标题 diff --git a/web-admin/nutrition/sup-process-analysis.html b/web-admin/nutrition/sup-process-analysis.html index 0ea7e1b..5f0391d 100644 --- a/web-admin/nutrition/sup-process-analysis.html +++ b/web-admin/nutrition/sup-process-analysis.html @@ -232,14 +232,17 @@ tr:hover td{background:#FAFAFA;}
切配线
- +
@@ -261,10 +264,10 @@ tr:hover td{background:#FAFAFA;} 加工时长(min) - 土豆(切丝)切配线-01320.0285.618.88.27.40.0814540 - 胡萝卜(切片)切配线-01180.0162.510.24.52.80.069380 - 猪肉(绞肉)切配线-02500.0452.028.012.57.50.01018620 - 青椒(切块)切配线-02260.0234.514.86.54.20.0610420 + 土豆(丝)切配线-01320.0285.618.88.27.40.0814540 + 胡萝卜(片)切配线-01180.0162.510.24.52.80.069380 + 猪肉(末)切配线-02500.0452.028.012.57.50.01018620 + 青椒(块)切配线-02260.0234.514.86.54.20.0610420
@@ -275,12 +278,21 @@ tr:hover td{background:#FAFAFA;}
包装线
- + +
+
+ +