WiiCITMS/process/oa/workflow_instance.go
2025-11-07 14:14:34 +08:00

235 lines
7.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package oa
import (
"WiiCITMS/models/oa"
"WiiGenerates/WiiCITMS/generates/v1/go/types"
"WiiGoLibrary/apply/middle/process/v1"
"WiiGoLibrary/framework/db/v1/utils/mssql/unique"
"WiiGoLibrary/framework/hub/v1/dblib"
"errors"
"time"
)
// CreateInstanceRequest 创建工作流实例请求参数
type CreateInstanceRequest struct {
WorkflowGuid string `json:"workflowGuid"` // 工作流ID
Title string `json:"title"` // 实例标题
BusinessType int `json:"businessType"` // 业务类型
BusinessID string `json:"businessID"` // 业务ID
InitiatorGuid string `json:"initiatorGuid"` // 发起人ID
FormData string `json:"formData"` // 表单数据
}
// QueryInstancesRequest 查询工作流实例请求参数
type QueryInstancesRequest struct {
WorkflowGuid string `json:"workflowGuid"` // 工作流ID可选
BusinessType int `json:"businessType"` // 业务类型,-1表示所有类型
BusinessID string `json:"businessID"` // 业务ID可选
InitiatorGuid string `json:"initiatorGuid"` // 发起人ID可选
Status int `json:"status"` // 状态,-1表示所有状态
Limit int `json:"limit"` // 分页参数,每页数量
Offset int `json:"offset"` // 分页参数,偏移量
}
// StartWorkflowInstance 创建并启动工作流实例
// checkPermission: 是否检查权限如果为true则检查发起人是否有权限发起此类工作流
func StartWorkflowInstance(params CreateInstanceRequest, checkPermission bool) (*oa.WorkflowInstanceModel, *process.Process) {
// 使用事务确保操作的原子性
tx := dblib.DBIns.DB.Begin()
// 验证工作流是否存在并且处于激活状态
workflowGuid, err := unique.FromString(params.WorkflowGuid)
if err != nil {
tx.Rollback()
return nil, process.FailError(types.InvalidWorkflowInstanceParamError, err)
}
workflow := &oa.WorkflowModel{}
r := tx.Where("RecordGuid = ? AND IsActive = 1 AND (RecordStatus & 524288) = 0", workflowGuid).First(workflow)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.WorkflowNotFoundOrInactiveError, r.Error)
}
// 解析发起人ID
initiatorGuid, err := unique.FromString(params.InitiatorGuid)
if err != nil {
tx.Rollback()
return nil, process.FailError(types.InvalidWorkflowInstanceParamError, err)
}
// 创建工作流实例
instance := oa.WorkflowInstanceInstance()
instance.WorkflowGuid = workflowGuid
instance.Title = params.Title
instance.BusinessType = int16(params.BusinessType)
instance.BusinessID = params.BusinessID
instance.InitiatorGuid = initiatorGuid
instance.Status = 0 // 进行中
instance.FormData = params.FormData
// 保存实例
r = tx.Create(instance)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.CreateWorkflowInstanceError, r.Error)
}
// 获取工作流的第一个节点
firstNode := &oa.WorkflowNodeModel{}
r = tx.Where("WorkflowGuid = ? AND NodeType = 1 AND (RecordStatus & 524288) = 0", workflowGuid).
Order("NodeOrder ASC").First(firstNode)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.WorkflowStartNodeNotFoundError, r.Error)
}
// 设置当前节点为第一个节点
instance.CurrentNodeID = firstNode.RecordGuid
r = tx.Save(instance)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.UpdateWorkflowInstanceError, r.Error)
}
// 获取工作流的第二个节点(如果是审批节点,则创建审批任务)
nextNode := &oa.WorkflowNodeModel{}
r = tx.Where("WorkflowGuid = ? AND NodeOrder > ? AND (RecordStatus & 524288) = 0", workflowGuid, firstNode.NodeOrder).
Order("NodeOrder ASC").First(nextNode)
if r.Error == nil && nextNode.NodeType == 2 { // 如果存在下一个节点且是审批节点
// 解析审批人
var approverGuid unique.UUID
if nextNode.ApproverType == 1 { // 指定人
approverGuid, err = unique.FromString(nextNode.ApproverValue)
if err != nil {
tx.Rollback()
return nil, process.FailError(types.InvalidApproverError, err)
}
} else {
// 其他类型的审批人逻辑(角色、部门负责人等)
// 这里简化处理,实际项目中需要根据不同的审批人类型查询对应的审批人
tx.Rollback()
return nil, process.FailError(types.UnsupportedApproverTypeError, errors.New("暂不支持的审批人类型"))
}
// 创建审批记录
approvalRecord := oa.ApprovalRecordInstance()
approvalRecord.InstanceGuid = instance.RecordGuid
approvalRecord.NodeGuid = nextNode.RecordGuid
approvalRecord.ApproverGuid = approverGuid
approvalRecord.Status = 0 // 待处理
r = tx.Create(approvalRecord)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.CreateApprovalRecordError, r.Error)
}
// 更新实例当前节点
instance.CurrentNodeID = nextNode.RecordGuid
r = tx.Save(instance)
if r.Error != nil {
tx.Rollback()
return nil, process.FailError(types.UpdateWorkflowInstanceError, r.Error)
}
}
// 提交事务
if err := tx.Commit().Error; err != nil {
return nil, process.FailError(types.TransactionCommitError, err)
}
return instance, process.Success(200)
}
// QueryWorkflowInstances 查询工作流实例
func QueryWorkflowInstances(params QueryInstancesRequest) ([]*oa.WorkflowInstanceModel, *process.Process) {
result := make([]*oa.WorkflowInstanceModel, 0)
db := dblib.DBIns.DB.Model(&oa.WorkflowInstanceModel{}).Where("(RecordStatus & 524288) = 0")
// 按工作流ID筛选
if params.WorkflowGuid != "" {
workflowGuid, err := unique.FromString(params.WorkflowGuid)
if err == nil {
db = db.Where("WorkflowGuid = ?", workflowGuid)
}
}
// 按业务类型筛选
if params.BusinessType >= 0 {
db = db.Where("BusinessType = ?", params.BusinessType)
}
// 按发起人筛选
if params.InitiatorGuid != "" {
initiatorGuid, err := unique.FromString(params.InitiatorGuid)
if err == nil {
db = db.Where("InitiatorGuid = ?", initiatorGuid)
}
}
// 按状态筛选
if params.Status >= 0 {
db = db.Where("Status = ?", params.Status)
}
// 分页查询
limit := params.Limit
if limit <= 0 {
limit = 20 // 默认每页20条
}
offset := params.Offset
if offset < 0 {
offset = 0
}
r := db.Limit(limit).Offset(offset).Order("CreateTime DESC").Find(&result)
if r.Error != nil {
return result, process.FailError(types.QueryWorkflowInstanceError, r.Error)
}
return result, process.Success(200)
}
// GetWorkflowInstance 根据ID获取工作流实例
func GetWorkflowInstance(instanceGuid string) (*oa.WorkflowInstanceModel, *process.Process) {
guid, err := unique.FromString(instanceGuid)
if err != nil {
return nil, process.FailError(types.InvalidWorkflowInstanceParamError, err)
}
instance := &oa.WorkflowInstanceModel{}
r := dblib.DBIns.DB.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", guid).First(instance)
if r.Error != nil {
return nil, process.FailError(types.WorkflowInstanceNotFoundError, r.Error)
}
return instance, process.Success(200)
}
// CancelWorkflowInstance 取消工作流实例
func CancelWorkflowInstance(instanceGuid string) *process.Process {
// 获取工作流实例
instance, proc := GetWorkflowInstance(instanceGuid)
if proc.IsError() {
return proc
}
// 只有进行中的工作流才能取消
if instance.Status != 0 {
return process.FailError(types.InvalidWorkflowStatusError, errors.New("只有进行中的工作流才能取消"))
}
// 更新状态为已取消
instance.Status = 3 // 已取消
instance.CompletionTime = time.Now()
// 保存更新
r := dblib.DBIns.DB.Save(instance)
if r.Error != nil {
return process.FailError(types.UpdateWorkflowInstanceError, r.Error)
}
return process.Success(200)
}