mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-01-03 05:06:36 +08:00
feat: flow design & page query refactor
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"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"
|
||||
|
||||
"github.com/may-fly/cast"
|
||||
)
|
||||
|
||||
// 流程定义信息
|
||||
@@ -16,7 +18,7 @@ type Procdef struct {
|
||||
|
||||
Name string `json:"name" form:"name" gorm:"size:150;comment:流程名称"` // 名称
|
||||
DefKey string `json:"defKey" form:"defKey" gorm:"not null;size:100;comment:流程定义key"` //
|
||||
Tasks string `json:"tasks" gorm:"not null;size:3000;comment:审批节点任务信息"` // 审批节点任务信息
|
||||
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;"`
|
||||
@@ -26,18 +28,6 @@ func (p *Procdef) TableName() string {
|
||||
return "t_flow_procdef"
|
||||
}
|
||||
|
||||
// 获取审批节点任务列表
|
||||
func (p *Procdef) GetTasks() []*ProcdefTask {
|
||||
var tasks []*ProcdefTask
|
||||
err := json.Unmarshal([]byte(p.Tasks), &tasks)
|
||||
if err != nil {
|
||||
logx.ErrorTrace("解析procdef tasks失败", err)
|
||||
return tasks
|
||||
}
|
||||
|
||||
return tasks
|
||||
}
|
||||
|
||||
// MatchCondition 是否匹配审批条件,匹配则需要启用该流程
|
||||
// @param bizType 业务类型
|
||||
// @param param 业务参数
|
||||
@@ -55,12 +45,6 @@ func (p *Procdef) MatchCondition(bizType string, param map[string]any) bool {
|
||||
return strings.TrimSpace(res) == "1"
|
||||
}
|
||||
|
||||
type ProcdefTask struct {
|
||||
Name string `json:"name" form:"name"` // 审批节点任务名称
|
||||
TaskKey string `json:"taskKey" form:"taskKey"` // 任务key
|
||||
UserId string `json:"userId"` // 审批人
|
||||
}
|
||||
|
||||
type ProcdefStatus int8
|
||||
|
||||
const (
|
||||
@@ -71,3 +55,102 @@ const (
|
||||
var ProcdefStatusEnum = enumx.NewEnum[ProcdefStatus]("流程定义状态").
|
||||
Add(ProcdefStatusEnable, "启用").
|
||||
Add(ProcdefStatusDisable, "禁用")
|
||||
|
||||
// GetFlowDef 获取流程定义信息
|
||||
func (p *Procdef) GetFlowDef() *FlowDef {
|
||||
if p.FlowDef == "" {
|
||||
return nil
|
||||
}
|
||||
flow, err := jsonx.To(p.FlowDef, new(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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user