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
@@ -13,7 +13,6 @@ import (
"bj_power_mes/common/httpx"
"bj_power_mes/ent"
"bj_power_mes/ent/bomitem"
"bj_power_mes/ent/processflow"
"bj_power_mes/ent/processstep"
"bj_power_mes/ent/station"
@@ -267,56 +266,43 @@ func buildModelCard(ctx context.Context, svcCtx *svc.ServiceContext, productType
card.Stations = append(card.Stations, ms)
}
// 5) 物料清单(按 BOM 名称分组;工艺清单经 flow_material + process_flow 映射)
// 5) 物料清单(按工艺分组的工艺物料清单——唯一用料来源)
if productCode != "" {
// 物料编码 → 使用该物料的工艺名列表(工艺物料清单是装配绑定的唯一依据)
flowNames := map[string][]string{}
if fms, e := client.FlowMaterial.Query().All(ctx); e == nil {
flowAll, _ := client.ProcessFlow.Query().All(ctx)
nameById := map[int]string{}
for _, f := range flowAll {
nameById[f.ID] = f.Name
}
for _, fm := range fms {
if n := nameById[fm.FlowId]; n != "" {
flowNames[fm.MaterialCode] = append(flowNames[fm.MaterialCode], n)
}
}
// 物料分组:按工艺分组的工艺物料清单(BOM 已删除,工艺物料清单是唯一用料来源)
flowAll, _ := client.ProcessFlow.Query().All(ctx)
nameById := map[int]string{}
for _, f := range flowAll {
nameById[f.ID] = f.Name
}
items, _ := client.BomItem.Query().
Where(bomitem.ProductCode(productCode)).
Order(ent.Asc(bomitem.FieldBomName), ent.Asc(bomitem.FieldMaterialCode)).All(ctx)
groupIdx := map[string]int{}
for _, it := range items {
name := it.BomName
if name == "" {
name = "默认"
if fms, e := client.FlowMaterial.Query().All(ctx); e == nil {
groupIdx := map[int]int{}
for _, fm := range fms {
name := nameById[fm.FlowId]
if name == "" {
name = "未命名工艺"
}
gi, ok := groupIdx[fm.FlowId]
if !ok {
card.BomGroups = append(card.BomGroups, modelBomGroup{BomName: name})
gi = len(card.BomGroups) - 1
groupIdx[fm.FlowId] = gi
}
card.BomGroups[gi].Items = append(card.BomGroups[gi].Items, modelBomItem{
MaterialCode: fm.MaterialCode,
MaterialName: fm.MaterialName,
Spec: fm.Spec,
Unit: fm.Unit,
ManageMode: manageModeCN(fm.ManageMode),
FlowNames: name,
UnitQty: f2s(fm.UnitQty),
LossRate: f2s(fm.LossRate),
RequiredQty: "-",
})
}
gi, ok := groupIdx[name]
if !ok {
card.BomGroups = append(card.BomGroups, modelBomGroup{BomName: name})
gi = len(card.BomGroups) - 1
groupIdx[name] = gi
}
fnames := "-"
if ns := flowNames[it.MaterialCode]; len(ns) > 0 {
fnames = strings.Join(ns, "、")
}
card.BomGroups[gi].Items = append(card.BomGroups[gi].Items, modelBomItem{
MaterialCode: it.MaterialCode,
MaterialName: it.MaterialName,
Spec: it.Spec,
Unit: it.Unit,
ManageMode: manageModeCN(it.ManageMode),
FlowNames: fnames,
UnitQty: f2s(it.UnitQty),
LossRate: f2s(it.LossRate),
RequiredQty: f2s(it.RequiredQty),
})
}
}
card.Summary = fmt.Sprintf("共 %d 个工位、%d 项检验卡项、%d 份物料清单",
card.Summary = fmt.Sprintf("共 %d 个工位、%d 项检验卡项、%d 个工艺物料分组",
card.StationCount, len(card.CheckItems), len(card.BomGroups))
return card, nil
}