mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 00:10:25 +08:00 
			
		
		
		
	feat: message notify
This commit is contained in:
		@@ -10,6 +10,7 @@ type Procdef struct {
 | 
			
		||||
	Status    entity.ProcdefStatus `json:"status" binding:"required"`
 | 
			
		||||
	Condition string               `json:"condition"`
 | 
			
		||||
	Remark    string               `json:"remark"`
 | 
			
		||||
	MsgTmplId uint64               `json:"msgTmplId"`
 | 
			
		||||
 | 
			
		||||
	CodePaths []string `json:"codePaths"`
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,14 @@ import (
 | 
			
		||||
	"mayfly-go/internal/flow/application/dto"
 | 
			
		||||
	"mayfly-go/internal/flow/domain/entity"
 | 
			
		||||
	"mayfly-go/internal/flow/imsg"
 | 
			
		||||
	msgapp "mayfly-go/internal/msg/application"
 | 
			
		||||
	msgentity "mayfly-go/internal/msg/domain/entity"
 | 
			
		||||
	tagapp "mayfly-go/internal/tag/application"
 | 
			
		||||
	tagentity "mayfly-go/internal/tag/domain/entity"
 | 
			
		||||
	"mayfly-go/pkg/biz"
 | 
			
		||||
	"mayfly-go/pkg/req"
 | 
			
		||||
	"mayfly-go/pkg/utils/collx"
 | 
			
		||||
	"mayfly-go/pkg/utils/structx"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/may-fly/cast"
 | 
			
		||||
@@ -20,12 +23,15 @@ import (
 | 
			
		||||
type Procdef struct {
 | 
			
		||||
	procdefApp       application.Procdef  `inject:"T"`
 | 
			
		||||
	tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"`
 | 
			
		||||
	msgTmplBizApp    msgapp.MsgTmplBiz    `inject:"T"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Procdef) ReqConfs() *req.Confs {
 | 
			
		||||
	reqs := [...]*req.Conf{
 | 
			
		||||
		req.NewGet("", p.GetProcdefPage),
 | 
			
		||||
 | 
			
		||||
		req.NewGet("/detail/:id", p.GetProcdefDetail),
 | 
			
		||||
 | 
			
		||||
		req.NewGet("/:resourceType/:resourceCode", p.GetProcdef),
 | 
			
		||||
 | 
			
		||||
		req.NewPost("", p.Save).Log(req.NewLogSaveI(imsg.LogProcdefSave)).RequiredPermissionCode("flow:procdef:save"),
 | 
			
		||||
@@ -49,6 +55,25 @@ func (p *Procdef) GetProcdefPage(rc *req.Ctx) {
 | 
			
		||||
	rc.ResData = res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Procdef) GetProcdefDetail(rc *req.Ctx) {
 | 
			
		||||
	def, err := p.procdefApp.GetById(cast.ToUint64(rc.PathParamInt("id")))
 | 
			
		||||
	biz.ErrIsNil(err)
 | 
			
		||||
	res := new(vo.Procdef)
 | 
			
		||||
	biz.ErrIsNil(structx.Copy(res, def))
 | 
			
		||||
 | 
			
		||||
	p.tagTreeRelateApp.FillTagInfo(tagentity.TagRelateTypeFlowDef, res)
 | 
			
		||||
 | 
			
		||||
	bizMsgTmpl := &msgentity.MsgTmplBiz{
 | 
			
		||||
		BizId:   res.Id,
 | 
			
		||||
		BizType: application.FlowTaskNotifyBizKey,
 | 
			
		||||
	}
 | 
			
		||||
	if p.msgTmplBizApp.GetByCond(bizMsgTmpl) == nil {
 | 
			
		||||
		res.MsgTmplId = &bizMsgTmpl.TmplId
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc.ResData = res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Procdef) GetProcdef(rc *req.Ctx) {
 | 
			
		||||
	resourceType := rc.PathParamInt("resourceType")
 | 
			
		||||
	resourceCode := rc.PathParam("resourceCode")
 | 
			
		||||
@@ -61,6 +86,7 @@ func (a *Procdef) Save(rc *req.Ctx) {
 | 
			
		||||
	rc.ReqParam = form
 | 
			
		||||
	biz.ErrIsNil(a.procdefApp.SaveProcdef(rc.MetaCtx, &dto.SaveProcdef{
 | 
			
		||||
		Procdef:   procdef,
 | 
			
		||||
		MsgTmplId: form.MsgTmplId,
 | 
			
		||||
		CodePaths: form.CodePaths,
 | 
			
		||||
	}))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@ import (
 | 
			
		||||
type Procdef struct {
 | 
			
		||||
	tagentity.RelateTags // 标签信息
 | 
			
		||||
	entity.Procdef
 | 
			
		||||
 | 
			
		||||
	MsgTmplId *uint64 `json:"msgTmplId" gorm:"-"` // 消息模板ID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Procdef) GetRelateId() uint64 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								server/internal/flow/application/const.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								server/internal/flow/application/const.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
package application
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	FlowTaskNotifyBizKey = "flow:task:notify" // 工单任务处理通知
 | 
			
		||||
)
 | 
			
		||||
@@ -4,6 +4,7 @@ import "mayfly-go/internal/flow/domain/entity"
 | 
			
		||||
 | 
			
		||||
type SaveProcdef struct {
 | 
			
		||||
	Procdef   *entity.Procdef
 | 
			
		||||
	MsgTmplId uint64 // 消息模板id
 | 
			
		||||
	CodePaths []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,8 @@ import (
 | 
			
		||||
	"mayfly-go/internal/flow/domain/entity"
 | 
			
		||||
	"mayfly-go/internal/flow/domain/repository"
 | 
			
		||||
	"mayfly-go/internal/flow/imsg"
 | 
			
		||||
	msgapp "mayfly-go/internal/msg/application"
 | 
			
		||||
	msgdto "mayfly-go/internal/msg/application/dto"
 | 
			
		||||
	tagapp "mayfly-go/internal/tag/application"
 | 
			
		||||
	tagentity "mayfly-go/internal/tag/domain/entity"
 | 
			
		||||
	"mayfly-go/pkg/base"
 | 
			
		||||
@@ -36,6 +38,7 @@ type procdefAppImpl struct {
 | 
			
		||||
 | 
			
		||||
	procinstApp Procinst `inject:"T"`
 | 
			
		||||
 | 
			
		||||
	msgTmplBizApp    msgapp.MsgTmplBiz    `inject:"T"`
 | 
			
		||||
	tagTreeApp       tagapp.TagTree       `inject:"T"`
 | 
			
		||||
	tagTreeRelateApp tagapp.TagTreeRelate `inject:"T"`
 | 
			
		||||
}
 | 
			
		||||
@@ -67,6 +70,14 @@ func (p *procdefAppImpl) SaveProcdef(ctx context.Context, defParam *dto.SaveProc
 | 
			
		||||
	return p.Tx(ctx, func(ctx context.Context) error {
 | 
			
		||||
		return p.Save(ctx, def)
 | 
			
		||||
	}, func(ctx context.Context) error {
 | 
			
		||||
		// 保存通知消息模板
 | 
			
		||||
		if err := p.msgTmplBizApp.SaveBizTmpl(ctx, msgdto.MsgTmplBizSave{
 | 
			
		||||
			TmplId:  defParam.MsgTmplId,
 | 
			
		||||
			BizType: FlowTaskNotifyBizKey,
 | 
			
		||||
			BizId:   def.Id,
 | 
			
		||||
		}); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return p.tagTreeRelateApp.RelateTag(ctx, tagentity.TagRelateTypeFlowDef, def.Id, defParam.CodePaths...)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,19 +3,24 @@ package application
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/internal/event"
 | 
			
		||||
	"mayfly-go/internal/flow/application/dto"
 | 
			
		||||
	"mayfly-go/internal/flow/domain/entity"
 | 
			
		||||
	"mayfly-go/internal/flow/domain/repository"
 | 
			
		||||
	"mayfly-go/internal/flow/imsg"
 | 
			
		||||
	msgdto "mayfly-go/internal/msg/application/dto"
 | 
			
		||||
	"mayfly-go/pkg/base"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/errorx"
 | 
			
		||||
	"mayfly-go/pkg/global"
 | 
			
		||||
	"mayfly-go/pkg/i18n"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"mayfly-go/pkg/utils/anyx"
 | 
			
		||||
	"mayfly-go/pkg/utils/jsonx"
 | 
			
		||||
	"mayfly-go/pkg/utils/stringx"
 | 
			
		||||
 | 
			
		||||
	"github.com/may-fly/cast"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Procinst interface {
 | 
			
		||||
@@ -140,6 +145,7 @@ func (p *procinstAppImpl) CompleteTask(ctx context.Context, instTaskId uint64, r
 | 
			
		||||
		procinst.SetEnd()
 | 
			
		||||
	} else {
 | 
			
		||||
		procinst.TaskKey = task.TaskKey
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p.Tx(ctx, func(ctx context.Context) error {
 | 
			
		||||
@@ -287,7 +293,26 @@ func (p *procinstAppImpl) createProcinstTask(ctx context.Context, procinst *enti
 | 
			
		||||
		TaskName: task.Name,
 | 
			
		||||
		Assignee: task.UserId,
 | 
			
		||||
	}
 | 
			
		||||
	return p.procinstTaskRepo.Insert(ctx, procinstTask)
 | 
			
		||||
 | 
			
		||||
	if err := p.procinstTaskRepo.Insert(ctx, procinstTask); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送通知消息
 | 
			
		||||
	global.EventBus.Publish(ctx, event.EventTopicBizMsgTmplSend, msgdto.BizMsgTmplSend{
 | 
			
		||||
		BizType: FlowTaskNotifyBizKey,
 | 
			
		||||
		BizId:   procinst.ProcdefId,
 | 
			
		||||
		Params: map[string]any{
 | 
			
		||||
			"creator":        procinst.Creator,
 | 
			
		||||
			"procdefName":    procinst.ProcdefName,
 | 
			
		||||
			"bizKey":         procinst.BizKey,
 | 
			
		||||
			"taskName":       task.Name,
 | 
			
		||||
			"procinstRemark": procinst.Remark,
 | 
			
		||||
		},
 | 
			
		||||
		ReceiverIds: []uint64{cast.ToUint64(task.UserId)},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取下一审批节点任务
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ type ProcinstTaskQuery struct {
 | 
			
		||||
	ProcinstId   uint64             `json:"procinstId"`   // 流程实例id
 | 
			
		||||
	ProcinstName string             `json:"procinstName"` // 流程实例名称
 | 
			
		||||
	BizType      string             `json:"bizType" form:"bizType"`
 | 
			
		||||
	BizKey       string             `json:"bizKey" form:"bizKey"` // 业务key
 | 
			
		||||
	Assignee     string             `json:"assignee"`             // 分配到该任务的用户
 | 
			
		||||
	Status       ProcinstTaskStatus `json:"status" form:"status"` // 状态
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"mayfly-go/internal/flow/domain/entity"
 | 
			
		||||
	"mayfly-go/internal/flow/domain/repository"
 | 
			
		||||
	"mayfly-go/pkg/base"
 | 
			
		||||
	"mayfly-go/pkg/gormx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -31,6 +32,14 @@ func newProcinstTaskRepo() repository.ProcinstTask {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *procinstTaskImpl) GetPageList(condition *entity.ProcinstTaskQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
 | 
			
		||||
	qd := model.NewModelCond(condition)
 | 
			
		||||
	return p.PageByCondToAny(qd, pageParam, toEntity)
 | 
			
		||||
	qd := gormx.NewQueryWithTableName("t_flow_procinst_task t").
 | 
			
		||||
		Joins("JOIN t_flow_procinst tp ON t.procinst_id = tp.id ").
 | 
			
		||||
		WithCond(model.NewCond().Columns("t.*, tp.biz_key").
 | 
			
		||||
			Eq("tp.biz_key", condition.BizKey).
 | 
			
		||||
			Eq0("tp.is_deleted", model.ModelUndeleted).
 | 
			
		||||
			Eq("tp.biz_type", condition.BizType).
 | 
			
		||||
			Eq0("t.is_deleted", model.ModelUndeleted).
 | 
			
		||||
			Eq("t.status", condition.Status).
 | 
			
		||||
			OrderByDesc("t.id"))
 | 
			
		||||
	return gormx.PageQuery(qd, pageParam, toEntity)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user