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
+49 -21
View File
@@ -9,6 +9,7 @@ import (
"time"
"bj_power_mes/ent"
"bj_power_mes/ent/dailyplan"
"bj_power_mes/ent/flowmaterial"
"bj_power_mes/ent/processflow"
"bj_power_mes/ent/processstep"
@@ -242,24 +243,26 @@ func (s *Service) flowSteps(ctx context.Context, flowId int) []*ProcessStepTempl
// ---------- 工位主数据(块3 ----------
type StationReq struct {
Id int `json:"id"`
StationNo int `json:"stationNo"`
Name string `json:"name"`
StationType *string `json:"stationType"`
FlowId *int `json:"flowId"`
Id int `json:"id"`
StationNo int `json:"stationNo"`
Name string `json:"name"`
StationType *string `json:"stationType"`
FlowId *int `json:"flowId"`
VisibleTabs []string `json:"visibleTabs"` // 终端可见页签(空=全部显示)
}
type StationVO struct {
Id int `json:"id"`
StationNo int `json:"stationNo"`
Name string `json:"name"`
FlowId int `json:"flowId"`
FlowName string `json:"flowName"`
StationType string `json:"stationType"`
Status string `json:"status"`
IsBuiltin bool `json:"isBuiltin"`
HasDock bool `json:"hasDock"`
DockCode string `json:"dockCode"`
Id int `json:"id"`
StationNo int `json:"stationNo"`
Name string `json:"name"`
FlowId int `json:"flowId"`
FlowName string `json:"flowName"`
StationType string `json:"stationType"`
Status string `json:"status"`
IsBuiltin bool `json:"isBuiltin"`
HasDock bool `json:"hasDock"`
DockCode string `json:"dockCode"`
VisibleTabs []string `json:"visibleTabs"`
}
func (s *Service) ListStations(ctx context.Context) ([]*StationVO, error) {
@@ -274,7 +277,7 @@ func (s *Service) ListStations(ctx context.Context) ([]*StationVO, error) {
}
out := make([]*StationVO, 0, len(stas))
for _, st := range stas {
vo := &StationVO{Id: st.ID, StationNo: st.StationNo, Name: st.Name, FlowId: st.FlowId, StationType: st.StationType, Status: st.Status, IsBuiltin: st.IsBuiltin, HasDock: st.HasDock, DockCode: st.DockCode}
vo := &StationVO{Id: st.ID, StationNo: st.StationNo, Name: st.Name, FlowId: st.FlowId, StationType: st.StationType, Status: st.Status, IsBuiltin: st.IsBuiltin, HasDock: st.HasDock, DockCode: st.DockCode, VisibleTabs: st.VisibleTabs}
if f, ok := flowMap[st.FlowId]; ok {
vo.FlowName = f.Name
}
@@ -317,6 +320,9 @@ func (s *Service) SaveStation(ctx context.Context, req StationReq, operator stri
// 页面「新增工位」创建的是非内置工位(可改类型、可删除);内置工位只能由种子/初始化数据产生。
// 是否有接驳台对应实体位置,由内置数据给定,页面新增时一律为 false 且不可手改。
SetIsBuiltin(false).SetHasDock(false)
if len(req.VisibleTabs) > 0 {
cr.SetVisibleTabs(req.VisibleTabs)
}
if req.FlowId != nil && *req.FlowId > 0 {
flow, fErr := s.ctx.EntClient.ProcessFlow.Get(ctx, *req.FlowId)
if fErr != nil {
@@ -365,6 +371,10 @@ func (s *Service) SaveStation(ctx context.Context, req StationReq, operator stri
upd.SetFlowId(0)
}
}
// 终端可见页签:传 nil=不改;传空数组=清空(全部显示);传列表=按配置显示
if req.VisibleTabs != nil {
upd.SetVisibleTabs(req.VisibleTabs)
}
if _, err := upd.Save(ctx); err != nil {
return err
}
@@ -430,12 +440,28 @@ func (s *Service) StationTask(ctx context.Context, stationNo int) (map[string]an
if err != nil {
return nil, errors.New("工位不存在或未配置")
}
// 工位终端可见工单 = 今日已启用排产(CONFIRMED/执行中)且工单已下发/在制(RELEASED/IN_PROGRESS)。
// 与状态机对齐:工单下发=批准生产、排产启用=排进某一天;未下发或未排进今天的工单,终端一律不显示。
orderNos := []string{}
wos, _ := s.ctx.EntClient.WorkOrder.Query().
Where(workorder.StatusIn("CREATED", "RELEASED", "IN_PROGRESS")).
Order(ent.Asc(workorder.FieldID)).Limit(10).All(ctx)
for _, w := range wos {
orderNos = append(orderNos, w.WorkOrderNo)
today := time.Now().Format("2006-01-02")
plans, _ := s.ctx.EntClient.DailyPlan.Query().
Where(dailyplan.PlanDate(today), dailyplan.StatusIn("CONFIRMED", "PROCESSING")).
Order(ent.Asc(dailyplan.FieldID)).All(ctx)
nos := make([]string, 0, len(plans))
seen := map[string]bool{}
for _, p := range plans {
if !seen[p.OrderNo] {
seen[p.OrderNo] = true
nos = append(nos, p.OrderNo)
}
}
if len(nos) > 0 {
wos, _ := s.ctx.EntClient.WorkOrder.Query().
Where(workorder.WorkOrderNoIn(nos...), workorder.StatusIn("RELEASED", "IN_PROGRESS")).
Order(ent.Asc(workorder.FieldID)).All(ctx)
for _, w := range wos {
orderNos = append(orderNos, w.WorkOrderNo)
}
}
// M4:工位终端按「本工位绑定的工艺流程」驱动。
// 产线定义 = 关联工位(station.flow_id+ 工位号 1→12 顺序,已无独立"工艺路线/路线段"对象。
@@ -457,6 +483,8 @@ func (s *Service) StationTask(ctx context.Context, stationNo int) (map[string]an
"flowActive": flow != nil && flow.Status == "ACTIVE",
"steps": steps,
"orderNos": orderNos,
// 终端可见页签(按工位配置;空=全部显示)
"tabs": st.VisibleTabs,
}, nil
}