feat: sql解析器替换、工单统一由‘我的流程’发起、流程定义支持自定义条件触发审批、资源隐藏编号、model支持物理删除等

This commit is contained in:
meilin.huang
2024-10-16 17:24:50 +08:00
parent 43edef412c
commit e135e4ce64
170 changed files with 397197 additions and 1251 deletions

View File

@@ -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"`
}

View File

@@ -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"`

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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),