完善驳回

This commit is contained in:
xiangheng
2023-12-28 19:07:19 +08:00
parent 8a203896f0
commit 5627068c4d
13 changed files with 337 additions and 38 deletions

View File

@@ -41,3 +41,7 @@ export function flow_history_get_approver(params: Record<string, any>) {
export function flow_history_pass(params: Record<string, any>) {
return request.post({ url: '/flow/flow_history/pass', params })
}
export function flow_history_back(params: Record<string, any>) {
return request.post({ url: '/flow/flow_history/back', params })
}

View File

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

View File

@@ -16,6 +16,12 @@
>
</v-form-render>
审批历史
<div v-for="history of historyList" :key="history.id">
{{ history.applyId }}{{ history.approverNickname || '无名' }} {{ history.passStatus }}
{{ history.passRemark }}
</div>
<!-- {{ historyList }} -->
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button v-if="applyDetail.status == 1" type="primary" @click="onSubmit">
@@ -29,6 +35,8 @@
import { ref } from 'vue'
import 'vform3-builds/dist/designer.style.css' //引入VForm3样式
import { flow_history_list_all } from '@/api/flow/flow_history'
const formJson = ref({})
const formData = ref({})
const optionData = reactive({})
@@ -37,6 +45,8 @@ const vFormRef = ref(null)
const dialogVisible = ref(false)
const applyDetail = ref({})
const historyList = ref({})
const props = defineProps({
save: {
type: Function,
@@ -45,12 +55,21 @@ const props = defineProps({
})
function open(row, form_json, form_data) {
applyDetail.value = row
getHistoryList(row.id)
formData.value = form_data
formJson.value = form_json
console.log('open')
dialogVisible.value = true
}
async function getHistoryList(applyId) {
try {
historyList.value = await flow_history_list_all({
applyId: applyId
})
} catch (error) {
historyList.value = []
}
}
function closeFn() {
dialogVisible.value = false
applyDetail.value = {}

View File

@@ -0,0 +1,121 @@
<template>
<el-dialog
v-model="dialogVisible"
:show-close="true"
:fullscreen="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
:title="title"
top="1px"
>
<el-form
ref="formRef"
:model="formData"
label-position="top"
label-width="110px"
:rules="formRules"
>
{{ back_nodes }}
<el-form-item :label="`驳回到`" prop="templateId">
<el-select class="flex-1" v-model="formData.historyId" placeholder="请选择驳回节点">
<el-option label="发起人" :value="0" clearable />
<el-option
v-for="item in back_nodes"
:key="item.id"
:label="item.nodeLabel"
:value="item.id"
clearable
/>
</el-select>
</el-form-item>
<el-form-item label="审批意见" prop="remark" v-if="props.showRemark">
<el-input
v-model="formData.remark"
:rows="2"
type="textarea"
placeholder="请输入审批意见"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="warning" @click="submit"> 驳回 </el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import feedback from '@/utils/feedback'
import { flow_history_back, flow_history_list_all } from '@/api/flow/flow_history'
const props = defineProps({
title: {
type: String,
default: ''
},
showRemark: {
type: Boolean,
default: true
}
})
const dialogVisible = ref(false)
// const props = defineProps({
// save: {
// type: Function,
// default: () => {}
// }
// })
class formDataState {
applyId = '' // 申请id
historyId: 0 //审批节点,0为发起人
remark = '' // 备注
}
const formData = reactive(new formDataState())
const back_nodes = ref([])
const formRules = {
applyUserId: [
{
required: true,
message: '请选择',
trigger: ['blur']
}
]
}
function open(applyId) {
console.log('open')
Object.assign(formData, new formDataState())
formData.applyId = applyId
dialogVisible.value = true
flow_history_list_all({
applyId: applyId,
nodeType: 'bpmn:userTask',
passStatus: 2
}).then((userNode) => {
console.log('userNode', userNode)
back_nodes.value = userNode
})
}
function BeforeClose() {
dialogVisible.value = false
}
function submit() {
flow_history_back(formData).then(() => {
BeforeClose()
})
}
defineExpose({
open
})
</script>
<style lang="scss">
// body {
// margin: 0; /* 如果页面出现垂直滚动条则加入此行CSS以消除之 */
// }
</style>

View File

@@ -72,15 +72,16 @@ function closeFn() {
applyDetail.value = {}
formData.value = {}
formJson.value = {}
historyDetail.value = {}
}
function onBack() {
emit('back')
emit('back', historyDetail.value)
}
function onSubmit() {
vFormRef.value.getFormData().then((formData) => {
console.log('formData', formData)
props
.save(applyDetail.value?.id, formData)
.save(historyDetail.value?.id, formData)
.then(() => {
closeFn()
})

View File

@@ -79,6 +79,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'
const userStore = useUserStore()
defineOptions({
@@ -86,6 +87,7 @@ defineOptions({
})
const ApproveRef = shallowRef<InstanceType<typeof ApproveRef>>()
const viewFormRef = shallowRef<InstanceType<typeof ViewForm>>()
// const ApplySubmitRef = shallowRef<InstanceType<typeof ApplySubmit>>()
const queryParams = reactive({

View File

@@ -66,7 +66,10 @@
<!-- <Approve ref="ApproveRef"></Approve> -->
<ViewForm ref="viewFormRef" :save="SaveViewForm"></ViewForm>
<ViewForm ref="viewFormRef" :save="SaveViewForm" @back="OpenBack"></ViewForm>
<Back ref="backRef"></Back>
<ApplySubmit ref="ApplySubmitRef" title="审批" @close="getLists"></ApplySubmit>
</div>
</template>
@@ -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<InstanceType<typeof ApproveRef>>()
const viewFormRef = shallowRef<InstanceType<typeof ViewForm>>()
const ApplySubmitRef = shallowRef<InstanceType<typeof ApplySubmit>>()
const backRef = shallowRef<InstanceType<typeof Back>>()
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()
</script>

View File

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

View File

@@ -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)
}
// 获取下一个审批节点,中间可能存在系统任务节点和网关

View File

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

View File

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

View File

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

View File

@@ -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:'通过备注'"` // 通过备注