Files
bj_power/bj_power_mes/internal/logic/stationstate.go
T

117 lines
4.1 KiB
Go
Raw Normal View History

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)
}