mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-01-06 14:45:48 +08:00
feat: sql解析器替换、工单统一由‘我的流程’发起、流程定义支持自定义条件触发审批、资源隐藏编号、model支持物理删除等
This commit is contained in:
@@ -3,12 +3,13 @@ package form
|
||||
import "mayfly-go/internal/flow/domain/entity"
|
||||
|
||||
type Procdef struct {
|
||||
Id uint64 `json:"id"`
|
||||
Name string `json:"name" binding:"required"` // 名称
|
||||
DefKey string `json:"defKey" binding:"required"`
|
||||
Tasks string `json:"tasks" binding:"required"` // 审批节点任务信息
|
||||
Status entity.ProcdefStatus `json:"status" binding:"required"`
|
||||
Remark string `json:"remark"`
|
||||
Id uint64 `json:"id"`
|
||||
Name string `json:"name" binding:"required"` // 名称
|
||||
DefKey string `json:"defKey" binding:"required"`
|
||||
Tasks string `json:"tasks" binding:"required"` // 审批节点任务信息
|
||||
Status entity.ProcdefStatus `json:"status" binding:"required"`
|
||||
Condition string `json:"condition"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
CodePaths []string `json:"codePaths"`
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
package form
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/utils/collx"
|
||||
)
|
||||
|
||||
type ProcinstStart struct {
|
||||
ProcdefId uint64 `json:"procdefId" binding:"required"` // 流程定义id
|
||||
BizType string `json:"bizType" binding:"required"` // 业务类型
|
||||
Remark string `json:"remark"` // 流程备注
|
||||
BizForm collx.M `json:"bizForm" binding:"required"` // 业务表单
|
||||
}
|
||||
|
||||
type ProcinstTaskAudit struct {
|
||||
Id uint64 `json:"id" binding:"required"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
"mayfly-go/internal/flow/api/form"
|
||||
"mayfly-go/internal/flow/api/vo"
|
||||
"mayfly-go/internal/flow/application"
|
||||
"mayfly-go/internal/flow/application/dto"
|
||||
"mayfly-go/internal/flow/domain/entity"
|
||||
"mayfly-go/internal/flow/domain/repository"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/req"
|
||||
"mayfly-go/pkg/utils/collx"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"mayfly-go/pkg/utils/structx"
|
||||
)
|
||||
|
||||
@@ -33,6 +35,16 @@ func (p *Procinst) GetProcinstPage(rc *req.Ctx) {
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (p *Procinst) ProcinstStart(rc *req.Ctx) {
|
||||
startForm := new(form.ProcinstStart)
|
||||
req.BindJsonAndValid(rc, startForm)
|
||||
_, err := p.ProcinstApp.StartProc(rc.MetaCtx, startForm.ProcdefId, &dto.StarProc{
|
||||
BizType: startForm.BizType,
|
||||
BizForm: jsonx.ToStr(startForm.BizForm),
|
||||
})
|
||||
biz.ErrIsNil(err)
|
||||
}
|
||||
|
||||
func (p *Procinst) ProcinstCancel(rc *req.Ctx) {
|
||||
instId := uint64(rc.PathParamInt("id"))
|
||||
rc.ReqParam = instId
|
||||
|
||||
@@ -8,10 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type BizHandleParam struct {
|
||||
BizType string //业务类型
|
||||
BizKey string // 业务key
|
||||
BizForm string // 业务表单信息
|
||||
ProcinstStatus entity.ProcinstStatus // 业务状态
|
||||
Procinst entity.Procinst // 流程实例
|
||||
}
|
||||
|
||||
// 业务流程处理器(流程状态变更后会根据流程业务类型获取对应的处理器进行回调处理)
|
||||
@@ -19,7 +16,9 @@ type FlowBizHandler interface {
|
||||
|
||||
// 业务流程处理函数
|
||||
// @param bizHandleParam 业务处理信息,可获取实例状态、关联业务key等信息
|
||||
FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) error
|
||||
// @return any 返回业务处理结果
|
||||
// @return error 错误信息
|
||||
FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) (any, error)
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -33,11 +32,11 @@ func RegisterBizHandler(flowBizType string, handler FlowBizHandler) {
|
||||
}
|
||||
|
||||
// 流程业务处理
|
||||
func FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) error {
|
||||
flowBizType := bizHandleParam.BizType
|
||||
func FlowBizHandle(ctx context.Context, bizHandleParam *BizHandleParam) (any, error) {
|
||||
flowBizType := bizHandleParam.Procinst.BizType
|
||||
if handler, ok := handlers[flowBizType]; !ok {
|
||||
logx.Warnf("flow biz handler not found: bizType=%s", flowBizType)
|
||||
return errorx.NewBiz("业务处理器不存在")
|
||||
return nil, errorx.NewBiz("业务处理器不存在")
|
||||
} else {
|
||||
return handler.FlowBizHandle(ctx, bizHandleParam)
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ type Procdef interface {
|
||||
// 删除流程实例信息
|
||||
DeleteProcdef(ctx context.Context, defId uint64) error
|
||||
|
||||
// GetProcdefIdByCodePath 根据资源编号路径获取对应的流程定义id
|
||||
GetProcdefIdByCodePath(ctx context.Context, codePaths ...string) uint64
|
||||
// GetProcdefByCodePath 根据资源编号路径获取对应的流程定义
|
||||
GetProcdefByCodePath(ctx context.Context, codePaths ...string) *entity.Procdef
|
||||
|
||||
// GetProcdefByResource 根据资源获取对应的流程定义
|
||||
GetProcdefByResource(ctx context.Context, resourceType int8, resourceCode string) *entity.Procdef
|
||||
@@ -82,21 +82,13 @@ func (p *procdefAppImpl) DeleteProcdef(ctx context.Context, defId uint64) error
|
||||
return p.DeleteById(ctx, defId)
|
||||
}
|
||||
|
||||
func (p *procdefAppImpl) GetProcdefIdByCodePath(ctx context.Context, codePaths ...string) uint64 {
|
||||
func (p *procdefAppImpl) GetProcdefByCodePath(ctx context.Context, codePaths ...string) *entity.Procdef {
|
||||
relateIds, err := p.tagTreeRelateApp.GetRelateIds(ctx, tagentity.TagRelateTypeFlowDef, codePaths...)
|
||||
if err != nil || len(relateIds) == 0 {
|
||||
return 0
|
||||
}
|
||||
return relateIds[len(relateIds)-1]
|
||||
}
|
||||
|
||||
func (p *procdefAppImpl) GetProcdefByResource(ctx context.Context, resourceType int8, resourceCode string) *entity.Procdef {
|
||||
resourceCodePaths := p.tagTreeApp.ListTagPathByTypeAndCode(resourceType, resourceCode)
|
||||
procdefId := p.GetProcdefIdByCodePath(ctx, resourceCodePaths...)
|
||||
if procdefId == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
procdefId := relateIds[len(relateIds)-1]
|
||||
procdef, err := p.GetById(procdefId)
|
||||
if err != nil {
|
||||
return nil
|
||||
@@ -107,6 +99,11 @@ func (p *procdefAppImpl) GetProcdefByResource(ctx context.Context, resourceType
|
||||
return procdef
|
||||
}
|
||||
|
||||
func (p *procdefAppImpl) GetProcdefByResource(ctx context.Context, resourceType int8, resourceCode string) *entity.Procdef {
|
||||
resourceCodePaths := p.tagTreeApp.ListTagPathByTypeAndCode(resourceType, resourceCode)
|
||||
return p.GetProcdefByCodePath(ctx, resourceCodePaths...)
|
||||
}
|
||||
|
||||
// 判断该流程实例是否可以执行修改操作
|
||||
func (p *procdefAppImpl) canModify(prodefId uint64) error {
|
||||
if activeInstCount := p.procinstApp.CountByCond(&entity.Procinst{ProcdefId: prodefId, Status: entity.ProcinstStatusActive}); activeInstCount > 0 {
|
||||
|
||||
@@ -9,7 +9,11 @@ import (
|
||||
"mayfly-go/pkg/base"
|
||||
"mayfly-go/pkg/contextx"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"mayfly-go/pkg/utils/stringx"
|
||||
)
|
||||
|
||||
type Procinst interface {
|
||||
@@ -68,9 +72,13 @@ func (p *procinstAppImpl) StartProc(ctx context.Context, procdefId uint64, reqPa
|
||||
return nil, errorx.NewBiz("该流程定义非启用状态")
|
||||
}
|
||||
|
||||
bizKey := reqParam.BizKey
|
||||
if bizKey == "" {
|
||||
bizKey = stringx.RandUUID()
|
||||
}
|
||||
procinst := &entity.Procinst{
|
||||
BizType: reqParam.BizType,
|
||||
BizKey: reqParam.BizKey,
|
||||
BizKey: bizKey,
|
||||
BizForm: reqParam.BizForm,
|
||||
BizStatus: entity.ProcinstBizStatusWait,
|
||||
ProcdefId: procdef.Id,
|
||||
@@ -217,13 +225,15 @@ func (p *procinstAppImpl) cancelInstTasks(ctx context.Context, procinstId uint64
|
||||
|
||||
// 触发流程实例状态改变事件
|
||||
func (p *procinstAppImpl) triggerProcinstStatusChangeEvent(ctx context.Context, procinst *entity.Procinst) error {
|
||||
err := FlowBizHandle(ctx, &BizHandleParam{
|
||||
BizType: procinst.BizType,
|
||||
BizKey: procinst.BizKey,
|
||||
BizForm: procinst.BizForm,
|
||||
ProcinstStatus: procinst.Status,
|
||||
|
||||
handleRes, err := FlowBizHandle(ctx, &BizHandleParam{
|
||||
Procinst: *procinst,
|
||||
})
|
||||
|
||||
if !anyx.IsBlank(handleRes) {
|
||||
procinst.BizHandleRes = jsonx.ToStr(handleRes)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// 业务处理错误,非完成状态则终止流程
|
||||
if procinst.Status != entity.ProcinstStatusCompleted {
|
||||
@@ -232,14 +242,20 @@ func (p *procinstAppImpl) triggerProcinstStatusChangeEvent(ctx context.Context,
|
||||
p.cancelInstTasks(ctx, procinst.Id, "业务处理失败")
|
||||
}
|
||||
procinst.BizStatus = entity.ProcinstBizStatusFail
|
||||
procinst.BizHandleRes = err.Error()
|
||||
if procinst.BizHandleRes == "" {
|
||||
procinst.BizHandleRes = err.Error()
|
||||
} else {
|
||||
logx.Errorf("流程业务[%s]处理失败: %v", procinst.BizKey, err.Error())
|
||||
}
|
||||
return p.UpdateById(ctx, procinst)
|
||||
}
|
||||
|
||||
// 处理成功,并且状态为完成,则更新业务状态为成功
|
||||
if procinst.Status == entity.ProcinstStatusCompleted {
|
||||
procinst.BizStatus = entity.ProcinstBizStatusSuccess
|
||||
procinst.BizHandleRes = "success"
|
||||
if procinst.BizHandleRes == "" {
|
||||
procinst.BizHandleRes = "success"
|
||||
}
|
||||
return p.UpdateById(ctx, procinst)
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -5,17 +5,21 @@ import (
|
||||
"mayfly-go/pkg/enumx"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/utils/collx"
|
||||
"mayfly-go/pkg/utils/stringx"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 流程定义信息
|
||||
type Procdef struct {
|
||||
model.Model
|
||||
|
||||
Name string `json:"name" form:"name"` // 名称
|
||||
DefKey string `json:"defKey" form:"defKey"` //
|
||||
Tasks string `json:"tasks"` // 审批节点任务信息
|
||||
Status ProcdefStatus `json:"status"` // 状态
|
||||
Remark string `json:"remark"`
|
||||
Name string `json:"name" form:"name"` // 名称
|
||||
DefKey string `json:"defKey" form:"defKey"` //
|
||||
Tasks string `json:"tasks"` // 审批节点任务信息
|
||||
Status ProcdefStatus `json:"status"` // 状态
|
||||
Condition *string `json:"condition"` // 触发审批的条件(计算结果返回1则需要启用该流程)
|
||||
Remark *string `json:"remark"`
|
||||
}
|
||||
|
||||
func (p *Procdef) TableName() string {
|
||||
@@ -34,6 +38,19 @@ func (p *Procdef) GetTasks() []*ProcdefTask {
|
||||
return tasks
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
res := stringx.TemplateResolve(*p.Condition, collx.Kvs("bizType", bizType, "param", param))
|
||||
return strings.TrimSpace(res) == "1"
|
||||
}
|
||||
|
||||
type ProcdefTask struct {
|
||||
Name string `json:"name" form:"name"` // 审批节点任务名称
|
||||
TaskKey string `json:"taskKey" form:"taskKey"` // 任务key
|
||||
|
||||
@@ -20,6 +20,8 @@ func InitProcinstRouter(router *gin.RouterGroup) {
|
||||
|
||||
req.NewGet("/:id", p.GetProcinstDetail),
|
||||
|
||||
req.NewPost("/start", p.ProcinstStart).Log(req.NewLogSave("流程-启动")),
|
||||
|
||||
req.NewPost("/:id/cancel", p.ProcinstCancel).Log(req.NewLogSave("流程-取消")),
|
||||
|
||||
req.NewGet("/tasks", p.GetTasks),
|
||||
|
||||
Reference in New Issue
Block a user