refactor: 重构工艺工序相关命名与数据模型

1.  全局替换"工序"为"工艺"统一术语,包括页面文案、枚举、注释
2.  重构工单与工件工艺数据模型:
    - 新增工艺组合表flow_material作为备料/齐套唯一源头
    - 新增工位状态表station_state支持自主停单/恢复接单
    - 移除station_process派工表,改用工单工艺组合作为路线唯一源头
    - 替换processCode为flowId作为工艺关联标识
    - 重构工件当前进度字段为currentStationNo
3.  删除冗余的静态备份资源文件
4.  调整物料选择组件默认启用仅显示激活物料
5.  优化工单创建/编辑逻辑,新增工艺组合校验与保存
This commit is contained in:
SunYF
2026-09-22 11:32:29 +08:00
parent 932700ca65
commit d609ff8a9e
185 changed files with 8623 additions and 4501 deletions
+116
View File
@@ -0,0 +1,116 @@
package logic
import (
"context"
"errors"
"fmt"
"strings"
"bj_power_mes/ent"
"bj_power_mes/ent/stationstate"
"bj_power_mes/ent/workorder"
)
// ---------- 工位停单(station_state,只认当天) ----------
// SetStationPause 工人自主停单/恢复(某工位当天停止/恢复接单)。
// upsertstationNo+date 唯一;恢复=标记可用即续走,工单/组合/排产三要素零变动。
// 停单瞬间做「工艺全停」判定:某工艺绑定的全部工位当天都停单 → 报警(flow_all_paused)+事件日志。
func (s *Service) SetStationPause(ctx context.Context, stationNo int, paused bool, reason, operator string) error {
if stationNo <= 0 {
return errors.New("stationNo 必填")
}
date := TodayStr()
exist, err := s.ctx.EntClient.StationState.Query().
Where(stationstate.StationNo(stationNo), stationstate.Date(date)).Only(ctx)
if err != nil && !ent.IsNotFound(err) {
return err
}
if exist == nil {
if err := s.ctx.EntClient.StationState.Create().
SetStationNo(stationNo).SetDate(date).SetPaused(paused).
SetReason(reason).SetOperator(operator).Exec(ctx); err != nil {
return err
}
} else {
if err := s.ctx.EntClient.StationState.UpdateOneID(exist.ID).
SetPaused(paused).SetReason(reason).SetOperator(operator).Exec(ctx); err != nil {
return err
}
}
action := "工位恢复接单"
eventType := "station.respawn"
if paused {
action = "工位停止接单(停单)"
eventType = "station.pause"
}
s.ctx.EventLog.Write(ctx, eventType, "", operator, "station_state", itoa(stationNo),
fmt.Sprintf("%s(工位%d%s", action, stationNo, date),
map[string]any{"stationNo": stationNo, "date": date, "paused": paused, "reason": reason})
if paused {
s.checkAllPausedFlows(ctx, operator)
}
return nil
}
// checkAllPausedFlows 工艺全停判定:执行中工单的组合里,某工艺涉及的全部工位当天都停单 → 报警+日志。
// (上位机在该工艺全停期间不下发流转指令;恢复=任一工位恢复即续走。)
func (s *Service) checkAllPausedFlows(ctx context.Context, operator string) {
wos, err := s.ctx.EntClient.WorkOrder.Query().
Where(workorder.Status("IN_PROGRESS")).All(ctx)
if err != nil {
return
}
for _, wo := range wos {
items, _ := RouteStationsFromWO(ctx, s.ctx.EntClient, wo)
if len(items) == 0 {
continue
}
byFlow := map[int][]int{}
for _, it := range items {
byFlow[it.FlowId] = append(byFlow[it.FlowId], it.StationNo)
}
for flowId, stations := range byFlow {
allPaused := len(stations) > 0
parts := make([]string, 0, len(stations))
for _, no := range stations {
parts = append(parts, itoa(no))
if !s.GetStationPaused(ctx, no) {
allPaused = false
}
}
if !allPaused {
continue
}
content := fmt.Sprintf("工艺「%s」的全部工位(%s)已停单,上位机不下发流转指令",
s.flowNameById(ctx, flowId), strings.Join(parts, ","))
_, _ = s.ctx.EntClient.Alert.Create().
SetRuleId(0).SetType("flow_all_paused").SetTitle("工艺全停").
SetContent(content).SetRefType("process_flow").SetRefId(fmt.Sprintf("%d", flowId)).
SetOrderNo(wo.WorkOrderNo).SetReceiver("").SetStatus("UNREAD").Save(ctx)
s.ctx.EventLog.Write(ctx, "flow.all_paused", wo.WorkOrderNo, operator, "process_flow", itoa(flowId),
content, map[string]any{"flowId": flowId, "stations": stations})
}
}
}
// GetStationPaused 某工位当天是否停单(无记录=未停单)
func (s *Service) GetStationPaused(ctx context.Context, stationNo int) bool {
if stationNo <= 0 {
return false
}
rows, err := s.ctx.EntClient.StationState.Query().
Where(stationstate.StationNo(stationNo), stationstate.Date(TodayStr()), stationstate.Paused(true)).
Limit(1).All(ctx)
return err == nil && len(rows) > 0
}
// ListStationStates 查询停单状态列表(date 空取当天)
func (s *Service) ListStationStates(ctx context.Context, date string) ([]*ent.StationState, error) {
if date == "" {
date = TodayStr()
}
return s.ctx.EntClient.StationState.Query().
Where(stationstate.Date(date)).
Order(ent.Asc(stationstate.FieldStationNo)).All(ctx)
}