Files
mayfly-go/server/internal/flow/domain/entity/procdef.go

157 lines
4.3 KiB
Go
Raw Normal View History

package entity
import (
"mayfly-go/pkg/enumx"
"mayfly-go/pkg/logx"
"mayfly-go/pkg/model"
"mayfly-go/pkg/utils/collx"
"mayfly-go/pkg/utils/jsonx"
"mayfly-go/pkg/utils/stringx"
"strings"
2025-06-27 12:17:45 +08:00
"github.com/spf13/cast"
)
// 流程定义信息
type Procdef struct {
model.Model
Name string `json:"name" form:"name" gorm:"size:150;comment:流程名称"` // 名称
DefKey string `json:"defKey" form:"defKey" gorm:"not null;size:100;comment:流程定义key"` //
FlowDef string `json:"flowDef" gorm:"type:text;comment:流程定义信息"` // 流程定义信息
Status ProcdefStatus `json:"status" gorm:"comment:状态"` // 状态
Condition *string `json:"condition" gorm:"type:text;comment:触发审批的条件计算结果返回1则需要启用该流程"` // 触发审批的条件计算结果返回1则需要启用该流程
Remark *string `json:"remark" gorm:"size:255;"`
}
func (p *Procdef) TableName() string {
return "t_flow_procdef"
}
// MatchCondition 是否匹配审批条件,匹配则需要启用该流程
// @param bizType 业务类型
// @param param 业务参数
// Condition返回值为1则表面该操作需要启用流程
func (p *Procdef) MatchCondition(bizType string, param map[string]any) bool {
if p.Condition == nil || *p.Condition == "" {
return true
}
2025-03-11 12:42:20 +08:00
res, err := stringx.TemplateResolve(*p.Condition, collx.Kvs("bizType", bizType, "param", param))
if err != nil {
logx.ErrorTrace("parse condition error", err.Error())
return true
}
return strings.TrimSpace(res) == "1"
}
type ProcdefStatus int8
const (
ProcdefStatusEnable ProcdefStatus = 1
ProcdefStatusDisable ProcdefStatus = -1
)
var ProcdefStatusEnum = enumx.NewEnum[ProcdefStatus]("流程定义状态").
Add(ProcdefStatusEnable, "启用").
Add(ProcdefStatusDisable, "禁用")
// GetFlowDef 获取流程定义信息
func (p *Procdef) GetFlowDef() *FlowDef {
if p.FlowDef == "" {
return nil
}
flow, err := jsonx.To[*FlowDef](p.FlowDef)
if err != nil {
logx.ErrorTrace("parse flow def failed", err)
return flow
}
return flow
}
// FlowDef 流程定义-流程内容
type FlowDef struct {
Nodes []*FlowNode `json:"nodes" form:"nodes"`
Edges []*FlowEdge `json:"edges" form:"edges"`
}
func (p *FlowDef) GetNodes(keys ...string) []*FlowNode {
result := make([]*FlowNode, 0)
keySet := make(map[string]bool)
for _, k := range keys {
keySet[k] = true
}
for _, node := range p.Nodes {
if keySet[node.Key] {
result = append(result, node)
}
}
return result
}
func (p *FlowDef) GetNodeByType(nodeType FlowNodeType) []*FlowNode {
return collx.ArrayFilter(p.Nodes, func(node *FlowNode) bool {
return node.Type == nodeType
})
}
func (p *FlowDef) GetEdgeBySourceNode(sourceNodeKey string) []*FlowEdge {
return collx.ArrayFilter(p.Edges, func(edge *FlowEdge) bool {
return edge.SourceNodeKey == sourceNodeKey
})
}
func (p *FlowDef) GetNextNodes(key string, vars collx.M) []*FlowNode {
edges := p.GetEdgeBySourceNode(key)
targetNodeKeys := make([]string, 0)
for _, edge := range edges {
if edge.MatchCondition(vars) {
targetNodeKeys = append(targetNodeKeys, edge.TargetNodeKey)
}
}
return p.GetNodes(targetNodeKeys...)
}
// FlowNode 流程定义-流程节点
type FlowNode struct {
model.ExtraData
Name string `json:"name" form:"name"` // 审批节点任务名称
Key string `json:"key" form:"key"` // 任务key
Type FlowNodeType `json:"type" form:"type"` // 任务节点类型
}
type FlowNodeType string
// FlowEdge 流程定义-流程节点-跳转
type FlowEdge struct {
model.ExtraData
Name string `json:"name" form:"name"` // 跳转名
Key string `json:"key" form:"key"` // 跳转key
SourceNodeKey string `json:"sourceNodeKey" form:"sourceNodeKey"` // 源节点key
TargetNodeKey string `json:"targetNodeKey" form:"targetNodeKey"` // 目标节点key
Condition string `json:"condition"` // 跳转条件
}
// MatchCondition 匹配条件
func (p *FlowEdge) MatchCondition(vars collx.M) bool {
if p.Condition == "" {
return true
}
// 解析条件
res, err := stringx.TemplateParse(p.Condition, vars)
if err != nil {
logx.Warnf("parse condition error, edge: %s, err: %s", p.Condition, err.Error())
return false
}
return cast.ToBool(res)
}