approveflow/app/provider/flow_definition/model_approval_flow.go

165 lines
5.0 KiB
Go

package flow_definition
import (
"approveflow/app/base"
"approveflow/app/provider/abstract/connect"
"approveflow/app/utils"
"encoding/json"
"fmt"
)
// ApprovalFlow 审批流程表
type ApprovalFlow struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` // 主键ID
Name string `gorm:"type:varchar(100);not null" json:"name"` // 流程名称
Description string `gorm:"type:text" json:"description"` // 流程描述
Steps []*ApprovalStep `gorm:"foreignKey:FlowID;constraint:OnDelete:CASCADE" json:"steps"` // 流程步骤
NodeMap map[string]connect.AbstractNode `gorm:"-" json:"node_map"` // 流程步骤
TenantKey string `gorm:"type:varchar(50);not null" json:"tenant_key"`
base.Model // 通用字段,包括创建时间、更新时间等
}
func (flow *ApprovalFlow) GetNodes() []connect.AbstractNode {
return utils.ConvertToAbstractNodes(flow.Steps, func(step *ApprovalStep) connect.AbstractNode {
return step
})
}
func (flow *ApprovalFlow) SetNodes(nodes []connect.AbstractNode) {
steps := make([]*ApprovalStep, len(nodes))
for i, node := range nodes {
// 类型断言,将 abstract.AbstractNode 转换为 *ApprovalStep
if step, ok := node.(*ApprovalStep); ok {
steps[i] = step
} else {
// 如果转换失败,可以选择处理错误,抛出异常或记录日志
panic("node is not of type *ApprovalStep")
}
}
flow.Steps = steps
}
func (flow *ApprovalFlow) GetNodeMap() map[string]connect.AbstractNode {
if flow.NodeMap == nil {
flow.NodeMap = map[string]connect.AbstractNode{}
connect.InitializeNodeMap(flow)
}
return flow.NodeMap
}
func (flow *ApprovalFlow) NewNodePathConfig(fromNodeKey, toNodeKey string) connect.AbstractNodePathConfig {
return NewPathConfig(fromNodeKey, toNodeKey)
}
func (flow *ApprovalFlow) MarshalBinary() ([]byte, error) {
return json.Marshal(flow)
}
func (flow *ApprovalFlow) UnmarshalBinary(data []byte) error {
return json.Unmarshal(data, flow)
}
func NewApprovalFlow(name string, description string) *ApprovalFlow {
approvalFlow := &ApprovalFlow{
Name: name,
Description: description,
Steps: make([]*ApprovalStep, 0),
}
startStep := NewStartStep()
endStep := NewEndStep()
connect.InsertNodeFirst(approvalFlow, startStep)
err := connect.InsertNodeAfter(approvalFlow, startStep, endStep)
//path := NewPathBetween(startStep, endStep)
//err := startStep.AddPathConfig(path)
//err = approvalFlow.AddStep(startStep)
//err = approvalFlow.AddStep(endStep)
if err != nil {
return nil
}
return approvalFlow
}
// AddStep 添加审批步骤
func (flow *ApprovalFlow) AddStep(step *ApprovalStep) error {
// 检查步骤是否已存在
for _, s := range flow.Steps {
if s.ID == step.ID && 0 != step.ID {
return fmt.Errorf("step with ID %d already exists in flow", step.ID)
}
}
step.FlowID = flow.ID
flow.Steps = append(flow.Steps, step)
return nil
}
// RemoveStep 删除审批步骤
func (flow *ApprovalFlow) RemoveStep(stepID int64) error {
for i, s := range flow.Steps {
if s.ID == stepID {
flow.Steps = append(flow.Steps[:i], flow.Steps[i+1:]...)
return nil
}
}
return fmt.Errorf("step with ID %d not found in flow", stepID)
}
// GetStep 获取审批步骤
func (flow *ApprovalFlow) GetStep(stepID int64) (*ApprovalStep, error) {
for _, s := range flow.Steps {
if s.ID == stepID {
return s, nil
}
}
return nil, fmt.Errorf("step with ID %d not found in flow", stepID)
}
func (flow *ApprovalFlow) GetStepByKey(key string) (*ApprovalStep, error) {
for _, s := range flow.Steps {
if s.Key == key {
return s, nil
}
}
return nil, fmt.Errorf("step with key %s not found in flow", key)
}
// ReorderSteps 重新排序步骤
func (flow *ApprovalFlow) ReorderSteps(order []int64) error {
if len(order) != len(flow.Steps) {
return fmt.Errorf("order length %d does not match steps length %d", len(order), len(flow.Steps))
}
stepMap := make(map[int64]*ApprovalStep)
for i := range flow.Steps {
stepMap[flow.Steps[i].ID] = flow.Steps[i]
}
var newSteps []*ApprovalStep
for _, id := range order {
if step, exists := stepMap[id]; exists {
newSteps = append(newSteps, step)
} else {
return fmt.Errorf("step ID %d not found in flow", id)
}
}
flow.Steps = newSteps
return nil
}
// Validate 验证流程的完整性和正确性
func (flow *ApprovalFlow) Validate() error {
if len(flow.Steps) == 0 {
return fmt.Errorf("approval flow must have at least one step")
}
// 可以添加更多验证逻辑,如检查步骤的顺序、路径配置等
return nil
}
// FirstStep 获取审批流程中的第一个审批节点
func (flow *ApprovalFlow) FirstStep() (*ApprovalStep, error) {
for _, step := range flow.Steps {
if step.StepCode == StepStart {
return step, nil
}
}
return nil, fmt.Errorf("no starting approval step found")
}