diff --git a/admin/src/api/flow/flow_history.ts b/admin/src/api/flow/flow_history.ts index 5657365..a1df808 100644 --- a/admin/src/api/flow/flow_history.ts +++ b/admin/src/api/flow/flow_history.ts @@ -41,3 +41,7 @@ export function flow_history_get_approver(params: Record) { export function flow_history_pass(params: Record) { return request.post({ url: '/flow/flow_history/pass', params }) } + +export function flow_history_back(params: Record) { + return request.post({ url: '/flow/flow_history/back', params }) +} diff --git a/admin/src/config/index.ts b/admin/src/config/index.ts index 7c9c95f..d4840d8 100644 --- a/admin/src/config/index.ts +++ b/admin/src/config/index.ts @@ -5,7 +5,7 @@ const config = { // import.meta.env.VITE_APP_BASE_URL || baseUrl: '', //请求接口域名 urlPrefix: '/api', //请求默认前缀 - timeout: 60 * 1000 //请求超时时长 + timeout: 60 * 3000 //请求超时时长 } export default config diff --git a/admin/src/views/flow/flow_apply/components/ViewForm.vue b/admin/src/views/flow/flow_apply/components/ViewForm.vue index 96d1551..035c1e3 100644 --- a/admin/src/views/flow/flow_apply/components/ViewForm.vue +++ b/admin/src/views/flow/flow_apply/components/ViewForm.vue @@ -16,6 +16,12 @@ > + 审批历史 +
+ {{ history.applyId }}{{ history.approverNickname || '无名' }} {{ history.passStatus }} + {{ history.passRemark }} +
+ @@ -79,6 +82,7 @@ import feedback from '@/utils/feedback' import useUserStore from '@/stores/modules/user' import ApplySubmit from '@/views/flow/flow_apply/components/apply_submit.vue' import ViewForm from './components/ViewForm.vue' +import Back from './components/Back.vue' const userStore = useUserStore() defineOptions({ @@ -87,6 +91,7 @@ defineOptions({ const ApproveRef = shallowRef>() const viewFormRef = shallowRef>() const ApplySubmitRef = shallowRef>() +const backRef = shallowRef>() const queryParams = reactive({ approverId: userStore?.userInfo?.id, @@ -124,20 +129,19 @@ const OpenViewForm = async (row: any) => { viewFormRef.value?.open(applyDetail, row, form_json, form_data) } -const SaveViewForm = (id, form_data) => { +const SaveViewForm = (historyId, form_data) => { return new Promise((resolve, reject) => { flow_history_edit({ - id: id, + id: historyId, formValue: JSON.stringify(form_data) }) .then(async () => { feedback.msgSuccess('保存成功') await getLists() - const row = pager.lists.find((item) => item.id === id) - - ApplySubmitRef.value?.open(row.applyId) + const row = pager.lists.find((item) => item.id === historyId) + OpenApplySubmit(row) resolve(true) }) .catch((err) => { @@ -151,5 +155,11 @@ const OpenApplySubmit = async (row: any) => { ApplySubmitRef.value?.open(row.applyId) } +const OpenBack = async (row: any) => { + console.log('OpenBack') + + backRef.value?.open(row.applyId) +} + getLists() diff --git a/server/admin/flow/enter.go b/server/admin/flow/enter.go index eb1c34a..09bed85 100644 --- a/server/admin/flow/enter.go +++ b/server/admin/flow/enter.go @@ -53,6 +53,8 @@ func FlowHistoryRoute(rg *gin.RouterGroup) { rg.POST("/flow_history/del", handle.Del) rg.POST("/flow_history/pass", handle.Pass) + rg.POST("/flow_history/back", handle.Back) + rg.POST("/flow_history/next_node", handle.NextNode) rg.POST("/flow_history/get_approver", handle.GetApprover) } diff --git a/server/admin/flow/flow_history/flow_history_ctl.go b/server/admin/flow/flow_history/flow_history_ctl.go index 7dc4eb6..948fd09 100644 --- a/server/admin/flow/flow_history/flow_history_ctl.go +++ b/server/admin/flow/flow_history/flow_history_ctl.go @@ -49,9 +49,12 @@ func (hd FlowHistoryHandler) List(c *gin.Context) { // @Tags flow_history-流程历史 // @Produce json // @Success 200 {object} []FlowHistoryResp "成功" -// @Router /api/flow_history/list [get] +// @Router /api/flow_history/listAll [get] func (hd FlowHistoryHandler) ListAll(c *gin.Context) { var listReq FlowHistoryListReq + if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) { + return + } res, err := Service.ListAll(listReq) response.CheckAndRespWithData(c, res, err) } @@ -136,9 +139,9 @@ func (hd FlowHistoryHandler) Del(c *gin.Context) { response.CheckAndResp(c, Service.Del(delReq.Id)) } -// 提交申请 +// 提交申请,通过审批 // -// @Router /api/flow_apply/SubmitApply [post] +// @Router /api/flow_apply/pass [post] func (hd FlowHistoryHandler) Pass(c *gin.Context) { var pass PassReq if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &pass)) { @@ -146,23 +149,17 @@ func (hd FlowHistoryHandler) Pass(c *gin.Context) { } err := Service.Pass(pass) response.CheckAndResp(c, err) +} - // 申请流程id, - // var addReq FlowApplyAddReq - // if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &addReq)) { - // return - // } - - // var Nickname = config.AdminConfig.GetNickname(c) - // var AdminId = config.AdminConfig.GetAdminId(c) - // addReq.ApplyUserNickname = Nickname - // addReq.ApplyUserId = int(AdminId) - // 解析json - // 查找开始节点 - // 查找开始的下一级节点 - // 下一个可能是网关,系统任务,用户任务,结束 - // 网关,系统任务节点处理后继续向下查找节点,网关只能有一个满足条件 - +// 拒绝审批 +// @Router /api/flow_apply/back [post] +func (hd FlowHistoryHandler) Back(c *gin.Context) { + var back BackReq + if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &back)) { + return + } + err := Service.Back(back) + response.CheckAndResp(c, err) } // 获取下一个审批节点,中间可能存在系统任务节点和网关 diff --git a/server/admin/flow/flow_history/flow_history_schema.go b/server/admin/flow/flow_history/flow_history_schema.go index 2e40180..b7ea03c 100644 --- a/server/admin/flow/flow_history/flow_history_schema.go +++ b/server/admin/flow/flow_history/flow_history_schema.go @@ -11,6 +11,8 @@ type FlowHistoryListReq struct { ApproverId int `form:"approverId"` // 审批人id ApproverNickname string `form:"approverNickname"` // 审批用户昵称 NodeId string `form:"nodeId"` // 节点 + NodeLabel string `form:"nodeLabel"` // 节点名称 + NodeType string `form:"nodeType"` // 节点类型 FormValue string `form:"formValue"` // 表单值 PassStatus int `form:"passStatus"` // 通过状态:1待处理,2通过,3拒绝 PassRemark string `form:"passRemark"` // 通过备注 @@ -30,6 +32,8 @@ type FlowHistoryAddReq struct { ApproverId int `form:"approverId"` // 审批人id ApproverNickname string `form:"approverNickname"` // 审批用户昵称 NodeId string `form:"nodeId"` // 节点 + NodeLabel string `form:"nodeLabel"` // 节点名称 + NodeType string `form:"nodeType"` // 节点类型 FormValue string `form:"formValue"` // 表单值 PassStatus int `form:"passStatus"` // 通过状态:1待处理,2通过,3拒绝 PassRemark string `form:"passRemark"` // 通过备注 @@ -45,6 +49,8 @@ type FlowHistoryEditReq struct { ApproverId int `form:"approverId"` // 审批人id ApproverNickname string `form:"approverNickname"` // 审批用户昵称 NodeId string `form:"nodeId"` // 节点 + NodeLabel string `form:"nodeLabel"` // 节点名称 + NodeType string `form:"nodeType"` // 节点类型 FormValue string `form:"formValue"` // 表单值 PassStatus int `form:"passStatus"` // 通过状态:1待处理,2通过,3拒绝 PassRemark string `form:"passRemark"` // 通过备注 @@ -65,6 +71,8 @@ type FlowHistoryResp struct { ApproverId int `json:"approverId" structs:"approverId"` // 审批人id ApproverNickname string `json:"approverNickname" structs:"approverNickname"` // 审批用户昵称 NodeId string `json:"nodeId" structs:"nodeId"` // 节点 + NodeType string `json:"nodeType" structs:"nodeType"` // 节点类型 + NodeLabel string `json:"nodeLabel" structs:"nodeLabel"` // 节点名称 FormValue string `json:"formValue" structs:"formValue"` // 表单值 PassStatus int `json:"passStatus" structs:"passStatus"` // 通过状态:1待处理,2通过,3拒绝 PassRemark string `json:"passRemark" structs:"passRemark"` // 通过备注 @@ -109,3 +117,9 @@ type PassReq struct { NextNodeAdminId int `form:"nextNodeAdminId"` // 下一个节点的审批用户id PassRemark string `form:"passRemark"` // 通过备注 } +type BackReq struct { + ApplyId int `form:"applyId"` // 申请id + // Type int `form:"type"` //驳回类型:1申请人,2审批节点 + HistoryId int `form:"historyId"` //审批节点 + Remark string `form:"Remark"` // 备注 +} diff --git a/server/admin/flow/flow_history/flow_history_service.go b/server/admin/flow/flow_history/flow_history_service.go index 4c0652b..303f4a1 100644 --- a/server/admin/flow/flow_history/flow_history_service.go +++ b/server/admin/flow/flow_history/flow_history_service.go @@ -110,6 +110,12 @@ func (Service flowHistoryService) ListAll(listReq FlowHistoryListReq) (res []Flo 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 objs []model.FlowHistory err := dbModel.Find(&objs).Error @@ -279,6 +285,8 @@ func (Service flowHistoryService) Pass(pass PassReq) (e error) { var flow = model.FlowHistory{ ApplyId: applyDetail.Id, NodeId: v.Id, + NodeType: v.Type, + NodeLabel: v.Label, FormValue: FormValue, PassStatus: 1, ApplyUserId: applyDetail.ApplyUserId, @@ -286,7 +294,16 @@ func (Service flowHistoryService) Pass(pass PassReq) (e error) { ApplyUserNickname: applyDetail.ApplyUserNickname, ApproverId: 0, } - if v.Type == "bpmn:serviceTask" { + 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" { flow.ApproverId = pass.NextNodeAdminId @@ -309,7 +326,10 @@ func (Service flowHistoryService) Pass(pass PassReq) (e error) { if LastHistory.Id > 0 { LastHistory.PassStatus = 2 LastHistory.PassRemark = pass.PassRemark - tx.Save(&LastHistory) + err = tx.Save(&LastHistory).Error + if err != nil { + return err + } } // 待提交或者有结束节点,修改申请状态 @@ -318,9 +338,9 @@ func (Service flowHistoryService) Pass(pass PassReq) (e error) { if isEnd { status = 3 //审批通过 } - tx.Model(&model.FlowApply{}).Where(model.FlowApply{ + err = tx.Model(&model.FlowApply{}).Where(model.FlowApply{ Id: pass.ApplyId, - }).Update("status", status) + }).Update("status", status).Error if err != nil { return err @@ -332,6 +352,105 @@ func (Service flowHistoryService) Pass(pass PassReq) (e error) { return err } +// 驳回 +func (Service flowHistoryService) Back(back 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 = flow_apply.Service.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, + PassStatus: 1, // + PassRemark: "", + } + err = tx.Create(&flow).Error + if err != nil { + return err + } + + var obj model.FlowApply + response.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, + + PassStatus: 1, // + PassRemark: "", + } + err = tx.Create(&flow).Error + return err + }) + + return err + + } +} + /** * 获取下一批流程,直到审批或结束节点 */ @@ -361,16 +480,19 @@ func (Service flowHistoryService) GetNextNode(ApplyId int) (res []FlowTree, appl var next []FlowTree if result.RowsAffected == 0 { - // if nextNode.CurrentNodeId == "" { for _, v := range flowTree { if v.Type == "bpmn:startEvent" { - next = *v.Children + next = []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 } @@ -386,7 +508,9 @@ func DeepNextNode(nextNodes []FlowTree, flowTree *[]FlowTree, formValue map[stri for _, v := range *flowTree { if v.Type == "bpmn:startEvent" { // 开始节点 + child := DeepNextNode(nextNodes, v.Children, formValue) + nextNodes = append(nextNodes, v) nextNodes = append(nextNodes, child...) break } else if v.Type == "bpmn:exclusiveGateway" { diff --git a/server/generator/tpl_utils/templates/gocode/controller.go.tpl b/server/generator/tpl_utils/templates/gocode/controller.go.tpl index fe327bc..a24c164 100644 --- a/server/generator/tpl_utils/templates/gocode/controller.go.tpl +++ b/server/generator/tpl_utils/templates/gocode/controller.go.tpl @@ -41,9 +41,12 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context) { // @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}} // @Produce json // @Success 200 {object} []{{{ title (toCamelCase .EntityName) }}}Resp "成功" -// @Router /api/{{{ .ModuleName }}}/list [get] +// @Router /api/{{{ .ModuleName }}}/listAll [get] func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Context) { res, err := Service.ListAll() + if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) { + return + } response.CheckAndRespWithData(c, res, err) } diff --git a/server/model/flow_history.go b/server/model/flow_history.go index 59af1c6..363754a 100644 --- a/server/model/flow_history.go +++ b/server/model/flow_history.go @@ -16,11 +16,13 @@ type FlowHistory struct { ApproverNickname string `gorm:"comment:'审批用户昵称'"` // 审批用户昵称 - NodeId string `gorm:"comment:'节点'"` // 节点 + NodeId string `gorm:"comment:'节点'"` // 节点 + NodeType string `gorm:"comment:'节点类型'"` // 节点类型 + NodeLabel string `gorm:"comment:'节点名称'"` //节点名称 FormValue string `gorm:"comment:'表单值'"` // 表单值 - PassStatus int `gorm:"comment:'通过状态:1待处理,2通过,3拒绝'"` // 通过状态:0待处理,1通过,2拒绝 + PassStatus int `gorm:"comment:'通过状态:1待处理,2通过,3拒绝'"` // 通过状态:1待处理,2通过,3拒绝 PassRemark string `gorm:"comment:'通过备注'"` // 通过备注