办公管理
This commit is contained in:
10
src/api/flowable/finished.js
Normal file
10
src/api/flowable/finished.js
Normal file
@ -0,0 +1,10 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 撤回任务
|
||||
export function revokeProcess(data) {
|
||||
return request({
|
||||
url: '/workflow/task/revokeProcess',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
141
src/api/flowable/process.js
Normal file
141
src/api/flowable/process.js
Normal file
@ -0,0 +1,141 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询流程列表
|
||||
export function listProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询流程列表
|
||||
export function getProcessForm(query) {
|
||||
return request({
|
||||
url: '/workflow/process/getProcessForm',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 部署流程实例
|
||||
export function startProcess(processDefId, data) {
|
||||
return request({
|
||||
url: '/workflow/process/start/' + processDefId,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取流程图
|
||||
export function getBpmnXml(processDefId) {
|
||||
return request({
|
||||
url: '/workflow/process/bpmnXml/' + processDefId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function detailProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/detail',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 我的发起的流程
|
||||
export function listOwnProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/ownList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 我待办的流程
|
||||
export function listTodoProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/todoList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 我待签的流程
|
||||
export function listClaimProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/claimList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 我已办的流程
|
||||
export function listFinishedProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/finishedList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询流程抄送列表
|
||||
export function listCopyProcess(query) {
|
||||
return request({
|
||||
url: '/workflow/process/copyList',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 完成任务
|
||||
export function complete(data) {
|
||||
return request({
|
||||
url: '/workflow/task/complete',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 取消申请
|
||||
export function stopProcess(data) {
|
||||
return request({
|
||||
url: '/workflow/task/stopProcess',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 驳回任务
|
||||
export function rejectTask(data) {
|
||||
return request({
|
||||
url: '/workflow/task/reject',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 可退回任务列表
|
||||
export function returnList(data) {
|
||||
return request({
|
||||
url: '/workflow/task/returnList',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 部署流程实例
|
||||
export function deployStart(deployId) {
|
||||
return request({
|
||||
url: '/workflow/process/startFlow/' + deployId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 删除流程实例
|
||||
export function delProcess(id) {
|
||||
return request({
|
||||
url: '/workflow/instance/delete/?instanceId=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
81
src/api/flowable/todo.js
Normal file
81
src/api/flowable/todo.js
Normal file
@ -0,0 +1,81 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 完成任务
|
||||
export function complete(data) {
|
||||
return request({
|
||||
url: '/workflow/task/complete',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 委派任务
|
||||
export function delegate(data) {
|
||||
return request({
|
||||
url: '/workflow/task/delegate',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 转办任务
|
||||
export function transfer(data) {
|
||||
return request({
|
||||
url: '/workflow/task/transfer',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 退回任务
|
||||
export function returnTask(data) {
|
||||
return request({
|
||||
url: '/workflow/task/return',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 拒绝任务
|
||||
export function rejectTask(data) {
|
||||
return request({
|
||||
url: '/workflow/task/reject',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 签收任务
|
||||
export function claimTask(data) {
|
||||
return request({
|
||||
url: '/workflow/task/claim',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 可退回任务列表
|
||||
export function returnList(data) {
|
||||
return request({
|
||||
url: '/workflow/task/returnList',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 下一节点
|
||||
export function getNextFlowNode(data) {
|
||||
return request({
|
||||
url: '/workflow/task/nextFlowNode',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 部署流程实例
|
||||
export function deployStart(deployId) {
|
||||
return request({
|
||||
url: '/workflow/process/startFlow/' + deployId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
@ -1,135 +1,142 @@
|
||||
import request from '@/utils/request'
|
||||
import request from "@/utils/request";
|
||||
import { parseStrEmpty } from "@/utils/ruoyi";
|
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) {
|
||||
return request({
|
||||
url: '/system/user/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
url: "/system/user/list",
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户详细
|
||||
export function getUser(userId) {
|
||||
return request({
|
||||
url: '/system/user/' + parseStrEmpty(userId),
|
||||
method: 'get'
|
||||
})
|
||||
url: "/system/user/" + parseStrEmpty(userId),
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
// 查询用户列表,用于流程里的用户选择
|
||||
export function selectUser(query) {
|
||||
return request({
|
||||
url: "/system/user/selectUser",
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 新增用户
|
||||
export function addUser(data) {
|
||||
return request({
|
||||
url: '/system/user',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 修改用户
|
||||
export function updateUser(data) {
|
||||
return request({
|
||||
url: '/system/user',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user",
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
export function delUser(userId) {
|
||||
return request({
|
||||
url: '/system/user/' + userId,
|
||||
method: 'delete'
|
||||
})
|
||||
url: "/system/user/" + userId,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(userId, password) {
|
||||
const data = {
|
||||
userId,
|
||||
password
|
||||
}
|
||||
password,
|
||||
};
|
||||
return request({
|
||||
url: '/system/user/resetPwd',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user/resetPwd",
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, status) {
|
||||
const data = {
|
||||
userId,
|
||||
status
|
||||
}
|
||||
status,
|
||||
};
|
||||
return request({
|
||||
url: '/system/user/changeStatus',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user/changeStatus",
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询用户个人信息
|
||||
export function getUserProfile() {
|
||||
return request({
|
||||
url: '/system/user/profile',
|
||||
method: 'get'
|
||||
})
|
||||
url: "/system/user/profile",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 修改用户个人信息
|
||||
export function updateUserProfile(data) {
|
||||
return request({
|
||||
url: '/system/user/profile',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user/profile",
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
}
|
||||
newPassword,
|
||||
};
|
||||
return request({
|
||||
url: '/system/user/profile/updatePwd',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
url: "/system/user/profile/updatePwd",
|
||||
method: "put",
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
url: '/system/user/profile/avatar',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
url: "/system/user/profile/avatar",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询授权角色
|
||||
export function getAuthRole(userId) {
|
||||
return request({
|
||||
url: '/system/user/authRole/' + userId,
|
||||
method: 'get'
|
||||
})
|
||||
url: "/system/user/authRole/" + userId,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 保存授权角色
|
||||
export function updateAuthRole(data) {
|
||||
return request({
|
||||
url: '/system/user/authRole',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
url: "/system/user/authRole",
|
||||
method: "put",
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询部门下拉树结构
|
||||
export function deptTreeSelect() {
|
||||
return request({
|
||||
url: '/system/dept/treeselect',
|
||||
method: 'get'
|
||||
})
|
||||
url: "/system/dept/treeselect",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
@ -120,12 +120,11 @@
|
||||
width="100px"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="处理时间"
|
||||
prop="createTime"
|
||||
width="140px"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column label="处理时间" width="140px" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ parseTime(row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="办结时间"
|
||||
prop="finishTime"
|
||||
@ -187,6 +186,7 @@
|
||||
|
||||
<script setup name="">
|
||||
import "@/plugins/package/theme/index.scss";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
import BpmnViewer from "bpmn-js/lib/Viewer";
|
||||
import MoveCanvasModule from "diagram-js/lib/navigation/movecanvas";
|
||||
import { nextTick, onBeforeUnmount, toRefs } from "vue";
|
||||
|
@ -337,7 +337,6 @@ function resetListenersList() {
|
||||
bpmnElement.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type === `${prefix}:ExecutionListener`
|
||||
) ?? [];
|
||||
debugger;
|
||||
elementListenersList.value = bpmnElementListeners.map((listener) =>
|
||||
initListenerType(listener)
|
||||
);
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"msg": "操作成功",
|
||||
"code": 200,
|
||||
"data": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:flowable=\"http://flowable.org/bpmn\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:omgdc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:omgdi=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" typeLanguage=\"http://www.w3.org/2001/XMLSchema\" expressionLanguage=\"http://www.w3.org/1999/XPath\" targetNamespace=\"http://flowable.org/bpmn\" id=\"diagram_Process_1671673403370\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\">\n <process id=\"Process_1671673403370\" name=\"请假\" isExecutable=\"true\">\n <startEvent id=\"Event_0o5vpsf\" flowable:formKey=\"key_1\"></startEvent>\n <userTask id=\"Activity_1qoq75d\" flowable:candidateGroups=\"DEPT100,DEPT103,DEPT209\" xmlns:flowable=\"http://flowable.org/bpmn\" flowable:dataType=\"DEPTS\" flowable:text=\"若依科技,研发部门,高新分公司\">\n <extensionElements>\n <flowable:taskListener event=\"complete\" class=\"print('1233);\"></flowable:taskListener>\n <flowable:taskListener event=\"create\" expression=\"阿萨大大\"></flowable:taskListener>\n <flowable:taskListener event=\"delete\" delegateExpression=\"rr24344\"></flowable:taskListener>\n <flowable:taskListener event=\"update\" delegateExpression=\"tertert\"></flowable:taskListener>\n <flowable:taskListener event=\"delete\" delegateExpression=\"34er13232\"></flowable:taskListener>\n <flowable:taskListener event=\"update\" expression=\"4234\"></flowable:taskListener>\n </extensionElements>\n </userTask>\n <sequenceFlow id=\"Flow_01oskyz\" sourceRef=\"Event_0o5vpsf\" targetRef=\"Activity_1qoq75d\"></sequenceFlow>\n <userTask id=\"Activity_0iuhaqx\"></userTask>\n <sequenceFlow id=\"Flow_0f843wd\" sourceRef=\"Activity_1qoq75d\" targetRef=\"Activity_0iuhaqx\"></sequenceFlow>\n <intermediateThrowEvent id=\"Event_10fq4h9\"></intermediateThrowEvent>\n <sequenceFlow id=\"Flow_0ditwq0\" sourceRef=\"Activity_0iuhaqx\" targetRef=\"Event_10fq4h9\"></sequenceFlow>\n </process>\n <bpmndi:BPMNDiagram id=\"BPMNDiagram_Process_1671673403370\">\n <bpmndi:BPMNPlane bpmnElement=\"Process_1671673403370\" id=\"BPMNPlane_Process_1671673403370\">\n <bpmndi:BPMNShape bpmnElement=\"Event_0o5vpsf\" id=\"BPMNShape_Event_0o5vpsf\">\n <omgdc:Bounds height=\"36.0\" width=\"36.0\" x=\"292.0\" y=\"152.0\"></omgdc:Bounds>\n </bpmndi:BPMNShape>\n <bpmndi:BPMNShape bpmnElement=\"Activity_1qoq75d\" id=\"BPMNShape_Activity_1qoq75d\">\n <omgdc:Bounds height=\"80.0\" width=\"100.0\" x=\"380.0\" y=\"130.0\"></omgdc:Bounds>\n </bpmndi:BPMNShape>\n <bpmndi:BPMNShape bpmnElement=\"Activity_0iuhaqx\" id=\"BPMNShape_Activity_0iuhaqx\">\n <omgdc:Bounds height=\"80.0\" width=\"100.0\" x=\"540.0\" y=\"130.0\"></omgdc:Bounds>\n </bpmndi:BPMNShape>\n <bpmndi:BPMNShape bpmnElement=\"Event_10fq4h9\" id=\"BPMNShape_Event_10fq4h9\">\n <omgdc:Bounds height=\"36.0\" width=\"36.0\" x=\"702.0\" y=\"152.0\"></omgdc:Bounds>\n </bpmndi:BPMNShape>\n <bpmndi:BPMNEdge bpmnElement=\"Flow_0ditwq0\" id=\"BPMNEdge_Flow_0ditwq0\">\n <omgdi:waypoint x=\"640.0\" y=\"170.0\"></omgdi:waypoint>\n <omgdi:waypoint x=\"702.0\" y=\"170.0\"></omgdi:waypoint>\n </bpmndi:BPMNEdge>\n <bpmndi:BPMNEdge bpmnElement=\"Flow_0f843wd\" id=\"BPMNEdge_Flow_0f843wd\">\n <omgdi:waypoint x=\"480.0\" y=\"170.0\"></omgdi:waypoint>\n <omgdi:waypoint x=\"540.0\" y=\"170.0\"></omgdi:waypoint>\n </bpmndi:BPMNEdge>\n <bpmndi:BPMNEdge bpmnElement=\"Flow_01oskyz\" id=\"BPMNEdge_Flow_01oskyz\">\n <omgdi:waypoint x=\"328.0\" y=\"170.0\"></omgdi:waypoint>\n <omgdi:waypoint x=\"380.0\" y=\"170.0\"></omgdi:waypoint>\n </bpmndi:BPMNEdge>\n </bpmndi:BPMNPlane>\n </bpmndi:BPMNDiagram>\n</definitions>"
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
// 初始化表单数据
|
||||
export function initListenerForm(listener) {
|
||||
let self = {
|
||||
...listener
|
||||
...listener,
|
||||
};
|
||||
if (listener.script) {
|
||||
self = {
|
||||
...listener,
|
||||
...listener.script,
|
||||
scriptType: listener.script.resource ? "externalScript" : "inlineScript"
|
||||
scriptType: listener.script.resource ? "externalScript" : "inlineScript",
|
||||
};
|
||||
}
|
||||
if (listener.event === "timeout" && listener.eventDefinitions) {
|
||||
@ -28,15 +28,17 @@ export function initListenerForm(listener) {
|
||||
}
|
||||
|
||||
export function initListenerType(listener) {
|
||||
// debugger;
|
||||
let listenerType;
|
||||
if (listener.class) listenerType = "classListener";
|
||||
if (listener.expression) listenerType = "expressionListener";
|
||||
if (listener.delegateExpression) listenerType = "delegateExpressionListener";
|
||||
if (listener.script) listenerType = "scriptListener";
|
||||
|
||||
return {
|
||||
...JSON.parse(JSON.stringify(listener)),
|
||||
...(listener.script ?? {}),
|
||||
listenerType: listenerType
|
||||
listenerType: listenerType,
|
||||
};
|
||||
}
|
||||
|
||||
@ -44,7 +46,7 @@ export const listenerType = {
|
||||
classListener: "Java 类",
|
||||
expressionListener: "表达式",
|
||||
delegateExpressionListener: "代理表达式",
|
||||
scriptListener: "脚本"
|
||||
scriptListener: "脚本",
|
||||
};
|
||||
|
||||
export const eventType = {
|
||||
@ -53,10 +55,10 @@ export const eventType = {
|
||||
complete: "完成",
|
||||
delete: "删除",
|
||||
update: "更新",
|
||||
timeout: "超时"
|
||||
timeout: "超时",
|
||||
};
|
||||
|
||||
export const fieldType = {
|
||||
string: "字符串",
|
||||
expression: "表达式"
|
||||
expression: "表达式",
|
||||
};
|
||||
|
@ -21,7 +21,7 @@
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template slot-scope="{ row, $index }">
|
||||
<template #default="{ row, $index }">
|
||||
<el-button size="small" link @click="openAttributesForm(row, $index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
@ -29,7 +29,7 @@
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
type="danger"
|
||||
@click="removeAttributes(row, $index)"
|
||||
>移除</el-button
|
||||
>
|
||||
|
@ -2,8 +2,20 @@
|
||||
<div class="panel-tab__content">
|
||||
<div class="panel-tab__content--title">
|
||||
<span
|
||||
><i class="el-icon-menu" style="margin-right: 8px; color: #555555"></i
|
||||
>消息列表</span
|
||||
:style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<el-icon
|
||||
:style="{
|
||||
marginRight: '8px',
|
||||
color: '#555555',
|
||||
}"
|
||||
>
|
||||
<Menu />
|
||||
</el-icon>
|
||||
消息列表</span
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
@ -33,8 +45,20 @@
|
||||
style="padding-top: 8px; margin-top: 8px; border-top: 1px solid #eeeeee"
|
||||
>
|
||||
<span
|
||||
><i class="el-icon-menu" style="margin-right: 8px; color: #555555"></i
|
||||
>信号列表</span
|
||||
:style="{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}"
|
||||
>
|
||||
<el-icon
|
||||
:style="{
|
||||
marginRight: '8px',
|
||||
color: '#555555',
|
||||
}"
|
||||
>
|
||||
<Menu />
|
||||
</el-icon>
|
||||
信号列表</span
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
|
@ -65,12 +65,14 @@ export function createScriptObject(options, prefix) {
|
||||
|
||||
// 更新元素扩展属性
|
||||
export function updateElementExtensions(element, extensionList) {
|
||||
// debugger;
|
||||
const extensions = window.bpmnInstances.moddle.create(
|
||||
"bpmn:ExtensionElements",
|
||||
{
|
||||
values: extensionList,
|
||||
}
|
||||
);
|
||||
debugger;
|
||||
window.bpmnInstances.modeling.updateProperties(element, {
|
||||
extensionElements: extensions,
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createWebHistory, createRouter } from 'vue-router'
|
||||
import { createWebHistory, createRouter } from "vue-router";
|
||||
/* Layout */
|
||||
import Layout from '@/layout'
|
||||
import Layout from "@/layout";
|
||||
|
||||
/**
|
||||
* Note: 路由配置项
|
||||
@ -27,147 +27,167 @@ import Layout from '@/layout'
|
||||
// 公共路由
|
||||
export const constantRoutes = [
|
||||
{
|
||||
path: '/redirect',
|
||||
path: "/redirect",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
component: () => import('@/views/redirect/index.vue')
|
||||
}
|
||||
]
|
||||
path: "/redirect/:path(.*)",
|
||||
component: () => import("@/views/redirect/index.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/login'),
|
||||
hidden: true
|
||||
path: "/login",
|
||||
component: () => import("@/views/login"),
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true
|
||||
path: "/register",
|
||||
component: () => import("@/views/register"),
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: () => import('@/views/error/404'),
|
||||
hidden: true
|
||||
component: () => import("@/views/error/404"),
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: '/401',
|
||||
component: () => import('@/views/error/401'),
|
||||
hidden: true
|
||||
path: "/401",
|
||||
component: () => import("@/views/error/401"),
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
path: "",
|
||||
component: Layout,
|
||||
redirect: '/index',
|
||||
redirect: "/index",
|
||||
children: [
|
||||
{
|
||||
path: '/index',
|
||||
component: () => import('@/views/index'),
|
||||
name: 'Index',
|
||||
meta: { title: '首页', icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
path: "/index",
|
||||
component: () => import("@/views/index"),
|
||||
name: "Index",
|
||||
meta: { title: "首页", icon: "dashboard", affix: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
path: "/user",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
redirect: 'noredirect',
|
||||
redirect: "noredirect",
|
||||
children: [
|
||||
{
|
||||
path: 'profile',
|
||||
component: () => import('@/views/system/user/profile/index'),
|
||||
name: 'Profile',
|
||||
meta: { title: '个人中心', icon: 'user' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
path: "profile",
|
||||
component: () => import("@/views/system/user/profile/index"),
|
||||
name: "Profile",
|
||||
meta: { title: "个人中心", icon: "user" },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
export const dynamicRoutes = [
|
||||
{
|
||||
path: '/system/user-auth',
|
||||
path: "/system/user-auth",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:user:edit'],
|
||||
permissions: ["system:user:edit"],
|
||||
children: [
|
||||
{
|
||||
path: 'role/:userId(\\d+)',
|
||||
component: () => import('@/views/system/user/authRole'),
|
||||
name: 'AuthRole',
|
||||
meta: { title: '分配角色', activeMenu: '/system/user' }
|
||||
}
|
||||
]
|
||||
path: "role/:userId(\\d+)",
|
||||
component: () => import("@/views/system/user/authRole"),
|
||||
name: "AuthRole",
|
||||
meta: { title: "分配角色", activeMenu: "/system/user" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/system/role-auth',
|
||||
path: "/system/role-auth",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:role:edit'],
|
||||
permissions: ["system:role:edit"],
|
||||
children: [
|
||||
{
|
||||
path: 'user/:roleId(\\d+)',
|
||||
component: () => import('@/views/system/role/authUser'),
|
||||
name: 'AuthUser',
|
||||
meta: { title: '分配用户', activeMenu: '/system/role' }
|
||||
}
|
||||
]
|
||||
path: "user/:roleId(\\d+)",
|
||||
component: () => import("@/views/system/role/authUser"),
|
||||
name: "AuthUser",
|
||||
meta: { title: "分配用户", activeMenu: "/system/role" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/system/dict-data',
|
||||
path: "/system/dict-data",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['system:dict:list'],
|
||||
permissions: ["system:dict:list"],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:dictId(\\d+)',
|
||||
component: () => import('@/views/system/dict/data'),
|
||||
name: 'Data',
|
||||
meta: { title: '字典数据', activeMenu: '/system/dict' }
|
||||
}
|
||||
]
|
||||
path: "index/:dictId(\\d+)",
|
||||
component: () => import("@/views/system/dict/data"),
|
||||
name: "Data",
|
||||
meta: { title: "字典数据", activeMenu: "/system/dict" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/monitor/job-log',
|
||||
path: "/monitor/job-log",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['monitor:job:list'],
|
||||
permissions: ["monitor:job:list"],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:jobId(\\d+)',
|
||||
component: () => import('@/views/monitor/job/log'),
|
||||
name: 'JobLog',
|
||||
meta: { title: '调度日志', activeMenu: '/monitor/job' }
|
||||
}
|
||||
]
|
||||
path: "index/:jobId(\\d+)",
|
||||
component: () => import("@/views/monitor/job/log"),
|
||||
name: "JobLog",
|
||||
meta: { title: "调度日志", activeMenu: "/monitor/job" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/tool/gen-edit',
|
||||
path: "/tool/gen-edit",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['tool:gen:edit'],
|
||||
permissions: ["tool:gen:edit"],
|
||||
children: [
|
||||
{
|
||||
path: 'index/:tableId(\\d+)',
|
||||
component: () => import('@/views/tool/gen/editTable'),
|
||||
name: 'GenEdit',
|
||||
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
path: "index/:tableId(\\d+)",
|
||||
component: () => import("@/views/tool/gen/editTable"),
|
||||
name: "GenEdit",
|
||||
meta: { title: "修改生成配置", activeMenu: "/tool/gen" },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/flowable/process",
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ["flowable:process:query"],
|
||||
children: [
|
||||
{
|
||||
path: "start/:deployId([\\w|\\-]+)",
|
||||
component: () => import("@/views/office/start"),
|
||||
name: "WorkStart",
|
||||
meta: { title: "发起流程", icon: "" },
|
||||
},
|
||||
{
|
||||
path: "detail/:procInsId([\\w|\\-]+)",
|
||||
component: () => import("@/views/office/detail"),
|
||||
name: "WorkDetail",
|
||||
meta: { title: "流程详情", activeMenu: "/office/own" },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: constantRoutes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
return savedPosition;
|
||||
} else {
|
||||
return { top: 0 }
|
||||
return { top: 0 };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
184
src/views/office/claim.vue
Normal file
184
src/views/office/claim.vue
Normal file
@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input
|
||||
v-model="queryParams.processName"
|
||||
placeholder="请输入流程名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="claimList">
|
||||
<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">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="medium">v{{ row.procDefVersion }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程发起人" align="center">
|
||||
<template #default="{ row }">
|
||||
<label
|
||||
>{{ row.startUserName }}
|
||||
<el-tag type="info" size="small">{{
|
||||
row.startDeptName
|
||||
}}</el-tag></label
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="接收时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
icon="s-claim"
|
||||
@click="handleClaim(row)"
|
||||
v-hasPermi="['flowable:process:claim']"
|
||||
>签收
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="Claim">
|
||||
import { listClaimProcess } from "@/api/flowable/process";
|
||||
import { claimTask } from "@/api/flowable/todo";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ref, reactive, toRefs } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const queryFormRef = ref();
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
// 选中数组
|
||||
const ids = ref([]);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
// 流程待办任务表格数据
|
||||
const claimList = ref([]);
|
||||
// 弹出层标题
|
||||
const title = ref("");
|
||||
// 是否显示弹出层
|
||||
const open = ref(false);
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
processName: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {},
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询流程定义列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listClaimProcess(queryParams.value).then((response) => {
|
||||
claimList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
/** 签收 */
|
||||
const router = useRouter();
|
||||
function handleClaim(row) {
|
||||
claimTask({ taskId: row.taskId }).then((response) => {
|
||||
ElMessage.success(response.msg);
|
||||
router.push({
|
||||
path: "/work/todo",
|
||||
});
|
||||
});
|
||||
}
|
||||
defineExpose({
|
||||
getList,
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
export default {
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next((vm) => {
|
||||
vm.getList();
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
221
src/views/office/copy.vue
Normal file
221
src/views/office/copy.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
size="small"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input
|
||||
v-model="queryParams.processName"
|
||||
placeholder="请输入流程名称"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="发起人" prop="originatorName">
|
||||
<el-input
|
||||
v-model="queryParams.originatorName"
|
||||
placeholder="请输入发起人"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="download"
|
||||
size="small"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['workflow:process:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
:showSearch.sync="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="copyList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="抄送编号" align="center" prop="copyId" />
|
||||
<el-table-column
|
||||
label="标题"
|
||||
align="center"
|
||||
prop="title"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="流程名称"
|
||||
align="center"
|
||||
prop="processName"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="发起人" align="center" prop="originatorName" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime">
|
||||
<template #default="{ row }">
|
||||
<span>{{ parseTime(row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
icon="tickets"
|
||||
@click="handleFlowRecord(row)"
|
||||
v-hasPermi="['flowable:process:query']"
|
||||
>详情</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { listCopyProcess } from "@/api/flowable/process";
|
||||
import { reactive, ref, toRefs } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const queryFormRef = ref();
|
||||
// 按钮loading
|
||||
// const buttonLoading = ref(false);
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
// 选中数组
|
||||
const ids = ref([]);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
// 流程抄送表格数据
|
||||
const copyList = ref([]);
|
||||
// 弹出层标题
|
||||
// const title = ref("");
|
||||
// 是否显示弹出层
|
||||
const open = ref(false);
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processId: undefined,
|
||||
processName: undefined,
|
||||
categoryId: undefined,
|
||||
taskId: undefined,
|
||||
userId: undefined,
|
||||
originatorName: undefined,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
copyId: [{ required: true, message: "抄送主键不能为空", trigger: "blur" }],
|
||||
processId: [
|
||||
{ required: true, message: "流程主键不能为空", trigger: "blur" },
|
||||
],
|
||||
processName: [
|
||||
{ required: true, message: "流程名称不能为空", trigger: "blur" },
|
||||
],
|
||||
categoryId: [
|
||||
{ required: true, message: "流程分类主键不能为空", trigger: "blur" },
|
||||
],
|
||||
taskId: [{ required: true, message: "任务主键不能为空", trigger: "blur" }],
|
||||
userId: [{ required: true, message: "用户主键不能为空", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
/** 查询流程抄送列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listCopyProcess(queryParams.value).then((response) => {
|
||||
copyList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.copyId);
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 查看详情 */
|
||||
function handleFlowRecord(row) {
|
||||
router.push({
|
||||
path: "/flowable/process/detail/" + row.instanceId,
|
||||
query: {
|
||||
definitionId: row.processId,
|
||||
deployId: row.deploymentId,
|
||||
taskId: row.taskId,
|
||||
finished: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
this.download(
|
||||
"workflow/copy/export",
|
||||
{
|
||||
...queryParams.value,
|
||||
},
|
||||
`copy_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
831
src/views/office/detail.vue
Normal file
831
src/views/office/detail.vue
Normal file
@ -0,0 +1,831 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs
|
||||
tab-position="top"
|
||||
:model-value="finished === 'true' ? 'approval' : 'form'"
|
||||
>
|
||||
<el-tab-pane label="任务办理" name="approval" v-if="finished === 'true'">
|
||||
<el-card class="box-card" shadow="hover" v-if="taskFormOpen">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>填写表单</span>
|
||||
</div>
|
||||
<el-col :span="20" :offset="2">
|
||||
<parser :form-conf="taskFormData" ref="taskFormParser" />
|
||||
</el-col>
|
||||
</el-card>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>审批流程</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-form
|
||||
ref="taskFormRef"
|
||||
:model="taskForm"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="审批意见" prop="comment">
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
v-model="taskForm.comment"
|
||||
placeholder="请输入 审批意见"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送人" prop="copyUserIds">
|
||||
<el-tag
|
||||
:key="index"
|
||||
v-for="(item, index) in copyUser"
|
||||
closable
|
||||
:disable-transitions="false"
|
||||
@close="handleClose('copy', item)"
|
||||
>
|
||||
{{ item.nickName }}
|
||||
</el-tag>
|
||||
<el-button
|
||||
class="button-new-tag"
|
||||
type="primary"
|
||||
icon="plus"
|
||||
size="small"
|
||||
circle
|
||||
@click="onSelectCopyUsers"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="指定审批人" prop="copyUserIds">
|
||||
<el-tag
|
||||
:key="index"
|
||||
v-for="(item, index) in nextUser"
|
||||
closable
|
||||
:disable-transitions="false"
|
||||
@close="handleClose('next', item)"
|
||||
>
|
||||
{{ item.nickName }}
|
||||
</el-tag>
|
||||
<el-button
|
||||
class="button-new-tag"
|
||||
type="primary"
|
||||
icon="plus"
|
||||
size="small"
|
||||
circle
|
||||
@click="onSelectNextUsers"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" type="flex" justify="center">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
icon="circle-check"
|
||||
type="success"
|
||||
@click="handleComplete"
|
||||
>通过</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
icon="chat-line-square"
|
||||
type="primary"
|
||||
@click="handleDelegate"
|
||||
>委派</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="pointer" type="success" @click="handleTransfer"
|
||||
>转办</el-button
|
||||
>
|
||||
</el-col>
|
||||
<!-- <el-col :span="2">-->
|
||||
<!-- <el-button icon="edit-outline" type="primary"" @click="handle">签收</el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
icon="refresh-left"
|
||||
type="warning"
|
||||
@click="handleReturn"
|
||||
>退回</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="circle-close" type="danger" @click="handleReject"
|
||||
>拒绝</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="表单信息" name="form">
|
||||
<div v-if="formOpen">
|
||||
<el-card
|
||||
class="box-card"
|
||||
shadow="never"
|
||||
v-for="(formInfo, index) in processFormList"
|
||||
:key="index"
|
||||
>
|
||||
<div slot="header" class="clearfix">
|
||||
<span>{{ formInfo.title }}</span>
|
||||
</div>
|
||||
<!--流程处理表单模块-->
|
||||
<el-col :span="20" :offset="2">
|
||||
<parser :form-conf="formInfo" />
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="流转记录" name="record">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<el-col :span="20" :offset="2">
|
||||
<div class="block">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(item, index) in historyProcNodeList"
|
||||
:key="index"
|
||||
:icon="setIcon(item.endTime)"
|
||||
:color="setColor(item.endTime)"
|
||||
>
|
||||
<p style="font-weight: 700">{{ item.activityName }}</p>
|
||||
<el-card
|
||||
v-if="item.activityType === 'startEvent'"
|
||||
class="box-card"
|
||||
shadow="hover"
|
||||
>
|
||||
{{ item.assigneeName }} 在
|
||||
{{ parseTime(item.createTime) }} 发起流程
|
||||
</el-card>
|
||||
<el-card
|
||||
v-if="item.activityType === 'userTask'"
|
||||
class="box-card"
|
||||
shadow="hover"
|
||||
>
|
||||
<el-descriptions
|
||||
:column="5"
|
||||
:labelStyle="{ 'font-weight': 'bold' }"
|
||||
>
|
||||
<el-descriptions-item label="实际办理">{{
|
||||
item.assigneeName || "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="候选办理">{{
|
||||
item.candidate || "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收时间">{{
|
||||
parseTime(item.createTime) || "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="办结时间">{{
|
||||
parseTime(item.endTime) || "-"
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="耗时">{{
|
||||
item.duration || "-"
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div v-if="item.commentList && item.commentList.length > 0">
|
||||
<div
|
||||
v-for="(comment, index) in item.commentList"
|
||||
:key="index"
|
||||
>
|
||||
<el-divider content-position="left">
|
||||
<el-tag
|
||||
:type="approveTypeTag(comment.type)"
|
||||
size="small"
|
||||
>{{ commentType(comment.type) }}</el-tag
|
||||
>
|
||||
<el-tag type="info" effect="plain" size="small">{{
|
||||
parseTime(comment.time)
|
||||
}}</el-tag>
|
||||
</el-divider>
|
||||
<span>{{ comment.fullMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card
|
||||
v-if="item.activityType === 'endEvent'"
|
||||
class="box-card"
|
||||
shadow="hover"
|
||||
>
|
||||
{{ parseTime(item.createTime) }} 结束流程
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="流程跟踪" name="track">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<process-viewer
|
||||
:key="`designer-${loadIndex}`"
|
||||
:style="'height:' + height"
|
||||
:xml="xmlData"
|
||||
:finishedInfo="finishedInfo"
|
||||
:allCommentList="historyProcNodeList"
|
||||
/>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!--退回流程-->
|
||||
<el-dialog
|
||||
:title="returnTitle"
|
||||
v-model="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>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="returnOpen = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitReturn">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:title="userData.title"
|
||||
v-model="userData.open"
|
||||
width="60%"
|
||||
append-to-body
|
||||
>
|
||||
<el-row type="flex" :gutter="20">
|
||||
<!--部门数据-->
|
||||
<el-col :span="5">
|
||||
<el-card shadow="never" style="height: 100%">
|
||||
<div slot="header">
|
||||
<span>部门列表</span>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-input
|
||||
v-model="deptName"
|
||||
placeholder="请输入部门名称"
|
||||
clearable
|
||||
size="small"
|
||||
prefix-icon="el-icon-search"
|
||||
/>
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="deptProps"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="tree"
|
||||
default-expand-all
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-table
|
||||
ref="userTableRef"
|
||||
:key="userData.type"
|
||||
height="500"
|
||||
v-loading="userLoading"
|
||||
:data="userList"
|
||||
highlight-current-row
|
||||
@current-change="changeCurrentUser"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="userData.type === 'copy' || userData.type === 'next'"
|
||||
width="55"
|
||||
type="selection"
|
||||
/>
|
||||
<el-table-column v-else width="30">
|
||||
<template slot-scope="scope">
|
||||
<el-radio :label="scope.row.userId" v-model="currentUserId">{{
|
||||
""
|
||||
}}</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户名" align="center" prop="nickName" />
|
||||
<el-table-column label="手机" align="center" prop="phonenumber" />
|
||||
<el-table-column label="部门" align="center" prop="dept.deptName" />
|
||||
</el-table>
|
||||
<pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="userData.open = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitUserData">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { detailProcess } from "@/api/flowable/process";
|
||||
import Parser from "@/utils/generator/parser";
|
||||
import {
|
||||
complete,
|
||||
delegate,
|
||||
transfer,
|
||||
rejectTask,
|
||||
returnList,
|
||||
returnTask,
|
||||
} from "@/api/flowable/todo";
|
||||
import tab from "@/plugins/tab";
|
||||
import { selectUser, deptTreeSelect, listUser } from "@/api/system/user";
|
||||
import ProcessViewer from "@/components/ProcessViewer";
|
||||
import { computed, nextTick, reactive, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { addDateRange } from "@/utils/ruoyi";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
// import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
// import Treeselect from "@riophae/vue-treeselect";
|
||||
const router = useRouter();
|
||||
const taskFormRef = ref();
|
||||
const userTableRef = ref();
|
||||
const height = ref(document.documentElement.clientHeight - 205 + "px;");
|
||||
// 模型xml数据
|
||||
const loadIndex = ref(0);
|
||||
const xmlData = ref(undefined);
|
||||
|
||||
const historyProcNodeList = ref([]);
|
||||
// 部门名称
|
||||
const deptName = ref(undefined);
|
||||
// 部门树选项
|
||||
const deptOptions = ref(undefined);
|
||||
const userLoading = ref(false);
|
||||
// 用户表格数据
|
||||
const userList = ref(null);
|
||||
|
||||
const total = ref(0);
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
|
||||
const currentUserId = ref(null);
|
||||
const variables = ref([]); // 流程变量数
|
||||
const taskFormOpen = ref(false);
|
||||
const processFormList = ref([]); // 流程变量数
|
||||
const formOpen = ref(false); // 是否加载流程变量数
|
||||
const returnTaskList = ref([]); // 回退列表数
|
||||
const finished = ref("false");
|
||||
const returnTitle = ref(null);
|
||||
const returnOpen = ref(false);
|
||||
const rejectOpen = ref(false);
|
||||
const rejectTitle = ref(null);
|
||||
const copyUser = ref([]);
|
||||
const nextUser = ref([]);
|
||||
const userMultipleSelection = ref([]);
|
||||
const userDialogTitle = ref("");
|
||||
const userOpen = ref(false);
|
||||
|
||||
const commentType = computed(() => {
|
||||
return (val) => {
|
||||
switch (val) {
|
||||
case "1":
|
||||
return "通过";
|
||||
case "2":
|
||||
return "退回";
|
||||
case "3":
|
||||
return "驳回";
|
||||
case "4":
|
||||
return "委派";
|
||||
case "5":
|
||||
return "转办";
|
||||
}
|
||||
};
|
||||
});
|
||||
const approveTypeTag = computed(() => {
|
||||
return (val) => {
|
||||
switch (val) {
|
||||
case "1":
|
||||
return "success";
|
||||
case "2":
|
||||
return "warning";
|
||||
case "3":
|
||||
return "danger";
|
||||
case "4":
|
||||
return "primary";
|
||||
case "5":
|
||||
return "success";
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const data = reactive({
|
||||
deptProps: {
|
||||
children: "children",
|
||||
label: "label",
|
||||
},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
deptId: undefined,
|
||||
},
|
||||
taskForm: {
|
||||
comment: "", // 意见内容
|
||||
procInsId: "", // 流程实例编号
|
||||
deployId: "", // 流程定义编号
|
||||
taskId: "", // 流程任务编号
|
||||
definitionId: "", // 流程编号
|
||||
copyUserIds: "", // 抄送人Id
|
||||
vars: "",
|
||||
targetKey: "",
|
||||
},
|
||||
taskFormData: {}, // 流程变量数据
|
||||
finishedInfo: {
|
||||
finishedSequenceFlowSet: [],
|
||||
finishedTaskSet: [],
|
||||
unfinishedTaskSet: [],
|
||||
rejectedTaskSet: [],
|
||||
},
|
||||
userData: {
|
||||
title: "",
|
||||
type: "",
|
||||
open: false,
|
||||
},
|
||||
rules: {
|
||||
comment: [{ required: true, message: "请输入审批意见", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
const {
|
||||
deptProps,
|
||||
queryParams,
|
||||
taskForm,
|
||||
taskFormData,
|
||||
finishedInfo,
|
||||
userData,
|
||||
rules,
|
||||
} = toRefs(data);
|
||||
const route = useRoute();
|
||||
function initData() {
|
||||
taskForm.value.procInsId = route.params && route.params.procInsId;
|
||||
taskForm.value.deployId = route.query && route.query.deployId;
|
||||
taskForm.value.definitionId = route.query && route.query.definitionId;
|
||||
taskForm.value.taskId = route.query && route.query.taskId;
|
||||
finished.value = route.query && route.query.finished;
|
||||
// 流程任务重获取变量表单
|
||||
if (taskForm.value.taskId) {
|
||||
getProcessDetails(
|
||||
taskForm.value.procInsId,
|
||||
taskForm.value.deployId,
|
||||
taskForm.value.taskId
|
||||
);
|
||||
}
|
||||
loadIndex.value = taskForm.value.procInsId;
|
||||
}
|
||||
/** 查询部门下拉树结构 */
|
||||
function getTreeSelect() {
|
||||
deptTreeSelect().then((response) => {
|
||||
deptOptions.value = response.data;
|
||||
});
|
||||
}
|
||||
let dateRange;
|
||||
/** 查询用户列表 */
|
||||
function getList() {
|
||||
userLoading.value = true;
|
||||
// debugger;
|
||||
listUser(addDateRange(queryParams.value, dateRange)).then((response) => {
|
||||
userList.value = response.rows;
|
||||
total.value = response.total;
|
||||
toggleSelection(userMultipleSelection.value);
|
||||
userLoading.value = false;
|
||||
});
|
||||
}
|
||||
// 筛选节点
|
||||
function filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
}
|
||||
// 节点单击事件
|
||||
function handleNodeClick(data) {
|
||||
queryParams.value.deptId = data.id;
|
||||
getList();
|
||||
}
|
||||
function setIcon(val) {
|
||||
if (val) {
|
||||
return "el-icon-check";
|
||||
} else {
|
||||
return "el-icon-time";
|
||||
}
|
||||
}
|
||||
function setColor(val) {
|
||||
if (val) {
|
||||
return "#2bc418";
|
||||
} else {
|
||||
return "#b3bdbb";
|
||||
}
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
userMultipleSelection.value = selection;
|
||||
}
|
||||
function toggleSelection(selection) {
|
||||
if (selection && selection.length > 0) {
|
||||
nextTick(() => {
|
||||
selection.forEach((item) => {
|
||||
let row = userList.value.find((k) => k.userId === item.userId);
|
||||
userTableRef.value.toggleRowSelection(row);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
nextTick(() => {
|
||||
userTableRef.value.clearSelection();
|
||||
});
|
||||
}
|
||||
}
|
||||
// 关闭标签
|
||||
function handleClose(type, tag) {
|
||||
let userObj = userMultipleSelection.value.find(
|
||||
(item) => item.userId === tag.id
|
||||
);
|
||||
userMultipleSelection.value.splice(
|
||||
userMultipleSelection.value.indexOf(userObj),
|
||||
1
|
||||
);
|
||||
if (type === "copy") {
|
||||
copyUser.value = userMultipleSelection.value;
|
||||
// 设置抄送人ID
|
||||
if (copyUser.value && copyUser.value.length > 0) {
|
||||
const val = copyUser.value.map((item) => item.id);
|
||||
taskForm.value.copyUserIds = val instanceof Array ? val.join(",") : val;
|
||||
} else {
|
||||
taskForm.value.copyUserIds = "";
|
||||
}
|
||||
} else if (type === "next") {
|
||||
nextUser.value = userMultipleSelection.value;
|
||||
// 设置抄送人ID
|
||||
if (nextUser.value && nextUser.value.length > 0) {
|
||||
const val = nextUser.value.map((item) => item.id);
|
||||
taskForm.value.nextUserIds = val instanceof Array ? val.join(",") : val;
|
||||
} else {
|
||||
taskForm.value.nextUserIds = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 流程变量赋值 */
|
||||
function handleCheckChange(val) {
|
||||
if (val instanceof Array) {
|
||||
taskForm.value.values = {
|
||||
approval: val.join(","),
|
||||
};
|
||||
} else {
|
||||
taskForm.value.values = {
|
||||
approval: val,
|
||||
};
|
||||
}
|
||||
}
|
||||
function getProcessDetails(procInsId, deployId, taskId) {
|
||||
const params = {
|
||||
procInsId: procInsId,
|
||||
deployId: deployId,
|
||||
taskId: taskId,
|
||||
};
|
||||
detailProcess(params).then((res) => {
|
||||
// const data = res.data;
|
||||
const data = JSON.parse(res.msg);
|
||||
// debugger;
|
||||
xmlData.value = data.bpmnXml;
|
||||
processFormList.value = data.processFormList;
|
||||
taskFormOpen.value = data.existTaskForm;
|
||||
if (taskFormOpen.value) {
|
||||
taskFormData.value = data.taskFormData;
|
||||
}
|
||||
historyProcNodeList.value = data.historyProcNodeList;
|
||||
finishedInfo.value = data.flowViewer;
|
||||
formOpen.value = true;
|
||||
});
|
||||
}
|
||||
function onSelectCopyUsers() {
|
||||
userMultipleSelection.value = copyUser.value;
|
||||
onSelectUsers("添加抄送人", "copy");
|
||||
}
|
||||
function onSelectNextUsers() {
|
||||
userMultipleSelection.value = nextUser.value;
|
||||
onSelectUsers("指定审批人", "next");
|
||||
}
|
||||
function onSelectUsers(title, type) {
|
||||
userData.value.title = title;
|
||||
userData.value.type = type;
|
||||
getTreeSelect();
|
||||
getList();
|
||||
userData.value.open = true;
|
||||
}
|
||||
/** 通过任务 */
|
||||
const taskFormParser = ref();
|
||||
function handleComplete() {
|
||||
// 校验表单
|
||||
// console.log(taskFormParser.value);
|
||||
// debugger;
|
||||
// const taskFormRef = taskFormParser.value;
|
||||
const isExistTaskForm = taskFormParser.value !== undefined;
|
||||
// 若无任务表单,则 taskFormPromise 为 true,即不需要校验
|
||||
const taskFormPromise = !isExistTaskForm
|
||||
? true
|
||||
: new Promise((resolve, reject) => {
|
||||
taskFormParser.value[
|
||||
taskFormParser.value.formConfCopy.formRef
|
||||
].validate((valid) => {
|
||||
valid ? resolve() : reject();
|
||||
});
|
||||
});
|
||||
const approvalPromise = new Promise((resolve, reject) => {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
valid ? resolve() : reject();
|
||||
});
|
||||
});
|
||||
Promise.all([taskFormPromise, approvalPromise]).then(() => {
|
||||
if (isExistTaskForm) {
|
||||
taskForm.value.variables =
|
||||
taskFormParser.value[taskFormParser.value.formConfCopy.formModel];
|
||||
}
|
||||
complete(taskForm.value).then((response) => {
|
||||
ElMessage.success(response.msg);
|
||||
goBack();
|
||||
});
|
||||
});
|
||||
}
|
||||
/** 委派任务 */
|
||||
function handleDelegate() {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
userData.value.type = "delegate";
|
||||
userData.value.title = "委派任务";
|
||||
userData.value.open = true;
|
||||
getTreeSelect();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 转办任务 */
|
||||
function handleTransfer() {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
userData.value.type = "transfer";
|
||||
userData.value.title = "转办任务";
|
||||
userData.value.open = true;
|
||||
getTreeSelect();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 拒绝任务 */
|
||||
function handleReject() {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
// const _this = this;
|
||||
ElMessageBox.confirm("拒绝审批单流程会终止,是否继续?")
|
||||
.then(function () {
|
||||
return rejectTask(taskForm.value);
|
||||
})
|
||||
.then((res) => {
|
||||
ElMessage.success(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function changeCurrentUser(val) {
|
||||
currentUserId.value = val.userId;
|
||||
}
|
||||
/** 返回页面 */
|
||||
function goBack() {
|
||||
// 关闭当前标签页并返回上个页面
|
||||
tab.closePage(route);
|
||||
router.back();
|
||||
}
|
||||
/** 接收子组件传的值 */
|
||||
function getData(data) {
|
||||
if (data) {
|
||||
const variables = [];
|
||||
data.fields.forEach((item) => {
|
||||
let variableData = {};
|
||||
variableData.label = item.__config__.label;
|
||||
// 表单值为多个选项时
|
||||
if (item.__config__.defaultValue instanceof Array) {
|
||||
const array = [];
|
||||
item.__config__.defaultValue.forEach((val) => {
|
||||
array.push(val);
|
||||
});
|
||||
variableData.val = array;
|
||||
} else {
|
||||
variableData.val = item.__config__.defaultValue;
|
||||
}
|
||||
variables.push(variableData);
|
||||
});
|
||||
variables.value = variables;
|
||||
}
|
||||
}
|
||||
function submitUserData() {
|
||||
let type = userData.value.type;
|
||||
if (type === "copy" || type === "next") {
|
||||
if (
|
||||
!userMultipleSelection.value ||
|
||||
userMultipleSelection.value.length <= 0
|
||||
) {
|
||||
ElMessage.error("请选择用户");
|
||||
return false;
|
||||
}
|
||||
let userIds = userMultipleSelection.value.map((k) => k.userId);
|
||||
if (type === "copy") {
|
||||
// 设置抄送人ID信息
|
||||
copyUser.value = userMultipleSelection.value;
|
||||
taskForm.value.copyUserIds =
|
||||
userIds instanceof Array ? userIds.join(",") : userIds;
|
||||
} else if (type === "next") {
|
||||
// 设置下一级审批人ID信息
|
||||
nextUser.value = userMultipleSelection.value;
|
||||
taskForm.value.nextUserIds =
|
||||
userIds instanceof Array ? userIds.join(",") : userIds;
|
||||
}
|
||||
userData.value.open = false;
|
||||
} else {
|
||||
if (!taskForm.value.comment) {
|
||||
ElMessage.error("请输入审批意见");
|
||||
return false;
|
||||
}
|
||||
if (!currentUserId.value) {
|
||||
ElMessage.error("请选择用户");
|
||||
return false;
|
||||
}
|
||||
taskForm.value.userId = currentUserId.value;
|
||||
if (type === "delegate") {
|
||||
delegate(taskForm.value).then((res) => {
|
||||
ElMessage.success(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
if (type === "transfer") {
|
||||
transfer(taskForm.value).then((res) => {
|
||||
ElMessage.success(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 可退回任务列表 */
|
||||
function handleReturn() {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
returnTitle.value = "退回流程";
|
||||
returnList(taskForm.value).then((res) => {
|
||||
returnTaskList.value = res.data;
|
||||
taskForm.value.values = null;
|
||||
returnOpen.value = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 提交退回任务 */
|
||||
function submitReturn() {
|
||||
taskFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
if (!taskForm.value.targetKey) {
|
||||
ElMessage.error("请选择退回节点!");
|
||||
}
|
||||
returnTask(taskForm.value).then((res) => {
|
||||
ElMessage.success(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
initData();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-tag + .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.el-col {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.button-new-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
275
src/views/office/finished.vue
Normal file
275
src/views/office/finished.vue
Normal file
@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="deployTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
size="small"
|
||||
v-model="queryParams.deployTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="delete"
|
||||
size="small"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['workflow:process:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
:showSearch.sync="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="finishedList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<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"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="任务节点" align="center" prop="taskName" />
|
||||
<el-table-column label="流程发起人" align="center">
|
||||
<template #default="{ row }">
|
||||
<label
|
||||
>{{ row.startUserName }}
|
||||
<el-tag type="info" size="small">{{
|
||||
row.startDeptName
|
||||
}}</el-tag></label
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="接收时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="审批时间"
|
||||
align="center"
|
||||
prop="finishTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="耗时"
|
||||
align="center"
|
||||
prop="duration"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
icon="tickets"
|
||||
@click="handleFlowRecord(row)"
|
||||
v-hasPermi="['flowable:process:query']"
|
||||
>流转记录</el-button
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
icon="tickets"
|
||||
@click="handleRevoke(row)"
|
||||
v-hasPermi="['flowable:process:revoke']"
|
||||
>撤回
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="Finished">
|
||||
import { listFinishedProcess } from "@/api/flowable/process";
|
||||
import { revokeProcess } from "@/api/flowable/finished";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref, reactive, toRefs } from "vue";
|
||||
const queryFormRef = ref();
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
// 选中数组
|
||||
const ids = ref([]);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
// 已办任务列表数据
|
||||
const finishedList = ref([]);
|
||||
// 弹出层标题
|
||||
const title = ref("");
|
||||
// 是否显示弹出层
|
||||
const open = ref(false);
|
||||
const src = ref("");
|
||||
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
category: null,
|
||||
key: null,
|
||||
tenantId: null,
|
||||
deployTime: null,
|
||||
derivedFrom: null,
|
||||
derivedFromRoot: null,
|
||||
parentDeploymentId: null,
|
||||
engineVersion: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {},
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询流程定义列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listFinishedProcess(queryParams.value).then((response) => {
|
||||
finishedList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 流程流转记录 */
|
||||
const router = useRouter();
|
||||
function handleFlowRecord(row) {
|
||||
router.push({
|
||||
path: "/flowable/process/detail/" + row.procInsId,
|
||||
query: {
|
||||
definitionId: row.procDefId,
|
||||
deployId: row.deployId,
|
||||
taskId: row.taskId,
|
||||
finished: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
/** 撤回任务 */
|
||||
function handleRevoke(row) {
|
||||
const params = {
|
||||
procInsId: row.procInsId,
|
||||
};
|
||||
revokeProcess(params).then((res) => {
|
||||
this.$modal.msgSuccess(res.msg);
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$confirm('是否确认删除流程定义编号为"' + ids + '"的数据项?', "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(function () {
|
||||
return delDeployment(ids);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
});
|
||||
}
|
||||
defineExpose({
|
||||
getList,
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
export default {
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next((vm) => {
|
||||
vm.getList();
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
221
src/views/office/index.vue
Normal file
221
src/views/office/index.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="deployTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
size="small"
|
||||
v-model="queryParams.deployTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
<el-table v-loading="loading" fit :data="processList">
|
||||
<el-table-column label="序号" type="index" width="50"></el-table-column>
|
||||
<el-table-column
|
||||
label="流程标识"
|
||||
align="center"
|
||||
prop="processKey"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="流程名称"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleProcessView(row)">
|
||||
<span>{{ row.processName }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="流程分类"
|
||||
align="center"
|
||||
prop="categoryName"
|
||||
:formatter="categoryFormat"
|
||||
/>
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="default">v{{ row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag type="success" v-if="!row.suspended">激活</el-tag>
|
||||
<el-tag type="warning" v-if="row.suspended">挂起</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="部署时间"
|
||||
align="center"
|
||||
prop="deploymentTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
icon="video-play"
|
||||
@click="handleStart(row)"
|
||||
v-hasPermi="['flowable:process:start']"
|
||||
>发起</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 流程图 -->
|
||||
<el-dialog
|
||||
:title="processView.title"
|
||||
v-model="processView.open"
|
||||
width="70%"
|
||||
append-to-body
|
||||
>
|
||||
<process-viewer
|
||||
:key="`designer-${processView.index}`"
|
||||
:xml="processView.xmlData"
|
||||
:style="{ height: '400px' }"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="WorkProcess">
|
||||
import { listProcess, getBpmnXml } from "@/api/flowable/process";
|
||||
import { listAllCategory } from "@/api/flowable/category";
|
||||
import ProcessViewer from "@/components/ProcessViewer";
|
||||
import { toRefs, reactive, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const queryFormRef = ref();
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
const filterCategoryText = ref("");
|
||||
const categoryOptions = ref([]);
|
||||
// 流程定义表格数据
|
||||
const processList = ref([]);
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
categoryProps: {
|
||||
label: "categoryName",
|
||||
value: "code",
|
||||
},
|
||||
processView: {
|
||||
title: "",
|
||||
open: false,
|
||||
index: undefined,
|
||||
xmlData: "",
|
||||
},
|
||||
});
|
||||
const { queryParams, categoryProps, processView } = toRefs(data);
|
||||
/** 查询流程分类列表 */
|
||||
function getCategoryList() {
|
||||
listAllCategory().then((response) => (categoryOptions.value = response.rows));
|
||||
}
|
||||
/** 查询流程定义列表 */
|
||||
function getList() {
|
||||
listProcess(queryParams.value).then((response) => {
|
||||
processList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
// 搜索按钮操作
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
// 重置按钮操作
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
/** 查看流程图 */
|
||||
function handleProcessView(row) {
|
||||
let definitionId = row.definitionId;
|
||||
processView.value.title = "流程图";
|
||||
processView.value.index = definitionId;
|
||||
// 发送请求,获取xml
|
||||
getBpmnXml(definitionId).then((res) => {
|
||||
processView.value.xmlData = res.data;
|
||||
});
|
||||
processView.value.open = true;
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
function handleStart(row) {
|
||||
router.push({
|
||||
path: "/flowable/process/start/" + row.deploymentId,
|
||||
query: {
|
||||
definitionId: row.definitionId,
|
||||
},
|
||||
});
|
||||
}
|
||||
function categoryFormat(row, column) {
|
||||
return (
|
||||
categoryOptions.value.find((k) => k.code === row.category)?.categoryName ??
|
||||
""
|
||||
);
|
||||
}
|
||||
getCategoryList();
|
||||
getList();
|
||||
</script>
|
364
src/views/office/own.vue
Normal file
364
src/views/office/own.vue
Normal file
@ -0,0 +1,364 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="deployTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
size="small"
|
||||
v-model="queryParams.deployTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="delete"
|
||||
size="small"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="download"
|
||||
size="small"
|
||||
@click="handleExport"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="ownProcessList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column
|
||||
label="流程编号"
|
||||
align="center"
|
||||
prop="procInsId"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="流程名称"
|
||||
align="center"
|
||||
prop="procDefName"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="流程类别"
|
||||
align="center"
|
||||
prop="category"
|
||||
:formatter="categoryFormat"
|
||||
/>
|
||||
<el-table-column label="流程版本" align="center" width="80px">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="default">v{{ row.procDefVersion }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="提交时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column label="流程状态" align="center" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.finishTime == null" size="small">进行中</el-tag>
|
||||
<el-tag type="success" v-if="row.finishTime != null" size="small"
|
||||
>已完成</el-tag
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="耗时"
|
||||
align="center"
|
||||
prop="duration"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column label="当前节点" align="center" prop="taskName" />
|
||||
<el-table-column label="办理" align="center">
|
||||
<template #default="{ row }">
|
||||
<label v-if="row.assigneeName"
|
||||
>{{ row.assigneeName }}
|
||||
<el-tag type="info" size="small">{{ row.deptName }}</el-tag></label
|
||||
>
|
||||
<label v-if="row.candidate">{{ row.candidate }}</label>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
icon="tickets"
|
||||
@click="handleFlowRecord(row)"
|
||||
v-hasPermi="['flowable:process:query']"
|
||||
>详情</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
icon="delete"
|
||||
@click="handleDelete(row)"
|
||||
v-hasPermi="['flowable:process:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
icon="circle-close"
|
||||
@click="handleStop(row)"
|
||||
v-hasPermi="['flowable:process:cancel']"
|
||||
>取消</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="Own">
|
||||
import {
|
||||
listOwnProcess,
|
||||
stopProcess,
|
||||
delProcess,
|
||||
} from "@/api/flowable/process";
|
||||
import { download } from "@/utils/request";
|
||||
import { listAllCategory } from "@/api/flowable/category";
|
||||
import { ref, reactive, toRefs } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const queryFormRef = ref();
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
const processLoading = ref(true);
|
||||
// 选中数组
|
||||
const ids = ref([]);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
const categoryOptions = ref([]);
|
||||
const processTotal = ref(0);
|
||||
// 我发起的流程列表数据
|
||||
const ownProcessList = ref([]);
|
||||
// 弹出层标题
|
||||
const title = ref("");
|
||||
// 是否显示弹出层
|
||||
const open = ref(false);
|
||||
const src = ref("");
|
||||
const definitionList = ref([]);
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
category: null,
|
||||
key: null,
|
||||
tenantId: null,
|
||||
deployTime: null,
|
||||
derivedFrom: null,
|
||||
derivedFromRoot: null,
|
||||
parentDeploymentId: null,
|
||||
engineVersion: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {},
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
function getCategoryList() {
|
||||
listAllCategory().then((response) => (categoryOptions.value = response.rows));
|
||||
}
|
||||
/** 查询流程定义列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listOwnProcess(queryParams.value).then((response) => {
|
||||
ownProcessList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.procInsId);
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 取消流程申请 */
|
||||
function handleStop(row) {
|
||||
const params = {
|
||||
procInsId: row.procInsId,
|
||||
};
|
||||
stopProcess(params).then((res) => {
|
||||
ElMessage.success(res.msg);
|
||||
getList();
|
||||
});
|
||||
}
|
||||
|
||||
const router = useRouter();
|
||||
/** 流程流转记录 */
|
||||
function handleFlowRecord(row) {
|
||||
router.push({
|
||||
path: "/flowable/process/detail/" + row.procInsId,
|
||||
query: {
|
||||
definitionId: row.procDefId,
|
||||
deployId: row.deployId,
|
||||
taskId: row.taskId,
|
||||
finished: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
// const ids = row.procInsId;
|
||||
const deleteIds = row.procInsId ? [row.procInsId] : ids.value;
|
||||
ElMessageBox.confirm(
|
||||
'是否确认删除流程定义编号为"' + deleteIds.join(",") + '"的数据项?',
|
||||
"警告",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}
|
||||
)
|
||||
.then(function () {
|
||||
return delProcess(deleteIds.join(","));
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success("删除成功");
|
||||
});
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
// const queryParams = queryParams.value;
|
||||
ElMessageBox.confirm("是否确认导出所有流程定义数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(function () {
|
||||
// return exportDeployment(queryParams);
|
||||
})
|
||||
.then((response) => {
|
||||
download(response.msg);
|
||||
});
|
||||
}
|
||||
function categoryFormat(row, column) {
|
||||
return (
|
||||
categoryOptions.value.find((k) => k.code === row.category)?.categoryName ??
|
||||
""
|
||||
);
|
||||
}
|
||||
getCategoryList();
|
||||
|
||||
defineExpose({
|
||||
getList,
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
export default {
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next((vm) => {
|
||||
vm.getList();
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<!-- <script>
|
||||
export default {
|
||||
name: "Own",
|
||||
components: {},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
this.getCategoryList();
|
||||
},
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next((vm) => {
|
||||
vm.getList();
|
||||
});
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
</script> -->
|
95
src/views/office/start.vue
Normal file
95
src/views/office/start.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>发起流程</span>
|
||||
</div>
|
||||
<el-col :span="18" :offset="3">
|
||||
<div class="form-conf" v-if="formOpen">
|
||||
<parser
|
||||
:key="new Date().getTime()"
|
||||
:form-conf="formData"
|
||||
@submit="submit"
|
||||
ref="parser"
|
||||
@getData="getData"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="WorkStart">
|
||||
import { getProcessForm, startProcess } from "@/api/flowable/process";
|
||||
import Parser from "@/utils/generator/parser";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, toRefs, ref } from "vue";
|
||||
import tab from "@/plugins/tab";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const definitionId = ref(null);
|
||||
const deployId = ref(null);
|
||||
const formOpen = ref(false);
|
||||
const data = reactive({
|
||||
formData: {},
|
||||
});
|
||||
const { formData } = toRefs(data);
|
||||
const route = useRoute();
|
||||
|
||||
function initData() {
|
||||
deployId.value = route.params && route.params.deployId;
|
||||
definitionId.value = route.query && route.query.definitionId;
|
||||
getProcessForm({
|
||||
definitionId: definitionId.value,
|
||||
deployId: deployId.value,
|
||||
}).then((res) => {
|
||||
if (res.msg) {
|
||||
formData.value = JSON.parse(res.msg);
|
||||
formOpen.value = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 接收子组件传的值 */
|
||||
function getData(data) {
|
||||
if (data) {
|
||||
const variables = [];
|
||||
data.fields.forEach((item) => {
|
||||
let variableData = {};
|
||||
variableData.label = item.__config__.label;
|
||||
// 表单值为多个选项时
|
||||
if (item.__config__.defaultValue instanceof Array) {
|
||||
const array = [];
|
||||
item.__config__.defaultValue.forEach((val) => {
|
||||
array.push(val);
|
||||
});
|
||||
variableData.val = array;
|
||||
} else {
|
||||
variableData.val = item.__config__.defaultValue;
|
||||
}
|
||||
variables.push(variableData);
|
||||
});
|
||||
variables.value = variables;
|
||||
}
|
||||
}
|
||||
function submit(data) {
|
||||
if (data && definitionId.value) {
|
||||
// 启动流程并将表单数据加入流程变量
|
||||
startProcess(definitionId.value, JSON.stringify(data.valData)).then(
|
||||
(res) => {
|
||||
ElMessage.success(res.msg);
|
||||
tab.closeOpenPage({
|
||||
path: "/office/own",
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
initData();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-conf {
|
||||
margin: 15px auto;
|
||||
width: 80%;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
260
src/views/office/todo.vue
Normal file
260
src/views/office/todo.vue
Normal file
@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryFormRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="请输入名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="deployTime">
|
||||
<el-date-picker
|
||||
clearable
|
||||
size="small"
|
||||
v-model="queryParams.deployTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择时间"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
@click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="refresh" size="small" @click="resetQuery"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="delete"
|
||||
size="small"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="todoList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<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">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="default">v{{ row.procDefVersion }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程发起人" align="center">
|
||||
<template #default="{ row }">
|
||||
<label
|
||||
>{{ row.startUserName }}
|
||||
<el-tag type="info" size="small">{{
|
||||
row.startDeptName
|
||||
}}</el-tag></label
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="接收时间"
|
||||
align="center"
|
||||
prop="createTime"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
type="primary"
|
||||
icon="edit"
|
||||
@click="handleProcess(row)"
|
||||
v-hasPermi="['flowable:process:approval']"
|
||||
>办理
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="Todo">
|
||||
import { listTodoProcess } from "@/api/flowable/process";
|
||||
// import { delDeployment, exportDeployment } from "@/api/flowable/todo";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { ref, reactive, toRefs } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const queryFormRef = ref();
|
||||
const router = useRouter();
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
// 选中数组
|
||||
const ids = ref([]);
|
||||
// 非单个禁用
|
||||
const single = ref(true);
|
||||
// 非多个禁用
|
||||
const multiple = ref(true);
|
||||
// 显示搜索条件
|
||||
const showSearch = ref(true);
|
||||
// 总条数
|
||||
const total = ref(0);
|
||||
// 流程待办任务表格数据
|
||||
const todoList = ref([]);
|
||||
// 弹出层标题
|
||||
const title = ref("");
|
||||
// 是否显示弹出层
|
||||
const open = ref(false);
|
||||
|
||||
const data = reactive({
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: null,
|
||||
category: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {},
|
||||
});
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询流程定义列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listTodoProcess(queryParams.value).then((response) => {
|
||||
todoList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
// 跳转到处理页面
|
||||
function handleProcess(row) {
|
||||
router.push({
|
||||
path: "/flowable/process/detail/" + row.procInsId,
|
||||
query: {
|
||||
definitionId: row.procDefId,
|
||||
deployId: row.deployId,
|
||||
taskId: row.taskId,
|
||||
finished: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
handleQuery();
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
// /** 新增按钮操作 */
|
||||
// function handleAdd() {
|
||||
// reset();
|
||||
// open.value = true;
|
||||
// title.value = "添加流程定义";
|
||||
// }
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const ids = row.id || ids.value;
|
||||
ElMessageBox.confirm(
|
||||
'是否确认删除流程定义编号为"' + ids + '"的数据项?',
|
||||
"警告",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}
|
||||
)
|
||||
.then(function () {
|
||||
return delDeployment(ids);
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success("删除成功");
|
||||
});
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
const queryParams = queryParams.value;
|
||||
ElMessageBox.confirm("是否确认导出所有流程定义数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(function () {
|
||||
return exportDeployment(queryParams);
|
||||
})
|
||||
.then((response) => {
|
||||
this.download(response.msg);
|
||||
});
|
||||
}
|
||||
defineExpose({
|
||||
getList,
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
export default {
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next((vm) => {
|
||||
vm.getList();
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user