Files
bj_power/bj_power_mes/internal/logic/stationstate.go
T
SunYF d609ff8a9e refactor: 重构工艺工序相关命名与数据模型
1.  全局替换"工序"为"工艺"统一术语,包括页面文案、枚举、注释
2.  重构工单与工件工艺数据模型:
    - 新增工艺组合表flow_material作为备料/齐套唯一源头
    - 新增工位状态表station_state支持自主停单/恢复接单
    - 移除station_process派工表,改用工单工艺组合作为路线唯一源头
    - 替换processCode为flowId作为工艺关联标识
    - 重构工件当前进度字段为currentStationNo
3.  删除冗余的静态备份资源文件
4.  调整物料选择组件默认启用仅显示激活物料
5.  优化工单创建/编辑逻辑,新增工艺组合校验与保存
2026-09-22 11:32:29 +08:00

117 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}