feat: 重构BOM架构,新增基础设置与虚拟工位管理功能

本次重构删除原有BOM物料清单表,改用工单工艺组合×工艺物料清单作为唯一用料来源;新增系统基础设置表支持WMS地址、日志保留天数等配置,新增虚拟工位作业管理后台接口与前端页签控制功能,同时优化工位号校验逻辑、事件日志自动清理与工单用料查询能力。
This commit is contained in:
SunYF
2026-09-23 11:41:28 +08:00
parent d3eda6b588
commit f274da044c
74 changed files with 3637 additions and 5586 deletions
+32 -24
View File
@@ -81,26 +81,6 @@ export const helpDailyPlan = {
]
}
export const helpBom = {
title: '产品物料清单',
overview:
'物料清单 = 生产 1 台该产品需要哪些物料、各用多少。\n按「产品编号 + 物料清单名称」维护:同一产品编号可并存多份物料清单(选用制)——不同厂家供货、含半成品的结构差异,都用不同的物料清单名称区分(缺省叫「默认」,不用 V1/V2 版本号)。\n工单建单时选定其中一份,之后该工单的备料算料、装机绑定校验都锁定这份物料清单,不同厂家的料单互不串。\n\n与 WMS 的关系:本页(MES)只维护「产品由哪几种料、各用几个」;每种物料叫什么、规格、按序列号还是按批次管理、库存有多少,统一在 WMS(库房)的「物料档案」里维护,两套系统互相解耦、通过图号对齐。\n\n编码对应规则:本页的「图号」必须与 WMS 物料档案里的「图号」完全一致;「管理方式」也要对应(电气件=SN 逐件,结构件=批次)。编码对不上,WMS 将无法为对应工单备料/出库。\n\n保护规则:某份物料清单一旦被工单选用过,就不允许再从中移除物料(防止历史工单追溯断链);新建/改名的物料清单名称在本页「物料清单名称」下拉直接输入即可创建。\n\n数据链路:先建「物料档案」→ 到本页选产品编号 + 命名物料清单,逐条添加物料 → 建工单时选定物料清单 → 仓库才能为对应工单领料。',
fields: [
{ name: '物料清单名称', source: '下拉选择/输入(可搜索,输入新名即创建)。缺省「默认」。', purpose: '同一产品编号下多份物料清单的区分名,工单建单时按此选定', fill: '如「默认」「A厂料单」「含半成品」;同一型号下名称唯一' },
{ name: '产品编号', source: '下拉选择。来自「物料档案」里建的编码。', purpose: '要为哪个产品配置物料清单', fill: '在查询区或「添加物料」弹窗里选择产品编号' },
{ name: '图号', source: '手工填写。必须与 WMS(库房) 物料档案的图号一致。', purpose: '该物料在库房的全库唯一编码,两系统靠它关联', fill: '如 螺丝=GJ-LUOSI-M16;图号对不上 WMS 将无法备料' },
{ name: '物料名称', source: '手工填写。', purpose: '物料中文名,便于识别', fill: '如 十字螺丝、主控芯片' },
{ name: '规格', source: '手工填写。', purpose: '物料规格型号', fill: '如 M16×80 / SMT-48脚' },
{ name: '单位', source: '手工填写。', purpose: '计量单位,用于算量', fill: '个 / 件 / 套 / kg' },
{ name: '管理方式', source: '单选。按物料类型决定,与 WMS 一致。', purpose: '电气件=逐件按SN管理;结构件=按批次管理', fill: '电气件/电子件选"序列号";螺丝等标准件选"批次"' },
{ name: '单台用量', source: '手工填写。', purpose: '生产 1 台产品用的该物料数量', fill: '如每台 8 颗螺丝 → 填 8' },
{ name: '损耗率%', source: '手工填写。', purpose: '考虑报废/损耗的加放比例', fill: '如 2% 填 2;0=不计算损耗' },
{ name: '需求量', source: '自动计算 = 数量×单台用量×(1+损耗率),可覆盖。', purpose: '该物料总需求,出库不能超它', fill: '一般自动算,不必改' },
{ name: '相关标准', source: '手工填写/导入带入。', purpose: '该物料对应的检验/工艺标准(如国标、图号标准),供质量检验与流程卡引用', fill: '如 GB/T xxx;可在导入模板中一列填入' },
{ name: '导入', source: 'Excel 模板导入(列表页「导入」按钮)。', purpose: '批量维护物料清单,减少逐条录入', fill: '下载模板→填写→上传,系统预检(编码/管理方式/数值)并提示错误行,确认后入库' }
]
}
export const helpMaterial = {
title: '备料单(按日排产自动算料)',
overview:
@@ -222,11 +202,39 @@ export const helpStation = {
{ name: '接驳台', source: '内置数据给定(对应实体位置),不可手动更改。', purpose: '该工位位置是否有接驳台', fill: '只读' },
{ name: '接驳台编码', source: '系统预置(种子初始化),与工位 1:1。', purpose: '该工位绑定的接驳台唯一标识', fill: '只读;由种子初始化,页面不可更改' },
{ name: '绑定工艺', source: '本页下拉选择「启用」的工艺即完成绑定。', purpose: '该工位执行的工艺(决定工艺步骤/考核标准/PDF/物料清单);一个工位只能绑定一个工艺', fill: '在本页下拉为该工位选择启用工艺;工单执行路线由工单工艺组合决定' },
{ name: '终端可见页签', source: '本页「页签」按钮配置(station.visibleTabs)。', purpose: '该工位终端允许显示哪些功能页签(上线建档/作业/物料/移料/工艺文件/巡检/下线完工),按工位差异化界面', fill: '点「页签」勾选;全部不勾 = 显示全部页签,保存后终端下次拉取任务生效' },
{ name: '删除', source: '本页操作。', purpose: '删除自定义工位', fill: '仅自定义工位可删除;内置工位不允许删除' },
{ name: '虚拟工位 0 / 13', source: '系统预置。工位号 0=上线位、13=下线位。', purpose: '产线进线口建档上线、出料口完工入库,由 PAD 操作,不连 PLC/拧紧枪', fill: '只读;上线位/下线位在工位终端(PAD)用「上线建档」「下线完工」面板操作' }
]
}
export const helpVirtualStation = {
title: '虚拟工位作业(MES 后台人工报工)',
overview:
'虚拟工位 = 没有终端硬件(无屏、无 PLC、无拧紧枪)的工位(如包装等辅助工序,线下位类型)。这类工位无法用工位终端,由操作人用自己的手机/电脑登录 MES 后台,在本页完成作业:选择自己的虚拟工位 → 选工单、扫/输工件SN → 查看当前工艺步骤与应绑配料 → 逐项录入 → 点「完成报工」。\n\n与工位终端走同一套接口与校验(/station/task、/station/report):齐套校验、检测确认校验、不可倒序报工等规则完全一致;拧紧步骤因无硬件不在本页采集(由物理工位拧紧枪采集)。\n\n权限:菜单「虚拟工位作业」按账号开通(角色管理勾选 produce.virtualstation),不给普通账号开「工位绑定」等管理菜单即可。',
fields: [
{ name: '选择虚拟工位', source: '下拉来自「工位绑定」页维护的工位(建议给虚拟工序建线下位类型工位)。', purpose: '报工落在哪个工位(报工校验工位必须在工单工艺组合中)', fill: '选择自己负责的虚拟工位' },
{ name: '工单', source: '今日已启用日排产且工单已下发/在制(与终端口径一致)。', purpose: '本工位今天该干哪些工单', fill: '选择当前作业的工单' },
{ name: '工件SN', source: '上线建档时系统生成的工件唯一码(标签/二维码)。', purpose: '定位工件与所属工单,报工/绑定都挂在 SN 下', fill: '扫码或手输后回车载入' },
{ name: '工艺步骤', source: '工位绑定工艺的步骤模板(工艺页维护)。', purpose: '本工位要做什么、考核标准是什么', fill: '手填步骤逐项录入数值/结果;「检测确认」步骤需勾选;拧紧步骤由物理工位采集,本页只读' },
{ name: '配料', source: '工艺物料清单(flow_material)中该工艺要求装配的物料 + 已绑记录(bind-panel 接口)。', purpose: '装机绑定强校验:电气件需绑满单台用量 SN、结构件至少绑一个批次号,缺料不允许报工', fill: '在录入框填批次号/SN(多个用逗号分隔),随报工一次性提交' },
{ name: '完成报工', source: 'POST /station/report(与终端同一接口)。', purpose: '写实绩 + 步骤考核 + 装机绑定,原子提交', fill: '全部录入后点「完成报工」;报错按提示补齐' }
]
}
export const helpSettings = {
title: '基础设置(系统管理员)',
overview:
'运行参数集中配置页,保存即生效(无需重启服务)。库存查询、缺料补货、可生产套数、排产支撑均为实时计算:库存实时来自 WMS,需求按「日排产 × 工单工艺组合」现场汇总,MES 不落库存/需求表,所以改配置立刻影响下一次计算。\n\n可配置项:\n· WMS 地址(IP:端口):保存后热切换,所有库存查询/扣账/台账同步即刻走新地址;「测试连通」只试测不保存,失败不影响当前配置。\n· 需求窗口天数:缺料补货/未来需求按日排产取未来 N 天(默认 5),WMS 备料四态「预警」数据源。\n· 外推均值窗口 / 外推封顶:排产支撑在排产日耗尽仍有余量时,按近 N 天平均日需求外推,封顶防死循环。\n· 事件日志保留天数:超过保留期的操作日志每小时自动清理,0=不清理。\n\n本机基础信息(只读):主机名/内网 IP、服务监听地址、数据库、当前生效 WMS 地址、Go 版本、启动时间。\n\n安全边界:JWT 密钥、WMS Token、数据库密码等敏感信息一律留在 etc/bj_power_mes-api.yaml,不进本页(不在库里明文存密)。',
fields: [
{ name: 'WMS 地址', source: '手工填写(sys_config: wms.base_url),留空=用 YAML 配置/默认 127.0.0.1:9091。', purpose: '库存查询/扣账/半成品流转/台账同步的 WMS 服务地址,保存即热切换', fill: '如 http://192.168.1.100:9091;先用「测试连通」验证再保存' },
{ name: '需求窗口天数', source: '数字(sys_config: demand.days,默认 5)。', purpose: '缺料补货/未来需求 = 未来 N 天日排产 × 工单单台含损耗用量', fill: '1~60 天;改大可提前看到更远期备料需求' },
{ name: '外推均值窗口', source: '数字(sys_config: producible.extrap.window,默认 3)。', purpose: '排产支撑外推取最近 N 天平均日需求', fill: '1~30 天' },
{ name: '外推封顶', source: '数字(sys_config: producible.extrap.cap,默认 365)。', purpose: '排产支撑外推最多算 N 天,防死循环', fill: '30~3650 天' },
{ name: '事件日志保留天数', source: '数字(sys_config: eventlog.retention.days,默认 0=不清理)。', purpose: '操作日志超期自动清理(每小时检查一次)', fill: '如 180 = 保留半年;0 = 永不清理' }
]
}
export const helpDock = {
title: '接驳台维护(只读主数据)',
overview:
@@ -456,9 +464,9 @@ export const helpProcessCard = {
export const helpQuality = {
title: '质量检验(过程检 / 完工检)',
overview:
'质量检验 = 对物料/产品做检验判定并留痕,分「过程检」与「完工检」两个 Tab。来料检在 WMS 库房侧完成,本页不重复。\n\n录入流程:选图号(输入图号或名称远程检索物料清单,自动带出物料名称)→ 填报检单号/生产厂家/检验单号 → 上传附件 → 判定合格/不合格 → 保存。\n\n不合格闭环:结论为「不合格」时可当场选择处置方式(退货/返修/退换)并写处置说明;也可在列表操作列「处置」补录,或点「不合格单」一键导出《不合格单.xlsx》(预填本次检验数据)。\n\n查询:图号 / 物料名称 / 报检单号 / 记录日期范围组合筛选,每个框内模糊匹配、多框取交集;记录按时间倒序,后端真分页。',
'质量检验 = 对物料/产品做检验判定并留痕,分「过程检」与「完工检」两个 Tab。来料检在 WMS 库房侧完成,本页不重复。\n\n录入流程:选图号(输入图号或名称远程检索 WMS 物料档案,自动带出物料名称)→ 填报检单号/生产厂家/检验单号 → 上传附件 → 判定合格/不合格 → 保存。\n\n不合格闭环:结论为「不合格」时可当场选择处置方式(退货/返修/退换)并写处置说明;也可在列表操作列「处置」补录,或点「不合格单」一键导出《不合格单.xlsx》(预填本次检验数据)。\n\n查询:图号 / 物料名称 / 报检单号 / 记录日期范围组合筛选,每个框内模糊匹配、多框取交集;记录按时间倒序,后端真分页。',
fields: [
{ name: '图号', source: '远程检索物料清单(/quality/bom-material),也可手填。', purpose: '被检物料的图号(即 WMS 物料档案的图号)', fill: '输入图号或名称关键字选择' },
{ name: '图号', source: '远程检索 WMS 物料档案(/materials 代理接口,WMS 是物料主数据源),也可手填。', purpose: '被检物料的图号(即 WMS 物料档案的图号)', fill: '输入图号或名称关键字选择' },
{ name: '物料名称', source: '选图号后自动带出,可手改。', purpose: '被检物料名称', fill: '一般无需手填' },
{ name: '报检单号', source: '系统自动生成(RQ+时间戳),可改。', purpose: '本次报检的唯一编号,也是附件挂靠键', fill: '一般无需改,须唯一' },
{ name: '生产厂家', source: '手工填写。', purpose: '该物料的生产/供货厂家', fill: '如 XX电气有限公司' },
@@ -523,12 +531,12 @@ export const helpAttachment = {
export const helpProducible = {
title: '排产支撑',
overview:
'把「库存还能撑多久」算清楚,给计划员排产/叫料决策用。数据来源:日排产(daily_plan)× 工单(work_order)× BOM(产品物料清单)得到需求量,库存可用量实时来自 WMS(/api/internal/stock/check)。\n\n本页两块:\n· 各成品可生产套数:只统计启用产品(停用产品不再展示产能,列表分页展示);按每个成品的 BOM 单台用量 ÷ 对应物料 WMS 可用量取最小值,即当前库存最多还能装出多少台该成品;短板说明列出限制它的物料(可用量 ÷ 单台用量 = 套数)。\n· 整体支撑:用 WMS 可用量对日排产做逐日消耗模拟,直到某物料不足,得出「还能满产多少天」「库存可支撑到哪天」「最先告罄的短板物料」;排产只排到 N 天时,第 N+1 天起用近3天平均日需求外推(封顶365天防死循环)。\n\n无排产计划时短板物料栏显示「无排产计划」;排产日全部满足且外推无有效需求时显示「充足」。本页只读,不落库。',
'把「库存还能撑多久」算清楚,给计划员排产/叫料决策用。数据来源:日排产(daily_plan,按排产日期窗口、剔除已取消排产)× 工单(work_order)× 工单工艺组合 × 工艺物料清单(flow_material)得到需求量,库存可用量实时来自 WMS(/api/internal/stock/check)。注意:物料需求跟着工单走(同成品不同工单可用不同工艺),且一律按日排产口径计算,工单起止日期仅作参考。\n\n本页两块:\n· 各成品可生产套数:只统计有未取消日排产的工单;按该工单工艺组合的物料单台含损耗用量 ÷ 对应物料 WMS 可用量取最小值,即当前库存最多还能装出多少台;短板说明列出限制它的物料(可用量 ÷ 单台用量 = 套数)。\n· 整体支撑:用 WMS 可用量对日排产做逐日消耗模拟,直到某物料不足,得出「还能满产多少天」「库存可支撑到哪天」「最先告罄的短板物料」;排产只排到 N 天时,第 N+1 天起用近3天平均日需求外推(封顶365天防死循环)。\n\n无排产计划时短板物料栏显示「无排产计划」;排产日全部满足且外推无有效需求时显示「充足」。本页只读,不落库。',
fields: [
{ name: '还能满产(天)', source: '逐日消耗模拟算得(/api/v1/production/producible-support)。', purpose: '一眼看出按当前排产节奏库存能撑几天', fill: '=0 表示今天/近期排产即缺料,需立即补料' },
{ name: '库存可支撑到', source: '支撑天数 + 今日日期推算。', purpose: '给出最晚需要到货的日期', fill: '只读;格式 YYYY-MM-DD' },
{ name: '最先告罄短板物料', source: '模拟中第一个被耗尽的物料(名称+编码)。', purpose: '指出最该优先补货的物料', fill: '「无排产计划」/「充足」表示暂无瓶颈' },
{ name: '可生产套数', source: '逐成品计算(只算启用产品,停用产品不展示):min(各物料可用量 ÷ 单台用量)。', purpose: '该成品当前库存能装出的最多台数', fill: '=0 表示关键物料已缺,无法开线' },
{ name: '可生产套数', source: '逐工单计算(只算有未取消日排产的工单):min(各物料可用量 ÷ 单台含损耗用量)。', purpose: '该工单当前库存能装出的最多台数', fill: '=0 表示关键物料已缺,无法开线' },
{ name: '短板说明', source: '限制该成品可生产套数的物料明细(可用量÷单台用量=套数)。', purpose: '定位缺哪料、缺多少', fill: '只读;多短板时最多列前3个' }
]
}