approveflow/app/provider/flow_definition/model_approval_step.go

178 lines
5.5 KiB
Go

package flow_definition
import (
"approveflow/app/base"
"approveflow/app/provider/abstract/connect"
"approveflow/app/utils"
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/pkg/errors"
)
// ApprovalStep 审批步骤表
type ApprovalStep struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` // 主键ID
FlowID int64 `gorm:"index;not null" json:"flow_id"` // 所属流程ID
Name string `gorm:"type:varchar(100);not null" json:"name"` // 步骤名称
StepCode string `gorm:"type:varchar(100)" json:"step_code"` // 步骤编号用于标识特殊的审批节点
Rules []*ApprovalRule `gorm:"foreignKey:StepID;constraint:OnDelete:CASCADE" json:"rules"` // Foreign key for Rules
DynamicConfig *DynamicApprovalStepConfig `gorm:"foreignKey:StepID;constraint:OnDelete:CASCADE" json:"dynamic_config"` // One-to-one with DynamicConfig
PathConfigs []*ApprovalPathConfig `gorm:"foreignKey:NodeID;constraint:OnDelete:CASCADE" json:"path_configs"` // 路径配置集合
base.Model
}
func (step *ApprovalStep) GetPathConfigs() []connect.AbstractNodePathConfig {
abstractConfigs := make([]connect.AbstractNodePathConfig, len(step.PathConfigs))
for i, config := range step.PathConfigs {
abstractConfigs[i] = config // 直接赋值,因为 ApprovalPathConfig 实现了 AbstractNodePathConfig
}
return abstractConfigs
}
func (step *ApprovalStep) SetPathConfigs(configs []connect.AbstractNodePathConfig) {
convertedConfigs, err := utils.ConvertToSpecificType(configs, func(item connect.AbstractNodePathConfig) (*ApprovalPathConfig, bool) {
specificConfig, ok := item.(*ApprovalPathConfig)
return specificConfig, ok
})
if err != nil {
panic(fmt.Sprintf("Error in SetPathConfigs: %v", err))
}
for _, path := range step.PathConfigs {
path.Delete()
}
step.PathConfigs = convertedConfigs
}
func (step *ApprovalStep) GetKey() string {
return step.Key
}
func (step *ApprovalStep) MarshalBinary() ([]byte, error) {
return json.Marshal(step)
}
func (step *ApprovalStep) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, step)
}
func NewApprovalStep(name string) *ApprovalStep {
step := &ApprovalStep{
Name: name,
Rules: make([]*ApprovalRule, 0),
PathConfigs: make([]*ApprovalPathConfig, 0),
}
step.Key = uuid.New().String()
return step
}
func NewStepWithDynamicConfig(name string, DynamicConfig *DynamicApprovalStepConfig) *ApprovalStep {
step := &ApprovalStep{
Name: name,
DynamicConfig: DynamicConfig,
Rules: make([]*ApprovalRule, 0),
PathConfigs: make([]*ApprovalPathConfig, 0),
}
return step
}
func (step *ApprovalStep) AddDynamicConfig(config *DynamicApprovalStepConfig) *ApprovalStep {
step.DynamicConfig = config
return step
}
func (step *ApprovalStep) GetPathById(pathID int64) (*ApprovalPathConfig, error) {
for _, path := range step.PathConfigs {
if path.ID == pathID {
return path, nil
}
}
return nil, errors.New("Path not found")
}
func (step *ApprovalStep) GetRuleById(ruleId int64) (*ApprovalRule, error) {
for _, rule := range step.Rules {
if rule.ID == ruleId {
return rule, nil
}
}
return nil, errors.New("rule not found")
}
// AddRule 添加审批规则
func (step *ApprovalStep) AddRule(rule *ApprovalRule) error {
for _, r := range step.Rules {
if r.ID == rule.ID {
return fmt.Errorf("rule with ID %d already exists in step", rule.ID)
}
}
step.Rules = append(step.Rules, rule)
return nil
}
// RemoveRule 删除审批规则
func (step *ApprovalStep) RemoveRule(ruleID int64) error {
for i, r := range step.Rules {
if r.ID == ruleID {
step.Rules = append(step.Rules[:i], step.Rules[i+1:]...)
return nil
}
}
return fmt.Errorf("rule with ID %d not found in step", ruleID)
}
// SetDynamicConfig 设置动态审批配置
func (step *ApprovalStep) SetDynamicConfig(config *DynamicApprovalStepConfig) {
step.DynamicConfig = config
}
// AddPathConfig 添加路径配置
func (step *ApprovalStep) AddPathConfig(pathConfig *ApprovalPathConfig) error {
for _, p := range step.PathConfigs {
if p.ID == pathConfig.ID {
return fmt.Errorf("path config with ID %d already exists in step", pathConfig.ID)
}
}
pathConfig.NodeID = step.ID
step.PathConfigs = append(step.PathConfigs, pathConfig)
return nil
}
// RemovePathConfig 删除路径配置
func (step *ApprovalStep) RemovePathConfig(pathConfigID int64) error {
for i, p := range step.PathConfigs {
if p.ID == pathConfigID {
step.PathConfigs = append(step.PathConfigs[:i], step.PathConfigs[i+1:]...)
return nil
}
}
return fmt.Errorf("path config with ID %d not found in step", pathConfigID)
}
// GetNextStepIDs 根据条件获取下一步审批步骤ID列表
func (step *ApprovalStep) GetNextStepIDs(data map[string]interface{}) ([]string, error) {
var nextStepKeys []string
for _, pathConfig := range step.PathConfigs {
met, err := pathConfig.IsConditionMet(data)
if err != nil {
return nil, err
}
if met {
nextStepKeys = append(nextStepKeys, pathConfig.ToNodeKey)
if !pathConfig.IsParallel {
break // 非并行时,只取第一个满足条件的路径
}
}
}
return nextStepKeys, nil
}
func (step *ApprovalStep) GetPathByToKey(toStepKey string) (*ApprovalPathConfig, bool) {
for _, pathConfig := range step.PathConfigs {
if pathConfig.ToNodeKey == toStepKey {
return pathConfig, true
}
}
return nil, false
}