Files
bj_power/bj_power_mes/internal/processor/recipe_runtime.go
T

124 lines
3.8 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 processor
import (
"sync"
"bj_power_mes/constants"
)
// StepRuntime 工序运行时(内存表示,从 RecipeStep DB 记录构建)
type StepRuntime struct {
StepID int // 步骤 ID
StepIdStr string // 业务步骤IDstepId 字段)
StepIndex int // 步骤索引(从 0 开始)
StepName string // 步骤名称
StepType constants.StepType // 步骤类型
ResourceType string // 工站设备类型编码(CNC/WASHER_HP/...),手持操作为空
ToolType string // 手持工具类型:SCANNER/LASER,工站操作为空
AllowedResources []string // 允许的设备ID列表
ProcessingParams map[string]any // 加工参数
NextStepDefault string // 默认下一步 stepId(空=顺序+1)
NextStepBranches map[string]string // 条件分支:条件名→stepId
RestoreStep int // 恢复时回退步数(-1=不回退)
StepTimeout int // 工序超时秒数
}
// RecipeRuntime 工艺路线运行时
type RecipeRuntime struct {
RecipeID int
RecipeCode string
TotalSteps int
Steps []StepRuntime
stepIndexMap map[int]int // stepIndex → Steps 切片下标
mu sync.RWMutex
}
// NewRecipeRuntime 从步骤列表构建 RecipeRuntime,建立 stepIndex→下标 索引
func NewRecipeRuntime(recipeID int, recipeCode string, steps []StepRuntime) *RecipeRuntime {
rr := &RecipeRuntime{
RecipeID: recipeID,
RecipeCode: recipeCode,
TotalSteps: len(steps),
Steps: steps,
stepIndexMap: make(map[int]int, len(steps)),
}
for i, s := range steps {
rr.stepIndexMap[s.StepIndex] = i
}
return rr
}
// GetStep 按步骤序号(stepIndex)获取 StepRuntime
func (rr *RecipeRuntime) GetStep(stepIndex int) (StepRuntime, bool) {
rr.mu.RLock()
defer rr.mu.RUnlock()
idx, ok := rr.stepIndexMap[stepIndex]
if !ok {
return StepRuntime{}, false
}
return rr.Steps[idx], true
}
// GetStepById 按业务 stepId 查找 StepRuntime
func (rr *RecipeRuntime) GetStepById(stepId string) (StepRuntime, bool) {
rr.mu.RLock()
defer rr.mu.RUnlock()
for _, s := range rr.Steps {
if s.StepIdStr == stepId {
return s, true
}
}
return StepRuntime{}, false
}
// IsLastStep 判断当前步骤是否为工艺路线的最后一步(比较实际最大 stepIndex,而非 Steps 长度)
func (rr *RecipeRuntime) IsLastStep(stepIndex int) bool {
rr.mu.RLock()
defer rr.mu.RUnlock()
if len(rr.Steps) == 0 {
return true
}
// 用最后一个步骤的 StepIndex,而非 TotalSteps,因为 stepIndex 可能不连续
maxIdx := rr.Steps[len(rr.Steps)-1].StepIndex
for _, s := range rr.Steps {
if s.StepIndex > maxIdx {
maxIdx = s.StepIndex
}
}
return stepIndex >= maxIdx
}
// IsStationStep 判断是否为工站操作步骤(ResourceType 非空)
func (s *StepRuntime) IsStationStep() bool {
return s.ResourceType != ""
}
// IsToolStep 判断是否为手持工具步骤(ToolType 非空)
func (s *StepRuntime) IsToolStep() bool {
return s.ToolType != ""
}
// IsWaitStep 判断是否为设备等待步骤
func (s *StepRuntime) IsWaitStep() bool {
return s.StepType == constants.StepType_Operation
}
// IsUnloadStep 判断是否为下料步骤(Unload 类型)
func (s *StepRuntime) IsUnloadStep() bool {
return s.StepType == constants.StepType_UnloadDock
}
// IsDecisionStep 判断是否为判断/决策步骤(Judge/Decision 类型)
func (s *StepRuntime) IsDecisionStep() bool {
return s.StepType == constants.StepType_Judge || s.StepType == constants.StepType_Decision
}
// FirstStepIndex returns the StepIndex of the first step, or 0 if empty.
func (rr *RecipeRuntime) FirstStepIndex() int {
if len(rr.Steps) == 0 {
return 0
}
return rr.Steps[0].StepIndex
}