mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-12-24 08:12:55 +08:00
617 lines
16 KiB
Go
617 lines
16 KiB
Go
package flowService
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"strconv"
|
||
|
||
"x_admin/core"
|
||
"x_admin/core/request"
|
||
"x_admin/core/response"
|
||
"x_admin/model"
|
||
"x_admin/model/system_model"
|
||
"x_admin/schema/flowSchema"
|
||
"x_admin/schema/systemSchema"
|
||
"x_admin/service/systemService"
|
||
"x_admin/util"
|
||
"x_admin/util/convert_util"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
var HistoryService = NewFlowHistoryService()
|
||
|
||
// NewFlowHistoryService 初始化
|
||
func NewFlowHistoryService() *flowHistoryService {
|
||
db := core.GetDB()
|
||
return &flowHistoryService{db: db}
|
||
}
|
||
|
||
// flowHistoryService 流程历史服务实现类
|
||
type flowHistoryService struct {
|
||
db *gorm.DB
|
||
}
|
||
|
||
// List 流程历史列表
|
||
func (service flowHistoryService) List(page request.PageReq, listReq flowSchema.FlowHistoryListReq) (res response.PageResp, e error) {
|
||
// 分页信息
|
||
limit := page.PageSize
|
||
offset := page.PageSize * (page.PageNo - 1)
|
||
// 查询
|
||
dbModel := service.db.Model(&model.FlowHistory{})
|
||
if listReq.ApplyId > 0 {
|
||
dbModel = dbModel.Where("apply_id = ?", listReq.ApplyId)
|
||
}
|
||
if listReq.TemplateId > 0 {
|
||
dbModel = dbModel.Where("template_id = ?", listReq.TemplateId)
|
||
}
|
||
if listReq.ApplyUserId > 0 {
|
||
dbModel = dbModel.Where("apply_user_id = ?", listReq.ApplyUserId)
|
||
}
|
||
if listReq.ApplyUserNickname != "" {
|
||
dbModel = dbModel.Where("apply_user_nickname like ?", "%"+listReq.ApplyUserNickname+"%")
|
||
}
|
||
if listReq.ApproverId > 0 {
|
||
dbModel = dbModel.Where("approver_id = ?", listReq.ApproverId)
|
||
}
|
||
if listReq.ApproverNickname != "" {
|
||
dbModel = dbModel.Where("approver_nickname like ?", "%"+listReq.ApproverNickname+"%")
|
||
}
|
||
if listReq.NodeId != "" {
|
||
dbModel = dbModel.Where("node_id = ?", listReq.NodeId)
|
||
}
|
||
if listReq.FormValue != "" {
|
||
dbModel = dbModel.Where("form_value = ?", listReq.FormValue)
|
||
}
|
||
if listReq.PassStatus > 0 {
|
||
dbModel = dbModel.Where("pass_status = ?", listReq.PassStatus)
|
||
}
|
||
if listReq.PassRemark != "" {
|
||
dbModel = dbModel.Where("pass_remark = ?", listReq.PassRemark)
|
||
}
|
||
// 总数
|
||
var count int64
|
||
err := dbModel.Count(&count).Error
|
||
if e = response.CheckErr(err, "列表总数获取失败"); e != nil {
|
||
return
|
||
}
|
||
// 数据
|
||
var modelList []model.FlowHistory
|
||
err = dbModel.Limit(limit).Offset(offset).Order("id desc").Find(&modelList).Error
|
||
if e = response.CheckErr(err, "列表获取失败"); e != nil {
|
||
return
|
||
}
|
||
list := []flowSchema.FlowHistoryResp{}
|
||
convert_util.Copy(&list, modelList)
|
||
return response.PageResp{
|
||
PageNo: page.PageNo,
|
||
PageSize: page.PageSize,
|
||
Count: count,
|
||
Lists: list,
|
||
}, nil
|
||
}
|
||
|
||
// ListAll 流程历史列表
|
||
func (service flowHistoryService) ListAll(listReq flowSchema.FlowHistoryListReq) (res []flowSchema.FlowHistoryResp, e error) {
|
||
|
||
// 查询
|
||
dbModel := service.db.Model(&model.FlowHistory{})
|
||
if listReq.ApplyId > 0 {
|
||
dbModel = dbModel.Where("apply_id = ?", listReq.ApplyId)
|
||
}
|
||
if listReq.PassStatus > 0 {
|
||
dbModel = dbModel.Where("pass_status = ?", listReq.PassStatus)
|
||
}
|
||
if listReq.NodeType != "" {
|
||
dbModel = dbModel.Where("node_type =?", listReq.NodeType)
|
||
}
|
||
// 数据
|
||
var modelList []model.FlowHistory
|
||
err := dbModel.Find(&modelList).Error
|
||
if e = response.CheckErr(err, "获取列表失败"); e != nil {
|
||
return
|
||
}
|
||
convert_util.Copy(&res, modelList)
|
||
return res, nil
|
||
}
|
||
|
||
// Detail 流程历史详情
|
||
func (service flowHistoryService) Detail(id int) (res flowSchema.FlowHistoryResp, e error) {
|
||
var obj model.FlowHistory
|
||
err := service.db.Where("id = ?", id).Limit(1).First(&obj).Error
|
||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||
return
|
||
}
|
||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||
return
|
||
}
|
||
convert_util.Copy(&res, obj)
|
||
return
|
||
}
|
||
|
||
// Add 流程历史新增
|
||
func (service flowHistoryService) Add(addReq flowSchema.FlowHistoryAddReq) (e error) {
|
||
var obj model.FlowHistory
|
||
convert_util.Copy(&obj, addReq)
|
||
err := service.db.Create(&obj).Error
|
||
e = response.CheckErr(err, "添加失败")
|
||
return
|
||
}
|
||
|
||
// Edit 流程历史编辑
|
||
func (service flowHistoryService) Edit(editReq flowSchema.FlowHistoryEditReq) (e error) {
|
||
var obj model.FlowHistory
|
||
err := service.db.Where("id = ?", editReq.Id).Limit(1).First(&obj).Error
|
||
// 校验
|
||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||
return
|
||
}
|
||
if e = response.CheckErr(err, "待编辑数据查找失败"); e != nil {
|
||
return
|
||
}
|
||
// 更新
|
||
convert_util.Copy(&obj, editReq)
|
||
err = service.db.Model(&obj).Updates(obj).Error
|
||
e = response.CheckErr(err, "编辑失败")
|
||
return
|
||
}
|
||
|
||
// Del 流程历史删除
|
||
func (service flowHistoryService) Del(id int) (e error) {
|
||
var obj model.FlowHistory
|
||
err := service.db.Where("id = ?", id).Limit(1).First(&obj).Error
|
||
// 校验
|
||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||
return
|
||
}
|
||
if e = response.CheckErr(err, "待删除数据查找失败"); e != nil {
|
||
return
|
||
}
|
||
// 删除
|
||
err = service.db.Delete(&obj).Error
|
||
e = response.CheckErr(err, "删除失败")
|
||
return
|
||
}
|
||
|
||
/**
|
||
* 获取节点的审批用户
|
||
*/
|
||
func (service flowHistoryService) GetApprover(ApplyId int) (res []systemSchema.SystemAuthAdminResp, e error) {
|
||
nextNodes, applyDetail, _, err := service.GetNextNode(ApplyId)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var userTask flowSchema.FlowTree
|
||
for n := 0; n < len(nextNodes); n++ {
|
||
if nextNodes[n].Type == "bpmn:userTask" {
|
||
userTask = nextNodes[n]
|
||
break
|
||
}
|
||
}
|
||
// 没有审批节点不用获取审批人
|
||
if userTask.Id == "" {
|
||
return nil, nil
|
||
}
|
||
|
||
var userType = userTask.UserType //用户类型,1指定部门、岗位,2用户部门负责人,3指定审批人
|
||
var userId = userTask.UserId
|
||
var deptId = userTask.DeptId
|
||
var postId = userTask.PostId
|
||
if userType == 0 && userId == 0 && deptId == 0 && postId == 0 {
|
||
// return nil, errors.New("未设置审批人")
|
||
|
||
// 未设置审批人时默认为2用户部门负责人
|
||
userType = 2
|
||
}
|
||
adminTbName := core.DBTableName(&system_model.SystemAuthAdmin{})
|
||
|
||
adminModel := service.db.Table(adminTbName+" AS admin").Where("admin.is_delete = ?", 0)
|
||
|
||
where := map[string]interface{}{}
|
||
if userType == 1 {
|
||
if deptId > 0 {
|
||
where["admin.dept_id"] = deptId
|
||
// adminModel.Or("admin.dept_id =?", deptId)
|
||
}
|
||
if postId > 0 {
|
||
where["admin.post_id"] = postId
|
||
// adminModel.Or("admin.post_id =?", postId)
|
||
}
|
||
} else if userType == 2 {
|
||
// 申请人所在的部门负责人
|
||
|
||
applyUser, err := systemService.AdminService.Detail(uint(applyDetail.ApplyUserId))
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if applyUser.DeptId == 0 {
|
||
return nil, errors.New("申请人没有绑定部门")
|
||
}
|
||
deptDetails, err := systemService.DeptService.Detail(applyUser.DeptId)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if deptDetails.DutyId == 0 {
|
||
return nil, errors.New(deptDetails.Name + "部门没有绑定负责人")
|
||
}
|
||
where["admin.id"] = deptDetails.DutyId
|
||
|
||
} else if userType == 3 {
|
||
if userId > 0 {
|
||
where["admin.id"] = userId
|
||
// adminModel.Or("admin.id =?", userId)
|
||
}
|
||
}
|
||
|
||
// 数据
|
||
var adminResp []systemSchema.SystemAuthAdminResp
|
||
err = adminModel.Where(where).Find(&adminResp).Error
|
||
if e = response.CheckErr(err, "获取审批用户失败"); e != nil {
|
||
return
|
||
}
|
||
for i := 0; i < len(adminResp); i++ {
|
||
adminResp[i].Avatar = util.UrlUtil.ToAbsoluteUrl(adminResp[i].Avatar)
|
||
if adminResp[i].ID == 1 {
|
||
adminResp[i].Role = "系统管理员"
|
||
}
|
||
}
|
||
return adminResp, nil
|
||
}
|
||
|
||
// 通过审批
|
||
func (service flowHistoryService) Pass(pass flowSchema.PassReq) (e error) {
|
||
nextNodes, applyDetail, LastHistory, err := service.GetNextNode(pass.ApplyId)
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// nextNodes必须包含审批节点或结束节点,否则流程抛出异常
|
||
|
||
isUserTask := false //是否有用户节点
|
||
isEndTask := false // 是否是最后一个节点
|
||
|
||
FormValue := applyDetail.FormValue
|
||
if LastHistory.Id != 0 {
|
||
FormValue = LastHistory.FormValue
|
||
}
|
||
var flows = []model.FlowHistory{}
|
||
|
||
for _, v := range nextNodes {
|
||
// if v.Type == "bpmn:exclusiveGateway" {
|
||
// 这里网关不用处理,顶多加一条历史记录
|
||
// }
|
||
var flow = model.FlowHistory{
|
||
ApplyId: applyDetail.Id,
|
||
NodeId: v.Id,
|
||
NodeType: v.Type,
|
||
NodeLabel: v.Label,
|
||
FormValue: FormValue,
|
||
PassStatus: 1,
|
||
ApplyUserId: applyDetail.ApplyUserId,
|
||
TemplateId: applyDetail.TemplateId,
|
||
ApplyUserNickname: applyDetail.ApplyUserNickname,
|
||
ApproverId: 0,
|
||
ApproverNickname: "",
|
||
}
|
||
if v.Type == "bpmn:startEvent" {
|
||
flow.ApproverId = 0
|
||
flow.PassStatus = 2 //2通过
|
||
} else if v.Type == "bpmn:exclusiveGateway" {
|
||
flow.ApproverId = 0
|
||
flow.PassStatus = 2
|
||
// 发邮件之类的,待完善
|
||
} else if v.Type == "bpmn:serviceTask" {
|
||
flow.ApproverId = 0
|
||
flow.PassStatus = 1 //1待处理,异步任务可以失败
|
||
// 发邮件之类的,待完善
|
||
} else if v.Type == "bpmn:userTask" {
|
||
isUserTask = true
|
||
flow.PassStatus = 1 //1待处理
|
||
flow.ApproverId = pass.NextNodeAdminId
|
||
Approver, err := systemService.AdminService.Detail(uint(pass.NextNodeAdminId))
|
||
if err != nil {
|
||
return err
|
||
} else {
|
||
flow.ApproverNickname = Approver.Nickname
|
||
}
|
||
|
||
} else if v.Type == "bpmn:endEvent" {
|
||
isEndTask = true
|
||
flow.ApproverId = 0
|
||
flow.PassStatus = 2 //2通过
|
||
}
|
||
flows = append(flows, flow)
|
||
}
|
||
if !isUserTask && !isEndTask {
|
||
return errors.New("必须包含审批节点或者结束节点")
|
||
}
|
||
err = service.db.Transaction(func(tx *gorm.DB) error {
|
||
// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
|
||
if err := tx.Create(&flows).Error; err != nil {
|
||
// 返回任何错误都会回滚事务
|
||
return err
|
||
}
|
||
// LastHistory
|
||
if LastHistory.Id > 0 {
|
||
LastHistory.PassStatus = 2
|
||
LastHistory.PassRemark = pass.PassRemark
|
||
err = tx.Save(&LastHistory).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
// 待提交或者有结束节点,修改申请状态
|
||
if applyDetail.Status == 1 || isEndTask {
|
||
status := 2 //审批中
|
||
if isEndTask {
|
||
status = 3 //审批通过
|
||
}
|
||
err = tx.Model(&model.FlowApply{}).Where(model.FlowApply{
|
||
Id: pass.ApplyId,
|
||
}).Update("status", status).Error
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
})
|
||
|
||
return err
|
||
}
|
||
|
||
// 驳回
|
||
func (service flowHistoryService) Back(back flowSchema.BackReq) (e error) {
|
||
// 得判断一下驳回的人权限
|
||
// 获取最后一条历史记录
|
||
var LastHistory model.FlowHistory
|
||
err := service.db.Where(model.FlowHistory{
|
||
ApplyId: back.ApplyId,
|
||
}).Limit(1).Last(&LastHistory).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 驳回到申请人,最后一条改驳回状态,驳回备注,新加一条
|
||
if back.HistoryId == 0 {
|
||
|
||
var applyDetail, err = ApplyService.Detail(back.ApplyId)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
err = service.db.Transaction(func(tx *gorm.DB) error {
|
||
// 获取最早的一条历史记录,nodeType为"bpmn:startEvent"
|
||
var FirstHistory model.FlowHistory
|
||
err = service.db.Where(model.FlowHistory{
|
||
ApplyId: back.ApplyId,
|
||
NodeType: "bpmn:startEvent",
|
||
}).Limit(1).First(&FirstHistory).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
var flow = model.FlowHistory{
|
||
ApplyId: FirstHistory.ApplyId,
|
||
NodeId: FirstHistory.NodeId,
|
||
NodeType: FirstHistory.NodeType,
|
||
NodeLabel: FirstHistory.NodeLabel,
|
||
FormValue: FirstHistory.FormValue,
|
||
|
||
TemplateId: FirstHistory.TemplateId,
|
||
ApplyUserId: FirstHistory.ApplyUserId,
|
||
ApplyUserNickname: FirstHistory.ApplyUserNickname,
|
||
ApproverId: 0,
|
||
ApproverNickname: "",
|
||
PassStatus: 1, //
|
||
PassRemark: "",
|
||
}
|
||
err = tx.Create(&flow).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var obj model.FlowApply
|
||
convert_util.Copy(&obj, applyDetail)
|
||
obj.Status = 4
|
||
err = tx.Save(&obj).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
LastHistory.PassStatus = 3
|
||
LastHistory.PassRemark = back.Remark
|
||
err = tx.Save(&LastHistory).Error
|
||
|
||
return err
|
||
})
|
||
|
||
return err
|
||
} else {
|
||
|
||
err = service.db.Transaction(func(tx *gorm.DB) error {
|
||
var historyDetail, err = service.Detail(back.HistoryId)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
LastHistory.PassStatus = 3
|
||
LastHistory.PassRemark = back.Remark
|
||
tx.Save(&LastHistory)
|
||
var flow = model.FlowHistory{
|
||
ApplyId: historyDetail.ApplyId,
|
||
NodeId: historyDetail.NodeId,
|
||
NodeType: historyDetail.NodeType,
|
||
NodeLabel: historyDetail.NodeLabel,
|
||
FormValue: historyDetail.FormValue,
|
||
|
||
ApplyUserId: historyDetail.ApplyUserId,
|
||
TemplateId: historyDetail.TemplateId,
|
||
ApplyUserNickname: historyDetail.ApplyUserNickname,
|
||
ApproverId: historyDetail.ApproverId,
|
||
ApproverNickname: historyDetail.ApplyUserNickname,
|
||
|
||
PassStatus: 1, //
|
||
PassRemark: "",
|
||
}
|
||
err = tx.Create(&flow).Error
|
||
return err
|
||
})
|
||
|
||
return err
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取下一批流程,直到审批或结束节点
|
||
*/
|
||
func (service flowHistoryService) GetNextNode(ApplyId int) (res []flowSchema.FlowTree, apply flowSchema.FlowApplyResp, LastHistory model.FlowHistory, e error) {
|
||
var applyDetail, err = ApplyService.Detail(ApplyId)
|
||
|
||
if e = response.CheckErr(err, "获取审批申请失败"); e != nil {
|
||
return
|
||
}
|
||
// 获取最后一条历史记录
|
||
// var LastHistory model.FlowHistory
|
||
result := service.db.Where(model.FlowHistory{
|
||
ApplyId: ApplyId,
|
||
}).Limit(1).Last(&LastHistory)
|
||
|
||
// start
|
||
var flowTree []flowSchema.FlowTree
|
||
json.Unmarshal([]byte(applyDetail.FlowProcessDataList), &flowTree)
|
||
var formValue map[string]interface{}
|
||
|
||
if result.RowsAffected == 1 { //有最新审批记录
|
||
json.Unmarshal([]byte(LastHistory.FormValue), &formValue)
|
||
|
||
} else {
|
||
json.Unmarshal([]byte(applyDetail.FormValue), &formValue)
|
||
}
|
||
|
||
var next []flowSchema.FlowTree
|
||
if result.RowsAffected == 0 {
|
||
for _, v := range flowTree {
|
||
if v.Type == "bpmn:startEvent" {
|
||
next = []flowSchema.FlowTree{v}
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
for _, v := range flowTree {
|
||
if v.Id == LastHistory.NodeId {
|
||
fmt.Println(v.Children)
|
||
if v.Children == nil {
|
||
break
|
||
}
|
||
next = *v.Children
|
||
break
|
||
}
|
||
}
|
||
}
|
||
res = DeepNextNode(&next, formValue)
|
||
return res, applyDetail, LastHistory, e
|
||
}
|
||
|
||
// 返回节点数组,最后一个节点为用户或结束节点
|
||
func DeepNextNode(flowTree *[]flowSchema.FlowTree, formValue map[string]interface{}) []flowSchema.FlowTree {
|
||
var nextNodes []flowSchema.FlowTree
|
||
for _, v := range *flowTree {
|
||
if v.Type == "bpmn:startEvent" {
|
||
nextNodes = append(nextNodes, v)
|
||
|
||
// 开始节点
|
||
if v.Children == nil {
|
||
break
|
||
}
|
||
child := DeepNextNode(v.Children, formValue)
|
||
nextNodes = append(nextNodes, child...)
|
||
break
|
||
} else if v.Type == "bpmn:exclusiveGateway" {
|
||
// 网关
|
||
// v.Gateway
|
||
var haveFalse = false
|
||
var gateway = *v.Gateway
|
||
for i := 0; i < len(gateway); i++ {
|
||
var id = gateway[i].Id
|
||
var value = gateway[i].Value
|
||
var condition = gateway[i].Condition
|
||
if condition == "==" {
|
||
if formValue[id].(string) == value { // 等与
|
||
|
||
} else {
|
||
haveFalse = true
|
||
}
|
||
} else if condition == "!=" {
|
||
if formValue[id].(string) != value { // 不等与
|
||
|
||
} else {
|
||
haveFalse = true
|
||
}
|
||
} else if condition == ">=" {
|
||
var val, err = strconv.Atoi(value)
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
continue
|
||
}
|
||
var formVal = formValue[id].(int64)
|
||
if formVal >= int64(val) { // 大于等于
|
||
|
||
} else {
|
||
haveFalse = true
|
||
}
|
||
} else if condition == "<=" {
|
||
var val, err = strconv.Atoi(value)
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
continue
|
||
}
|
||
var formVal = formValue[id].(int64)
|
||
|
||
if formVal <= int64(val) { // 小于等于
|
||
|
||
} else {
|
||
haveFalse = true
|
||
}
|
||
} else {
|
||
haveFalse = true
|
||
fmt.Println("未知的条件")
|
||
}
|
||
|
||
}
|
||
// 不满足条件,继续循环
|
||
if haveFalse {
|
||
continue
|
||
} else {
|
||
nextNodes = append(nextNodes, v)
|
||
|
||
if v.Children == nil {
|
||
break
|
||
}
|
||
// 判断formValue值,决定是不是递归这个网关
|
||
child := DeepNextNode(v.Children, formValue)
|
||
nextNodes = append(nextNodes, child...)
|
||
break
|
||
}
|
||
} else if v.Type == "bpmn:serviceTask" {
|
||
nextNodes = append(nextNodes, v)
|
||
if v.Children == nil {
|
||
break
|
||
}
|
||
// 系统服务
|
||
child := DeepNextNode(v.Children, formValue)
|
||
nextNodes = append(nextNodes, child...)
|
||
} else if v.Type == "bpmn:userTask" {
|
||
//用户节点
|
||
nextNodes = append(nextNodes, v)
|
||
break
|
||
} else if v.Type == "bpmn:endEvent" {
|
||
// 结束节点
|
||
nextNodes = append(nextNodes, v)
|
||
break
|
||
}
|
||
}
|
||
return nextNodes
|
||
}
|