Browse Source

feat: 流程详情页面优化显示

master
tony 3 years ago
parent
commit
a899003440
  1. 2
      ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowTaskVo.java
  2. 12
      ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java
  3. 19
      ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java
  4. 4
      ruoyi-ui/src/components/flow/Role/index.vue
  5. 8
      ruoyi-ui/src/components/flow/User/index.vue
  6. 50
      ruoyi-ui/src/views/flowable/task/finished/detail/index.vue
  7. 50
      ruoyi-ui/src/views/flowable/task/myProcess/detail/index.vue
  8. 6
      ruoyi-ui/src/views/flowable/task/myProcess/send/flow.vue
  9. 132
      ruoyi-ui/src/views/flowable/task/myProcess/send/flowview.vue
  10. 215
      ruoyi-ui/src/views/flowable/task/myProcess/send/index.vue
  11. 2
      ruoyi-ui/src/views/flowable/task/record/index.vue
  12. 178
      ruoyi-ui/src/views/flowable/task/todo/detail/index.vue
  13. 4
      ruoyi-ui/src/views/flowable/task/todo/index.vue

2
ruoyi-flowable/src/main/java/com/ruoyi/flowable/domain/vo/FlowTaskVo.java

@ -35,7 +35,7 @@ public class FlowTaskVo {
private String deploymentId;
@ApiModelProperty("流程变量信息")
private Map<String, Object> values;
private Map<String, Object> variables;
@ApiModelProperty("审批人")
private String assignee;

12
ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowDefinitionServiceImpl.java

@ -181,7 +181,7 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @param procDefId 流程模板ID
* @param variables 流程变量
* @return
*/
@ -193,13 +193,15 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
return AjaxResult.error("流程已被挂起,请先激活流程");
}
// variables.put("skip", true);
// variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
// 设置流程发起人Id到流程中
SysUser sysUser = SecurityUtils.getLoginUser().getUser();
identityService.setAuthenticatedUserId(sysUser.getUserId().toString());
variables.put(ProcessConstants.PROCESS_INITIATOR, "");
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId());
runtimeService.startProcessInstanceById(procDefId, variables);
// variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUserId());
// variables.put("skip", true);
// variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
// // 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题?
// Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
// if (Objects.nonNull(task)) {

19
ruoyi-flowable/src/main/java/com/ruoyi/flowable/service/impl/FlowTaskServiceImpl.java

@ -90,12 +90,12 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
if (DelegationState.PENDING.equals(task.getDelegationState())) {
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
taskService.resolveTask(taskVo.getTaskId(), taskVo.getValues());
taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
} else {
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
taskService.setAssignee(taskVo.getTaskId(), userId.toString());
taskService.complete(taskVo.getTaskId(), taskVo.getValues());
taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
}
return AjaxResult.success();
}
@ -616,6 +616,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
@Override
public AjaxResult todoList(Integer pageNum, Integer pageSize) {
Page<FlowTaskDto> page = new Page<>();
// 只查看自己的数据
Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
TaskQuery taskQuery = taskService.createTaskQuery()
.active()
@ -648,8 +649,7 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
.processInstanceId(task.getProcessInstanceId())
.singleResult();
SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
flowTask.setStartUserId(startUser.getNickName());
flowTask.setStartUserId(startUser.getUserId().toString());
flowTask.setStartUserName(startUser.getNickName());
flowTask.setStartDeptName(startUser.getDept().getDeptName());
flowList.add(flowTask);
@ -916,6 +916,11 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
*/
@Override
public AjaxResult processVariables(String taskId) {
// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
// .processInstanceId(task.getProcessInstanceId())
// .singleResult();
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
// 流程变量
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult();
if (Objects.nonNull(historicTaskInstance)) {
@ -946,10 +951,8 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
// 会签节点
if (Objects.nonNull(multiInstance)) {
List<SysUser> list = sysUserService.selectUserList(new SysUser());
flowNextDto.setVars(ProcessConstants.PROCESS_MULTI_INSTANCE_USER);
flowNextDto.setType(ProcessConstants.PROCESS_MULTI_INSTANCE);
flowNextDto.setUserList(list);
} else {
// 读取自定义节点属性 判断是否是否需要动态指定任务接收人员、组
String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
@ -982,16 +985,14 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
// Step 1. 获取当前节点并找到下一步节点
FlowNextDto flowNextDto = new FlowNextDto();
// Step 2. 获取当前流程所有流程变量(网关节点时需要校验表达式)
List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasksByStart(repositoryService, processDefinition, new HashMap<>());
List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasksByStart(repositoryService, processDefinition, flowTaskVo.getVariables());
if (CollectionUtils.isNotEmpty(nextUserTask)) {
for (UserTask userTask : nextUserTask) {
MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
// 会签节点
if (Objects.nonNull(multiInstance)) {
List<SysUser> list = sysUserService.selectUserList(new SysUser());
flowNextDto.setVars(ProcessConstants.PROCESS_MULTI_INSTANCE_USER);
flowNextDto.setType(ProcessConstants.PROCESS_MULTI_INSTANCE);
flowNextDto.setUserList(list);
} else {
// 读取自定义节点属性 判断是否是否需要动态指定任务接收人员、组
String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);

4
ruoyi-ui/src/components/flow/Role/index.vue

@ -75,7 +75,7 @@ export default {
checkType: {
type: String,
default: 'multiple',
required: true
required: false
},
},
data() {
@ -126,7 +126,7 @@ export default {
},
roleList: {
handler(newVal) {
if (newVal) {
if (newVal && this.selectRoleList) {
this.$nextTick(() => {
this.$refs.dataTable.clearSelection();
this.selectRoleList?.split(',').forEach(key => {

8
ruoyi-ui/src/components/flow/User/index.vue

@ -35,7 +35,7 @@
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 240px"
style="width: 150px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
@ -44,7 +44,7 @@
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 240px"
style="width: 150px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
@ -181,7 +181,7 @@ export default {
},
userList: {
handler(newVal) {
if (newVal) {
if (newVal && this.selectUserList) {
this.$nextTick(() => {
this.$refs.dataTable.clearSelection();
this.selectUserList?.split(',').forEach(key => {
@ -234,7 +234,7 @@ export default {
//
handleSingleUserSelect(selection) {
this.radioSelected = selection.userId;//,radio
this.$emit('handleUserSelect', selection.toString());
this.$emit('handleUserSelect', selection);
},
/** 搜索按钮操作 */
handleQuery() {

50
ruoyi-ui/src/views/flowable/task/finished/detail/index.vue

@ -1,24 +1,21 @@
<template>
<div class="app-container">
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span class="el-icon-document">基础信息</span>
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button>
</div>
<!--流程处理表单模块-->
<el-col :span="16" :offset="6" v-if="variableOpen">
<div>
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
</el-col>
</el-card>
<!--流程流转记录-->
<el-card class="box-card" v-if="flowRecordList">
<div slot="header" class="clearfix">
<span class="el-icon-notebook-1">审批记录</span>
</div>
<div slot="header" class="clearfix">
<span class="el-icon-document">办结任务</span>
<el-button style="float: right;" size="mini" type="primary" @click="goBack">关闭</el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-col :span="16" :offset="4" v-if="variableOpen">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<el-col :span="16" :offset="4" >
<div class="block">
<el-timeline>
@ -62,12 +59,12 @@
</el-timeline>
</div>
</el-col>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">流程图</span>
</div>
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-tab-pane>
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack">关闭</el-button>
</el-card>
</div>
</template>
@ -76,7 +73,7 @@
import {flowRecord} from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser'
import {getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import flow from '@/views/flowable/task/record/flow'
import flow from '@/views/flowable/task/finished/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import Treeselect from "@riophae/vue-treeselect";
@ -137,6 +134,9 @@ export default {
this.getFlowRecordList( this.taskForm.procInsId, this.taskForm.deployId);
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
getModelDetail(deployId) {
// xml

50
ruoyi-ui/src/views/flowable/task/myProcess/detail/index.vue

@ -1,23 +1,21 @@
<template>
<div class="app-container">
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span class="el-icon-document">基础信息</span>
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button>
</div>
<!--流程处理表单模块-->
<el-col :span="16" :offset="6">
<div>
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
</el-col>
</el-card>
<!--流程流转记录-->
<el-card class="box-card" v-if="flowRecordList">
<div slot="header" class="clearfix">
<span class="el-icon-notebook-1">审批记录</span>
</div>
<div slot="header" class="clearfix">
<span class="el-icon-document">已发任务</span>
<el-button style="float: right;" size="mini" type="primary" @click="goBack">关闭</el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<el-col :span="16" :offset="4" >
<div class="block">
<el-timeline>
@ -61,12 +59,13 @@
</el-timeline>
</div>
</el-col>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">流程图</span>
</div>
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack">关闭</el-button>
</el-card>
</div>
</template>
@ -75,7 +74,7 @@
import {flowRecord} from "@/api/flowable/finished";
import Parser from '@/components/parser/Parser'
import {getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import flow from '@/views/flowable/task/record/flow'
import flow from '@/views/flowable/task/myProcess/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
@ -121,6 +120,9 @@ export default {
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId);
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
getModelDetail(deployId) {
// xml

6
ruoyi-ui/src/views/flowable/task/myProcess/send/flow.vue

@ -6,7 +6,7 @@
:is-view="true"
:taskList="taskData"
/>-->
<flow-view :xmlData="xmlData" :taskList="taskData"/>
<flow-view :xmlData="xmlData"/>
</div>
</template>
<script>
@ -24,10 +24,6 @@ export default {
type: String,
default: ''
},
taskData: {
type: Array,
default: () => []
}
},
data() {
return {};

132
ruoyi-ui/src/views/flowable/task/myProcess/send/flowview.vue

@ -21,14 +21,11 @@ import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
export default {
name: "FlowView",
props: {
// xml
xmlData: {
type: String,
default: ''
},
taskList: {
type: Array,
default: () => []
}
},
data() {
return {
@ -36,10 +33,14 @@ export default {
};
},
watch: {
xmlData: function(val) {
if (val) {
this.getImg(val)
}
xmlData: {
handler(newVal) {
if (newVal) {
this.loadFlowImg(newVal)
}
},
immediate: true, //
deep: true //
}
},
mounted() {
@ -49,28 +50,18 @@ export default {
container: this.$refs.flowCanvas,
height: 'calc(100vh - 200px)',
});
this.getImg(this.xmlData)
},
methods: {
//
async getImg(xmlUrl) {
//
async loadFlowImg(xmlData) {
const self = this
try {
await self.bpmnViewer.importXML(xmlUrl);
await self.bpmnViewer.importXML(xmlData);
self.fitViewport()
if (self.taskList !==undefined && self.taskList.length > 0 ) {
self.fillColor()
}
} catch (err) {
console.error(err.message, err.warnings)
}
},
// class
setNodeColor(nodeCodes, colorClass, canvas) {
for (let i = 0; i < nodeCodes.length; i++) {
canvas.addMarker(nodeCodes[i], colorClass);
}
},
//
fitViewport() {
this.zoom = this.bpmnViewer.get('canvas').zoom("fit-viewport", "auto")
@ -81,78 +72,6 @@ export default {
this.zoom += (zoomIn ? 0.1 : -0.1)
if(this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom)
},
//
fillColor() {
const canvas = this.bpmnViewer.get('canvas')
this.bpmnViewer.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = this.taskList.find(m => m.key === n.id)
const todoTask = this.taskList.find(m => !m.completed)
const endTask = this.taskList[this.taskList.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, todoTask.completed ? 'highlight' : 'highlight-todo')
}else {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
}
})
}
}
//
else if (n.$type === 'bpmn:ExclusiveGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
//
else if (n.$type === 'bpmn:ParallelGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = this.taskList.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')
return
}
})
}
else if (n.$type === 'bpmn:EndEvent') {
if (endTask.key === n.id && endTask.completed) {
canvas.addMarker(n.id, 'highlight')
return
}
}
})
},
}
};
</script>
@ -202,33 +121,6 @@ export default {
min-height: 650px;
}
.highlight.djs-shape .djs-visual > :nth-child(1) {
fill: green !important;
stroke: green !important;
fill-opacity: 0.2 !important;
}
.highlight.djs-shape .djs-visual > :nth-child(2) {
fill: green !important;
}
.highlight.djs-shape .djs-visual > path {
fill: green !important;
fill-opacity: 0.2 !important;
stroke: green !important;
}
.highlight.djs-connection > .djs-visual > path {
stroke: green !important;
}
.highlight-todo.djs-connection > .djs-visual > path {
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.highlight-todo.djs-shape .djs-visual > :nth-child(1) {
fill: orange !important;
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.overlays-div {
font-size: 10px;
color: red;

215
ruoyi-ui/src/views/flowable/task/myProcess/send/index.vue

@ -2,42 +2,34 @@
<div class="app-container">
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span class="el-icon-document">基础信息</span>
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button>
<span class="el-icon-document">发起任务</span>
<el-button style="float: right;" size="mini" type="primary" @click="goBack">关闭</el-button>
</div>
<!--初始化流程加载表单信息-->
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="formConf" @submit="submitForm" ref="parser" @getData="getData" />
</div>
</el-col>
</el-card>
<!--审批正常流程-->
<el-dialog :title="completeTitle" :visible.sync="completeOpen" width="60%" append-to-body>
<el-form ref="taskForm" :model="taskForm">
<el-form-item prop="targetKey">
<!-- <el-row :gutter="24">-->
<flow-user v-if="checkSendUser" :checkType="checkType" @handleUserSelect="handleUserSelect"></flow-user>
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"></flow-role>
<!-- </el-row>-->
</el-form-item>
<el-form-item label="处理意见" label-width="80px" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
<el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeOpen = false"> </el-button>
<el-button type="primary" @click="taskComplete"> </el-button>
</span>
</el-dialog>
<!--流程图-->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">流程图</span>
</div>
<flow :xmlData="xmlData" :taskData="taskList"></flow>
<el-tabs tab-position="top" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<!--初始化流程加载表单信息-->
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="formConf" @submit="submitForm" ref="parser" @getData="getData" />
</div>
</el-col>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData"></flow>
</el-tab-pane>
</el-tabs>
<el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack">关闭</el-button>
<!--选择流程接收人-->
<el-dialog :title="taskTitle" :visible.sync="taskOpen" width="65%" append-to-body>
<flow-user v-if="checkSendUser" :checkType="checkType" @handleUserSelect="handleUserSelect"/>
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"/>
<span slot="footer" class="dialog-footer">
<el-button @click="taskOpen = false"> </el-button>
<el-button type="primary" @click="submitTask"> </el-button>
</span>
</el-dialog>
</el-card>
</div>
</template>
@ -45,26 +37,25 @@
<script>
import Parser from '@/components/parser/Parser'
import {definitionStart, readXml} from "@/api/flowable/definition";
import flow from '@/views/flowable/task/record/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {listUser} from "@/api/system/user";
import flow from '@/views/flowable/task/myProcess/send/flow'
import {flowFormData} from "@/api/flowable/process";
import {getNextFlowNodeByStart} from "@/api/flowable/todo";
import FlowUser from '@/components/flow/User'
import FlowRole from '@/components/flow/Role'
export default {
name: "Record",
components: {
Parser,
flow,
FlowUser,
FlowRole,
},
props: {},
data() {
return {
// xml
xmlData: "",
taskList: [],
//
userList: null,
defaultProps: {
children: "children",
label: "label"
@ -75,45 +66,32 @@ export default {
},
//
loading: true,
rules: {}, //
variablesForm: {}, //
taskForm:{
multiple: false,
comment:"", //
procInsId: "", //
instanceId: "", //
deployId: "", //
taskId: "" ,//
procDefId: "", //
vars: "",
targetKey:""
},
deployId: "", //
procDefId: "", //
formConf: {}, //
variables: [], //
completeTitle: null,
completeOpen: false,
taskTitle: null,
taskOpen: false,
checkSendUser: false, //
checkSendRole: false,//
checkType: 'single', //
checkValues: null, //
formData: {}, // ,
activeValue: 1, // tab
};
},
created() {
this.taskForm.deployId = this.$route.query && this.$route.query.deployId;
this.deployId = this.$route.query && this.$route.query.deployId;
//
this.taskForm.procDefId = this.$route.query && this.$route.query.procDefId;
this.getNextFlowNode(this.taskForm.deployId);
this.getFlowFormData(this.taskForm.deployId);
this.procDefId = this.$route.query && this.$route.query.procDefId;
// this.getNextFlowNodeByStart(this.deployId);
this.getFlowFormData(this.deployId);
//
this.loadModelXml(this.taskForm.deployId);
this.loadModelXml(this.deployId);
},
methods: {
/** 查询用户列表 */
getList() {
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.rows;
this.total = response.total;
}
);
handleClick(tab, event) {
console.log(tab, event);
},
/** xml 文件 */
loadModelXml(deployId) {
@ -162,27 +140,78 @@ export default {
}
},
/** 申请流程表单数据提交 */
submitForm(data) {
if (data) {
const variables = data.valData;
const formData = data.formData;
submitForm(formData) {
// todo
getNextFlowNodeByStart({deploymentId: this.deployId,variables:formData.valData}).then(res => {
const data = res.data;
if (data) {
if (data.type === 'assignee') { //
this.checkSendUser = true;
this.checkType = "single";
} else if (data.type === 'candidateUsers') { // ()
this.checkSendUser = true;
this.checkType = "multiple";
} else if (data.type === 'candidateGroups') { // ()
this.checkSendRole = true;
} else if (data.type === 'multiInstance') { // ?
this.checkSendUser = true;
}
if (this.checkSendUser || this.checkSendRole){
this.taskOpen = true;
this.taskTitle = "选择任务接收";
this.formData = formData;
}
}
})
// else {
// if (data) {
// const variables = data.valData;
// const formData = data.formData;
// formData.disabled = true;
// formData.formBtns = false;
// if (this.taskForm.procDefId) {
// variables.variables = formData;
// //
// definitionStart(this.taskForm.procDefId, JSON.stringify(variables)).then(res => {
// this.msgSuccess(res.msg);
// this.goBack();
// })
// }
// }
// }
},
/** 提交流程 */
submitTask() {
if (!this.checkValues && this.checkSendUser){
this.$modal.msgError("请选择任务接收!");
return;
}
if (!this.checkValues && this.checkSendRole){
this.$modal.msgError("请选择流程接收角色组!");
return;
}
if (this.formData) {
const variables = this.formData.valData;
const formData = this.formData.formData;
//
formData.disabled = true;
//
formData.formBtns = false;
if (this.taskForm.procDefId) {
variables.variables = formData;
//
definitionStart(this.taskForm.procDefId, JSON.stringify(variables)).then(res => {
this.msgSuccess(res.msg);
this.goBack();
})
}
variables.variables = formData;
variables.approval = this.checkValues;
console.log(variables,"流程发起提交表单数据")
//
definitionStart(this.procDefId, JSON.stringify(variables)).then(res => {
this.$modal.msgSuccess(res.msg);
this.goBack();
})
}
},
/** 根据当前任务获取流程设计配置的下一步节点 */
getNextFlowNode(deploymentId) {
getNextFlowNodeByStart(deploymentId,variables) {
// todo
const params = {deploymentId: deploymentId}
getNextFlowNodeByStart(params).then(res => {
getNextFlowNodeByStart({deploymentId: deploymentId,variables:variables}).then(res => {
const data = res.data;
if (data) {
if (data.type === 'assignee') { //
@ -202,15 +231,11 @@ export default {
//
handleUserSelect(selection) {
if (selection) {
const selectVal = selection.map(item => item.userId);
if (selectVal instanceof Array) {
this.taskForm.values = {
"approval": selectVal.join(',')
}
if (selection instanceof Array) {
const selectVal = selection.map(item => item.userId);
this.checkValues = selectVal.join(',')
} else {
this.taskForm.values = {
"approval": selectVal
}
this.checkValues = selection.userId;
}
}
},
@ -219,13 +244,9 @@ export default {
if (selection) {
if (selection instanceof Array) {
const selectVal = selection.map(item => item.roleId);
this.taskForm.values = {
"approval": selectVal.join(',')
}
this.checkValues = selectVal.join(',')
} else {
this.taskForm.values = {
"approval": selection
}
this.checkValues = selection;
}
}
},

2
ruoyi-ui/src/views/flowable/task/record/index.vue

@ -3,7 +3,7 @@
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span class="el-icon-document">基础信息</span>
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button>
<el-button style="float: right;" type="primary" @click="goBack">关闭</el-button>
</div>
<!--流程处理表单模块-->

178
ruoyi-ui/src/views/flowable/task/todo/detail/index.vue

@ -1,31 +1,32 @@
<template>
<div class="app-container">
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span class="el-icon-document">基础信息</span>
<el-button style="float: right;" type="primary" @click="goBack">返回</el-button>
</div>
<!--流程处理表单模块-->
<el-col :span="16" :offset="6">
<div>
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
<div style="margin-left:10%;margin-bottom: 20px;font-size: 14px;">
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleComplete">审批</el-button>
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">委派</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">签收</el-button>-->
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleReturn">退回</el-button>
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleReject">驳回</el-button>
</div>
</el-col>
</el-card>
<!--流程流转记录-->
<el-card class="box-card" v-if="flowRecordList">
<div slot="header" class="clearfix">
<span class="el-icon-notebook-1">审批记录</span>
</div>
<div slot="header" class="clearfix">
<span class="el-icon-document">待办任务</span>
<el-tag style="margin-left:10px">发起人:{{startUser}}</el-tag>
<el-tag>任务节点:{{taskName}}</el-tag>
<el-button style="float: right;" size="mini" type="primary" @click="goBack">关闭</el-button>
</div>
<el-tabs tab-position="top" @tab-click="handleClick">
<!--表单信息-->
<el-tab-pane label="表单信息">
<el-col :span="16" :offset="4">
<div class="test-form">
<parser :key="new Date().getTime()" :form-conf="variablesData" />
</div>
<div style="margin-left:15%;margin-bottom: 20px;font-size: 14px;">
<el-button icon="el-icon-edit-outline" type="success" size="mini" @click="handleComplete">审批</el-button>
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">委派</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>-->
<!-- <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate">签收</el-button>-->
<el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleReturn">退回</el-button>
<el-button icon="el-icon-circle-close" type="danger" size="mini" @click="handleReject">驳回</el-button>
</div>
</el-col>
</el-tab-pane>
<!--流程流转记录-->
<el-tab-pane label="流转记录">
<!--flowRecordList-->
<el-col :span="16" :offset="4" >
<div class="block">
<el-timeline>
@ -69,45 +70,41 @@
</el-timeline>
</div>
</el-col>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span class="el-icon-picture-outline">流程图</span>
</div>
</el-tab-pane>
<!--流程图-->
<el-tab-pane label="流程图">
<flow :xmlData="xmlData" :taskData="taskList"></flow>
</el-card>
<!--审批正常流程-->
<el-dialog :title="completeTitle" :visible.sync="completeOpen" width="60%" append-to-body>
<el-form ref="taskForm" :model="taskForm">
<el-form-item prop="targetKey">
<!-- <el-row :gutter="24">-->
</el-tab-pane>
</el-tabs>
<!-- <el-button style="position: absolute;right:35px;top:35px;" type="primary" @click="goBack">关闭</el-button>-->
<!--审批正常流程-->
<el-dialog :title="completeTitle" :visible.sync="completeOpen" width="60%" append-to-body>
<el-form ref="taskForm" :model="taskForm">
<el-form-item prop="targetKey">
<flow-user v-if="checkSendUser" :checkType="checkType" @handleUserSelect="handleUserSelect"></flow-user>
<flow-role v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"></flow-role>
<!-- </el-row>-->
</el-form-item>
<el-form-item label="处理意见" label-width="80px" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
<el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
</el-form-item>
<el-form-item label="处理意见" label-width="80px" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
<el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="completeOpen = false"> </el-button>
<el-button type="primary" @click="taskComplete"> </el-button>
</span>
</el-dialog>
<!--退回流程-->
<el-dialog :title="returnTitle" :visible.sync="returnOpen" width="40%" append-to-body>
</el-dialog>
<!--退回流程-->
<el-dialog :title="returnTitle" :visible.sync="returnOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="退回节点" prop="targetKey">
<el-radio-group v-model="taskForm.targetKey">
<el-radio-button
v-for="item in returnTaskList"
:key="item.id"
:label="item.id"
>{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="退回节点" prop="targetKey">
<el-radio-group v-model="taskForm.targetKey">
<el-radio-button
v-for="item in returnTaskList"
:key="item.id"
:label="item.id"
>{{item.name}}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="退回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
@ -116,20 +113,20 @@
<el-button @click="returnOpen = false"> </el-button>
<el-button type="primary" @click="taskReturn"> </el-button>
</span>
</el-dialog>
<!--驳回流程-->
<el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="驳回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
</el-dialog>
<!--驳回流程-->
<el-dialog :title="rejectTitle" :visible.sync="rejectOpen" width="40%" append-to-body>
<el-form ref="taskForm" :model="taskForm" label-width="80px" >
<el-form-item label="驳回意见" prop="comment" :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]">
<el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见"/>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="rejectOpen = false"> </el-button>
<el-button type="primary" @click="taskReject"> </el-button>
</span>
</el-dialog>
</el-dialog>
</el-card>
</div>
</template>
@ -140,7 +137,7 @@ import FlowRole from '@/components/flow/Role'
import Parser from '@/components/parser/Parser'
import {definitionStart, getProcessVariables, readXml, getFlowViewer} from "@/api/flowable/definition";
import {complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate} from "@/api/flowable/todo";
import flow from '@/views/flowable/task/record/flow'
import flow from '@/views/flowable/task/todo/detail/flow'
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {listUser} from "@/api/system/user";
@ -207,25 +204,34 @@ export default {
checkSendUser: false, //
checkSendRole: false,//
checkType: 'single', //
taskName: null, //
startUser: null, //
};
},
created() {
this.taskForm.deployId = this.$route.query && this.$route.query.deployId;
this.taskForm.taskId = this.$route.query && this.$route.query.taskId;
this.taskForm.procInsId = this.$route.query && this.$route.query.procInsId;
this.taskForm.executionId = this.$route.query && this.$route.query.executionId;
this.taskForm.instanceId = this.$route.query && this.$route.query.procInsId;
//
this.getFlowViewer(this.taskForm.procInsId,this.taskForm.executionId);
this.getModelDetail(this.taskForm.deployId);
//
if (this.taskForm.taskId){
this.processVariables(this.taskForm.taskId)
this.getNextFlowNode(this.taskForm.taskId)
if (this.$route.query) {
this.taskName = this.$route.query.taskName;
this.startUser = this.$route.query.startUser;
this.taskForm.deployId = this.$route.query.deployId;
this.taskForm.taskId = this.$route.query.taskId;
this.taskForm.procInsId = this.$route.query.procInsId;
this.taskForm.executionId = this.$route.query.executionId;
this.taskForm.instanceId = this.$route.query.procInsId;
//
this.getFlowViewer(this.taskForm.procInsId, this.taskForm.executionId);
this.getModelDetail(this.taskForm.deployId);
//
if (this.taskForm.taskId) {
this.processVariables(this.taskForm.taskId)
this.getNextFlowNode(this.taskForm.taskId)
}
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId);
}
this.getFlowRecordList(this.taskForm.procInsId, this.taskForm.deployId);
},
methods: {
handleClick(tab, event) {
console.log(tab, event);
},
/** 查询用户列表 */
getList() {
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
@ -272,23 +278,21 @@ export default {
},
//
handleUserSelect(selection) {
// console.log(selection,"handleUserSelect")
if (selection) {
const selectVal = selection.map(item => item.userId);
if (selectVal instanceof Array) {
if (selection instanceof Array) {
const selectVal = selection.map(item => item.userId);
this.taskForm.values = {
"approval": selectVal.join(',')
}
} else {
this.taskForm.values = {
"approval": selectVal
"approval": selection
}
}
}
},
//
handleRoleSelect(selection) {
// console.log(selection,"handleRoleSelect")
if (selection) {
if (selection instanceof Array) {
const selectVal = selection.map(item => item.roleId);

4
ruoyi-ui/src/views/flowable/task/todo/index.vue

@ -44,7 +44,7 @@
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName"/>
<el-table-column label="任务节点" align="center" prop="taskName"/>
<el-table-column label="当前节点" align="center" prop="taskName"/>
<el-table-column label="流程版本" align="center">
<template slot-scope="scope">
<el-tag size="medium" >v{{scope.row.procDefVersion}}</el-tag>
@ -148,6 +148,8 @@ export default {
executionId: row.executionId,
deployId: row.deployId,
taskId: row.taskId,
taskName: row.taskName,
startUser: row.startUserName + '-' + row.startDeptName,
}})
},
//

Loading…
Cancel
Save