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

124 lines
3.8 KiB
Go
Raw Normal View History

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
}