feat:【工作流】添加vue2版本的退回和委派前端代码

This commit is contained in:
liuxiaolu 2023-10-11 16:08:39 +08:00
parent 6388950ab2
commit 9a876cff3d
3 changed files with 230 additions and 42 deletions

View File

@ -61,3 +61,25 @@ export function getTaskListByProcessInstanceId(processInstanceId) {
method: 'get',
})
}
export function getReturnList(taskId) {
return request({
url: '/bpm/task/get-return-list?taskId='+ taskId,
method: 'get',
})
}
export function returnTask(data) {
return request({
url: '/bpm/task/return',
method: 'PUT',
data: data
})
}
export function delegateTask(data) {
return request({
url: '/bpm/task/delegate',
method: 'PUT',
data: data
})
}

View File

@ -233,6 +233,10 @@ export default {
return 'highlight-reject';
} else if (result === 4) { //
return 'highlight-cancel';
} else if (result === 5) { // 退
return 'highlight-back';
} else if (result === 6) { //
return 'highlight-todo';
}
return '';
},
@ -475,7 +479,33 @@ export default {
:deep(.highlight-cancel.djs-connection > .djs-visual > path) {
stroke: grey !important;
}
/**驳回 */
.highlight-back.djs-connection > .djs-visual > path {
stroke: #FFBA00 !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.highlight-back.djs-shape .djs-visual > :nth-child(1) {
fill: #FFBA00 !important;
stroke: #FFBA00 !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight-back.djs-connection > .djs-visual > path) {
stroke: #FFBA00 !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
marker-end: url(#sequenceflow-end-_E7DFDF-_E7DFDF-803g1kf6zwzmcig1y2ulm5egr);
}
:deep(.highlight-back.djs-shape .djs-visual > :nth-child(1)) {
fill: #FFBA00 !important;
stroke: #FFBA00 !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.element-overlays {
box-sizing: border-box;
padding: 8px;

View File

@ -5,7 +5,7 @@
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">审批任务{{ item.name }}</span>
</div>
<el-col :span="16" :offset="6" >
<el-col :span="16" :offset="6">
<el-form :ref="'form' + index" :model="auditForms[index]" :rules="auditRule" label-width="100px">
<el-form-item label="流程名" v-if="processInstance && processInstance.name">
{{ processInstance.name }}
@ -15,15 +15,20 @@
<el-tag type="info" size="mini">{{ processInstance.startUser.deptName }}</el-tag>
</el-form-item>
<el-form-item label="审批建议" prop="reason">
<el-input type="textarea" v-model="auditForms[index].reason" placeholder="请输入审批建议" />
<el-input type="textarea" v-model="auditForms[index].reason" placeholder="请输入审批建议"/>
</el-form-item>
</el-form>
<div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px;">
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleAudit(item, true)">通过</el-button>
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleAudit(item, false)">不通过</el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleUpdateAssignee(item)">转办</el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate(item)">委派</el-button>
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleBack(item)">退回</el-button>
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleAudit(item, true)">通过
</el-button>
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleAudit(item, false)">不通过
</el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleUpdateAssignee(item)">转办
</el-button>
<el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate(item)">委派
</el-button>
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleBackList(item)">退回
</el-button>
</div>
</el-col>
</el-card>
@ -34,8 +39,8 @@
</div>
<el-col v-if="this.processInstance.processDefinition && this.processInstance.processDefinition.formType === 10"
:span="16" :offset="6">
<div >
<parser :key="new Date().getTime()" :form-conf="detailForm" />
<div>
<parser :key="new Date().getTime()" :form-conf="detailForm"/>
</div>
</el-col>
<div v-if="this.processInstance.processDefinition && this.processInstance.processDefinition.formType === 20">
@ -48,7 +53,7 @@
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">审批记录</span>
</div>
<el-col :span="16" :offset="4" >
<el-col :span="16" :offset="4">
<div class="block">
<el-timeline>
<el-timeline-item v-for="(item, index) in tasks" :key="index"
@ -62,9 +67,12 @@
<label style="font-weight: normal" v-if="item.createTime">创建时间</label>
<label style="color:#8a909c; font-weight: normal">{{ parseTime(item.createTime) }}</label>
<label v-if="item.endTime" style="margin-left: 30px;font-weight: normal">审批时间</label>
<label v-if="item.endTime" style="color:#8a909c;font-weight: normal"> {{ parseTime(item.endTime) }}</label>
<label v-if="item.endTime" style="color:#8a909c;font-weight: normal"> {{
parseTime(item.endTime)
}}</label>
<label v-if="item.durationInMillis" style="margin-left: 30px;font-weight: normal">耗时</label>
<label v-if="item.durationInMillis" style="color:#8a909c;font-weight: normal"> {{ getDateStar(item.durationInMillis) }} </label>
<label v-if="item.durationInMillis" style="color:#8a909c;font-weight: normal">
{{ getDateStar(item.durationInMillis) }} </label>
<p v-if="item.reason">
<el-tag :type="getTimelineItemType(item)">{{ item.reason }}</el-tag>
</p>
@ -81,15 +89,16 @@
<span class="el-icon-picture-outline">流程图</span>
</div>
<my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" :activityData="activityList"
:processInstanceData="processInstance" :taskData="tasks" />
:processInstanceData="processInstance" :taskData="tasks"/>
</el-card>
<!-- 对话框(审批人) -->
<el-dialog title="转审批人" :visible.sync="updateAssignee.open" width="500px" append-to-body>
<!-- 对话框(审批人) -->
<el-dialog title="转审批人" :visible.sync="updateAssignee.open" width="500px" append-to-body>
<el-form ref="updateAssigneeForm" :model="updateAssignee.form" :rules="updateAssignee.rules" label-width="110px">
<el-form-item label="新审批人" prop="assigneeUserId">
<el-select v-model="updateAssignee.form.assigneeUserId" clearable style="width: 100%">
<el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname" :value="parseInt(item.id)" />
<el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname"
:value="parseInt(item.id)"/>
</el-select>
</el-form-item>
</el-form>
@ -98,17 +107,64 @@
<el-button @click="cancelUpdateAssigneeForm"> </el-button>
</div>
</el-dialog>
<!-- 对话框(委派审批人) -->
<el-dialog title="委派审批人" :visible.sync="updateDelegate.open" width="500px" append-to-body>
<el-form ref="updateDelegateForm" :model="updateDelegate.form" :rules="updateDelegate.rules" label-width="110px">
<el-form-item label="新审批人" prop="assigneeUserId">
<el-select v-model="updateDelegate.form.delegateUserId" clearable style="width: 100%">
<el-option v-for="item in userOptions" :key="parseInt(item.id)" :label="item.nickname"
:value="parseInt(item.id)"/>
</el-select>
</el-form-item>
<el-form-item label="委派理由" prop="reason">
<el-input v-model="updateDelegate.form.reason" clearable placeholder="请输入委派理由"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitUpdateDelegateForm"> </el-button>
<el-button @click="cancelUpdateDelegateForm"> </el-button>
</div>
</el-dialog>
<!--退回流程-->
<el-dialog title="退回流程" :visible.sync="returnOpen" width="40%" append-to-body>
<el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="formRules" label-width="110px">
<el-form-item label="退回节点" prop="targetDefinitionKey">
<el-select v-model="formData.targetDefinitionKey" clearable style="width: 100%">
<el-option
v-for="item in returnList"
:key="item.definitionKey"
:label="item.name"
:value="item.definitionKey"
/>
</el-select>
</el-form-item>
<el-form-item label="回退理由" prop="reason">
<el-input v-model="formData.reason" clearable placeholder="请输入回退理由"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="returnOpen = false"> </el-button>
<el-button :disabled="formLoading" type="primary" @click="submitReturn"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {getProcessDefinitionBpmnXML} from "@/api/bpm/definition";
import {DICT_TYPE, getDictDatas} from "@/utils/dict";
import store from "@/store";
import {decodeFields} from "@/utils/formGenerator";
import Parser from '@/components/parser/Parser'
import {getProcessInstance} from "@/api/bpm/processInstance";
import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task";
import {
approveTask,
delegateTask,
getReturnList,
getTaskListByProcessInstanceId,
rejectTask,
returnTask,
updateTaskAssignee,
} from "@/api/bpm/task";
import {getDate} from "@/utils/dateUtils";
import {listSimpleUsers} from "@/api/system/user";
import {getActivityList} from "@/api/bpm/activity";
@ -127,12 +183,23 @@ export default {
//
id: undefined, //
processInstance: {},
formLoading: false,
//
detailForm: {
fields: []
},
//退
returnList: [],
formData: {
id: '',
targetDefinitionKey: undefined,
reason: ''
},
formRules: {
targetDefinitionKey: [{required: true, message: '必须选择回退节点', trigger: 'change'}],
reason: [{required: true, message: '回退理由不能为空', trigger: 'blur'}]
},
returnOpen: false,
// BPMN
bpmnXML: null,
bpmnControlForm: {
@ -148,9 +215,8 @@ export default {
runningTasks: [],
auditForms: [],
auditRule: {
reason: [{ required: true, message: "审批建议不能为空", trigger: "blur" }],
reason: [{required: true, message: "审批建议不能为空", trigger: "blur"}],
},
//
userOptions: [],
updateAssignee: {
@ -159,7 +225,18 @@ export default {
assigneeUserId: undefined,
},
rules: {
assigneeUserId: [{ required: true, message: "新审批人不能为空", trigger: "change" }],
assigneeUserId: [{required: true, message: "新审批人不能为空", trigger: "change"}],
}
},
updateDelegate: {
open: false,
form: {
delegateUserId: undefined,
reason: ''
},
rules: {
delegateUserId: [{required: true, message: "新审批人不能为空", trigger: "change"}],
reason: [{required: true, message: '委派理由不能为空', trigger: 'blur'}]
}
}
};
@ -193,7 +270,7 @@ export default {
//
const path = this.processInstance.processDefinition.formCustomViewPath;
Vue.component("async-biz-form-component", function(resolve) {
Vue.component("async-biz-form-component", function (resolve) {
require([`@/views${path}`], resolve);
});
@ -260,7 +337,7 @@ export default {
//
const userId = store.getters.userId;
this.tasks.forEach(task => {
if (task.result !== 1) { //
if (task.result !== 1 && task.result !== 6) { //
return;
}
if (!task.assigneeUser || task.assigneeUser.id !== userId) { //
@ -292,6 +369,9 @@ export default {
if (item.result === 4) {
return 'el-icon-remove-outline';
}
if (item.result === 5) {
return 'el-icon-back'
}
return '';
},
getTimelineItemType(item) {
@ -307,6 +387,12 @@ export default {
if (item.result === 4) {
return 'info';
}
if (item.result === 5) {
return 'warning';
}
if (item.result === 6) {
return 'default'
}
return '';
},
/** 处理审批通过和不通过的操作 */
@ -333,7 +419,7 @@ export default {
}
});
},
/** 处理转审批人 */
/** 处理转审批人 */
handleUpdateAssignee(task) {
//
this.resetUpdateAssigneeForm();
@ -341,25 +427,25 @@ export default {
//
this.updateAssignee.open = true;
},
/** 提交转审批人 */
/** 提交转审批人 */
submitUpdateAssigneeForm() {
this.$refs['updateAssigneeForm'].validate(valid => {
if (!valid) {
return;
}
updateTaskAssignee(this.updateAssignee.form).then(response => {
this.$modal.msgSuccess("转任务成功!");
this.$modal.msgSuccess("转任务成功!");
this.updateAssignee.open = false;
this.getDetail(); //
});
});
},
/** 取消转审批人 */
/** 取消转审批人 */
cancelUpdateAssigneeForm() {
this.updateAssignee.open = false;
this.resetUpdateAssigneeForm();
},
/** 重置转审批人 */
/** 重置转审批人 */
resetUpdateAssigneeForm() {
this.updateAssignee.form = {
id: undefined,
@ -367,22 +453,72 @@ export default {
};
this.resetForm("updateAssigneeForm");
},
/** 处理审批退回的操作 */
/** 处理审批委派的操作 */
handleDelegate(task) {
this.$modal.msgError("暂不支持【委派】功能,可以使用【转派】替代!");
//this.$modal.msgError("使");
this.resetUpdateDelegateForm();
this.updateDelegate.form.id = task.id;
//
this.updateDelegate.open = true;
},
/** 提交委派审批人 */
submitUpdateDelegateForm() {
this.$refs['updateDelegateForm'].validate(valid => {
if (!valid) {
return;
}
delegateTask(this.updateDelegate.form).then(response => {
this.$modal.msgSuccess("委派任务成功!");
this.updateDelegate.open = false;
this.getDetail(); //
});
});
},
/** 取消委派审批人 */
cancelUpdateDelegateForm() {
this.updateDelegate.open = false;
this.resetUpdateDelegateForm();
},
/** 重置委派审批人 */
resetUpdateDelegateForm() {
this.updateDelegate.form = {
id: undefined,
delegateUserId: undefined,
};
this.resetForm("updateDelegateForm");
},
/** 处理审批退回的操作 */
handleBack(task) {
this.$modal.msgError("暂不支持【退回】功能!");
/** 返回退回节点列表 */
handleBackList(task) {
// http://blog.wya1.com/article/636697030/details/7296
// const data = {
// id: task.id,
// assigneeUserId: 1
// }
// backTask(data).then(response => {
// this.$modal.msgSuccess("退");
// this.getDetail(); //
// });
getReturnList(task.id).then(response => {
this.returnList = response.data;
if (this.returnList.length == 0) {
this.$modal.msgError("当前没有可回退的节点!");
return;
}
this.formData.id = task.id;
this.returnOpen = true;
});
},
/** 提交退回任务 */
submitReturn() {
if (!this.formData.targetDefinitionKey) {
this.$modal.msgError("请选择退回节点!");
}
this.$refs['formRef'].validate(valid => {
if (!valid) {
return;
}
returnTask(this.formData).then(res => {
if (res.data) {
this.$modal.msgSuccess("回退成功!");
this.returnOpen = false;
this.getDetail();
}
});
});
}
}
};