init:first commit of plus-ui
This commit is contained in:
280
src/components/Process/approvalRecord.vue
Normal file
280
src/components/Process/approvalRecord.vue
Normal file
@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-dialog v-model="visible" draggable title="审批记录" :width="props.width" :height="props.height" :close-on-click-modal="false">
|
||||
<el-tabs v-model="tabActiveName" class="demo-tabs">
|
||||
<el-tab-pane v-loading="loading" label="流程图" name="image" style="height: 68vh">
|
||||
<div
|
||||
ref="imageWrapperRef"
|
||||
class="image-wrapper"
|
||||
@wheel="handleMouseWheel"
|
||||
@mousedown="handleMouseDown"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseup="handleMouseUp"
|
||||
@mouseleave="handleMouseLeave"
|
||||
@dblclick="resetTransform"
|
||||
:style="transformStyle"
|
||||
>
|
||||
<el-card class="box-card">
|
||||
<el-image :src="imgUrl" class="scalable-image" />
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-loading="loading" label="审批信息" name="info">
|
||||
<div>
|
||||
<el-table :data="historyList" style="width: 100%" border fit>
|
||||
<el-table-column type="index" label="序号" align="center" width="60"></el-table-column>
|
||||
<el-table-column prop="nodeName" label="任务名称" sortable align="center"></el-table-column>
|
||||
<el-table-column prop="approveName" :show-overflow-tooltip="true" label="办理人" sortable align="center">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.approveName">
|
||||
<el-tag v-for="(item, index) in scope.row.approveName.split(',')" :key="index" type="success">{{ item }}</el-tag>
|
||||
</template>
|
||||
<template v-else> <el-tag type="success">无</el-tag></template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="flowStatus" label="状态" width="80" sortable align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_task_status" :value="scope.row.flowStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="message" label="审批意见" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
|
||||
<el-table-column prop="createTime" label="开始时间" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
|
||||
<el-table-column prop="updateTime" label="结束时间" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
|
||||
<el-table-column
|
||||
prop="runDuration"
|
||||
label="运行时长"
|
||||
width="140"
|
||||
:show-overflow-tooltip="true"
|
||||
sortable
|
||||
align="center"
|
||||
></el-table-column>
|
||||
<el-table-column prop="attachmentList" width="120" label="附件" align="center">
|
||||
<template #default="scope">
|
||||
<el-popover v-if="scope.row.attachmentList && scope.row.attachmentList.length > 0" placement="right" :width="310" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" style="margin-right: 16px">附件</el-button>
|
||||
</template>
|
||||
<el-table border :data="scope.row.attachmentList">
|
||||
<el-table-column prop="originalName" width="202" :show-overflow-tooltip="true" label="附件名称"></el-table-column>
|
||||
<el-table-column prop="name" width="80" align="center" :show-overflow-tooltip="true" label="操作">
|
||||
<template #default="tool">
|
||||
<el-button type="text" @click="handleDownload(tool.row.ossId)">下载</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { flowImage } from '@/api/workflow/instance';
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { listByIds } from '@/api/system/oss';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status'));
|
||||
const props = defineProps({
|
||||
width: propTypes.string.def('80%'),
|
||||
height: propTypes.string.def('100%')
|
||||
});
|
||||
const loading = ref(false);
|
||||
const visible = ref(false);
|
||||
const historyList = ref<Array<any>>([]);
|
||||
const tabActiveName = ref('image');
|
||||
const imgUrl = ref('');
|
||||
|
||||
//初始化查询审批记录
|
||||
const init = async (businessId: string | number) => {
|
||||
visible.value = true;
|
||||
loading.value = true;
|
||||
tabActiveName.value = 'image';
|
||||
historyList.value = [];
|
||||
flowImage(businessId).then((resp) => {
|
||||
if (resp.data) {
|
||||
historyList.value = resp.data.list;
|
||||
imgUrl.value = 'data:image/gif;base64,' + resp.data.image;
|
||||
if (historyList.value.length > 0) {
|
||||
historyList.value.forEach((item) => {
|
||||
if (item.ext) {
|
||||
getIds(item.ext).then((res) => {
|
||||
item.attachmentList = res.data;
|
||||
});
|
||||
} else {
|
||||
item.attachmentList = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
const getIds = async (ids: string | number) => {
|
||||
const res = await listByIds(ids);
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 下载按钮操作 */
|
||||
const handleDownload = (ossId: string) => {
|
||||
proxy?.$download.oss(ossId);
|
||||
};
|
||||
|
||||
const imageWrapperRef = ref<HTMLElement | null>(null);
|
||||
const scale = ref(1); // 初始缩放比例
|
||||
const maxScale = 3; // 最大缩放比例
|
||||
const minScale = 0.5; // 最小缩放比例
|
||||
|
||||
let isDragging = false;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let currentTranslateX = 0;
|
||||
let currentTranslateY = 0;
|
||||
|
||||
const handleMouseWheel = (event: WheelEvent) => {
|
||||
event.preventDefault();
|
||||
let newScale = scale.value - event.deltaY / 1000;
|
||||
newScale = Math.max(minScale, Math.min(newScale, maxScale));
|
||||
if (newScale !== scale.value) {
|
||||
scale.value = newScale;
|
||||
resetDragPosition(); // 重置拖拽位置,使图片居中
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
if (scale.value > 1) {
|
||||
event.preventDefault(); // 阻止默认行为,防止拖拽
|
||||
isDragging = true;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (!isDragging || !imageWrapperRef.value) return;
|
||||
|
||||
const deltaX = event.clientX - startX;
|
||||
const deltaY = event.clientY - startY;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
|
||||
currentTranslateX += deltaX;
|
||||
currentTranslateY += deltaY;
|
||||
|
||||
// 边界检测,防止图片被拖出容器
|
||||
const bounds = getBounds();
|
||||
if (currentTranslateX > bounds.maxTranslateX) {
|
||||
currentTranslateX = bounds.maxTranslateX;
|
||||
} else if (currentTranslateX < bounds.minTranslateX) {
|
||||
currentTranslateX = bounds.minTranslateX;
|
||||
}
|
||||
|
||||
if (currentTranslateY > bounds.maxTranslateY) {
|
||||
currentTranslateY = bounds.maxTranslateY;
|
||||
} else if (currentTranslateY < bounds.minTranslateY) {
|
||||
currentTranslateY = bounds.minTranslateY;
|
||||
}
|
||||
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const resetTransform = () => {
|
||||
scale.value = 1;
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const resetDragPosition = () => {
|
||||
currentTranslateX = 0;
|
||||
currentTranslateY = 0;
|
||||
applyTransform();
|
||||
};
|
||||
|
||||
const applyTransform = () => {
|
||||
if (imageWrapperRef.value) {
|
||||
imageWrapperRef.value.style.transform = `translate(${currentTranslateX}px, ${currentTranslateY}px) scale(${scale.value})`;
|
||||
}
|
||||
};
|
||||
|
||||
const getBounds = () => {
|
||||
if (!imageWrapperRef.value) return { minTranslateX: 0, maxTranslateX: 0, minTranslateY: 0, maxTranslateY: 0 };
|
||||
|
||||
const imgRect = imageWrapperRef.value.getBoundingClientRect();
|
||||
const containerRect = imageWrapperRef.value.parentElement?.getBoundingClientRect() ?? imgRect;
|
||||
|
||||
const minTranslateX = (containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const maxTranslateX = -(containerRect.width - imgRect.width * scale.value) / 2;
|
||||
const minTranslateY = (containerRect.height - imgRect.height * scale.value) / 2;
|
||||
const maxTranslateY = -(containerRect.height - imgRect.height * scale.value) / 2;
|
||||
|
||||
return { minTranslateX, maxTranslateX, minTranslateY, maxTranslateY };
|
||||
};
|
||||
|
||||
const transformStyle = computed(() => ({
|
||||
transition: isDragging ? 'none' : 'transform 0.2s ease'
|
||||
}));
|
||||
|
||||
/**
|
||||
* 对外暴露子组件方法
|
||||
*/
|
||||
defineExpose({
|
||||
init
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.triangle {
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.triangle::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 8em;
|
||||
right: 215px;
|
||||
border: 15px solid;
|
||||
border-color: transparent #fff transparent transparent;
|
||||
}
|
||||
|
||||
.container {
|
||||
:deep(.el-dialog .el-dialog__body) {
|
||||
max-height: calc(100vh - 170px) !important;
|
||||
min-height: calc(100vh - 170px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
user-select: none; /* 禁用文本选择 */
|
||||
cursor: grab; /* 设置初始鼠标指针为可拖动 */
|
||||
}
|
||||
|
||||
.image-wrapper:active {
|
||||
cursor: grabbing; /* 当正在拖动时改变鼠标指针 */
|
||||
}
|
||||
|
||||
.scalable-image {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
207
src/components/Process/processMeddle.vue
Normal file
207
src/components/Process/processMeddle.vue
Normal file
@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" draggable title="流程干预" :width="props.width" :height="props.height" :close-on-click-modal="false">
|
||||
<el-descriptions v-loading="loading" class="margin-top" :title="`${task.flowName}(${task.flowCode})`" :column="2" border>
|
||||
<el-descriptions-item label="任务名称">{{ task.nodeName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="节点编码">{{ task.nodeCode }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开始时间">{{ task.createTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="流程实例ID">{{ task.instanceId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="版本号">{{ task.version }}.0</el-descriptions-item>
|
||||
<el-descriptions-item label="业务ID">{{ task.businessId }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转办 </el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="openMultiInstanceUser"
|
||||
>
|
||||
加签
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="handleTaskUser"
|
||||
>
|
||||
减签
|
||||
</el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> 终止 </el-button>
|
||||
</span>
|
||||
</template>
|
||||
<!-- 转办 -->
|
||||
<UserSelect ref="transferTaskRef" :multiple="false" @confirm-call-back="handleTransferTask"></UserSelect>
|
||||
<!-- 加签组件 -->
|
||||
<UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect>
|
||||
<el-dialog v-model="deleteSignatureVisible" draggable title="减签人员" width="700px" height="400px" append-to-body :close-on-click-modal="false"
|
||||
><div>
|
||||
<el-table :data="deleteUserList" border>
|
||||
<el-table-column prop="nodeName" label="任务名称" />
|
||||
<el-table-column prop="nickName" label="办理人" />
|
||||
<el-table-column label="操作" align="center" width="160">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" size="small" icon="Delete" @click="deleteMultiInstanceUser(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes';
|
||||
import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types';
|
||||
import UserSelect from '@/components/UserSelect';
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
import { getTask, taskOperation, currentTaskAllUser, terminationTask } from '@/api/workflow/task';
|
||||
const props = defineProps({
|
||||
width: propTypes.string.def('50%'),
|
||||
height: propTypes.string.def('100%')
|
||||
});
|
||||
const emits = defineEmits(['submitCallback']);
|
||||
const transferTaskRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>();
|
||||
//遮罩层
|
||||
const loading = ref(true);
|
||||
//按钮
|
||||
const buttonDisabled = ref(true);
|
||||
const visible = ref(false);
|
||||
//减签弹窗
|
||||
const deleteSignatureVisible = ref(false);
|
||||
//可减签的人员
|
||||
const deleteUserList = ref<any>([]);
|
||||
//任务
|
||||
const task = ref<FlowTaskVO>({
|
||||
id: undefined,
|
||||
createTime: undefined,
|
||||
updateTime: undefined,
|
||||
tenantId: undefined,
|
||||
definitionId: undefined,
|
||||
instanceId: undefined,
|
||||
flowName: undefined,
|
||||
businessId: undefined,
|
||||
nodeCode: undefined,
|
||||
nodeName: undefined,
|
||||
flowCode: undefined,
|
||||
flowStatus: undefined,
|
||||
nodeType: undefined,
|
||||
nodeRatio: undefined,
|
||||
version: undefined
|
||||
});
|
||||
|
||||
const open = (taskId: string) => {
|
||||
visible.value = true;
|
||||
getTask(taskId).then((response) => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
task.value = response.data;
|
||||
});
|
||||
};
|
||||
|
||||
//打开转办
|
||||
const openTransferTask = () => {
|
||||
transferTaskRef.value.open();
|
||||
};
|
||||
//转办
|
||||
const handleTransferTask = async (data) => {
|
||||
if (data && data.length > 0) {
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userId: data[0].userId,
|
||||
taskId: task.value.id,
|
||||
message: ''
|
||||
});
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await taskOperation(taskOperationBo, 'transferTask').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
visible.value = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning('请选择用户!');
|
||||
}
|
||||
};
|
||||
//加签
|
||||
const openMultiInstanceUser = async () => {
|
||||
multiInstanceUserRef.value.open();
|
||||
};
|
||||
//加签
|
||||
const addMultiInstanceUser = async (data) => {
|
||||
if (data && data.length > 0) {
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userIds: data.map((e) => e.userId),
|
||||
taskId: task.value.id,
|
||||
message: ''
|
||||
});
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await taskOperation(taskOperationBo, 'addSignature').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
visible.value = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning('请选择用户!');
|
||||
}
|
||||
};
|
||||
//减签
|
||||
const deleteMultiInstanceUser = async (row) => {
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userIds: [row.userId],
|
||||
taskId: task.value.id,
|
||||
message: ''
|
||||
});
|
||||
await taskOperation(taskOperationBo, 'reductionSignature').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
visible.value = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
//获取办理人
|
||||
const handleTaskUser = async () => {
|
||||
let data = await currentTaskAllUser(task.value.id);
|
||||
deleteUserList.value = data.data;
|
||||
if (deleteUserList.value && deleteUserList.value.length > 0) {
|
||||
deleteUserList.value.forEach((e) => {
|
||||
e.nodeName = task.value.nodeName;
|
||||
});
|
||||
}
|
||||
deleteSignatureVisible.value = true;
|
||||
};
|
||||
|
||||
//终止任务
|
||||
const handleTerminationTask = async () => {
|
||||
let params = {
|
||||
taskId: task.value.id,
|
||||
comment: ''
|
||||
};
|
||||
await proxy?.$modal.confirm('是否确认终止?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await terminationTask(params).finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
visible.value = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
/**
|
||||
* 对外暴露子组件方法
|
||||
*/
|
||||
defineExpose({
|
||||
open
|
||||
});
|
||||
</script>
|
421
src/components/Process/submitVerify.vue
Normal file
421
src/components/Process/submitVerify.vue
Normal file
@ -0,0 +1,421 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialog.visible" :title="dialog.title" width="50%" draggable :before-close="cancel" center :close-on-click-modal="false">
|
||||
<el-form v-loading="loading" :model="form" label-width="120px">
|
||||
<el-form-item label="消息提醒">
|
||||
<el-checkbox-group v-model="form.messageType">
|
||||
<el-checkbox value="1" name="type" disabled>站内信</el-checkbox>
|
||||
<el-checkbox value="2" name="type">邮件</el-checkbox>
|
||||
<el-checkbox value="3" name="type">短信</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
|
||||
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送">
|
||||
<el-button type="primary" icon="Plus" circle @click="openUserSelectCopy" />
|
||||
<el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)">
|
||||
{{ user.nickName }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="审批意见">
|
||||
<el-input v-model="form.message" type="textarea" resize="none" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="buttonDisabled" type="primary" @click="handleCompleteTask"> 提交 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openDelegateTask"> 委托 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转办 </el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="openMultiInstanceUser"
|
||||
>
|
||||
加签
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0"
|
||||
:disabled="buttonDisabled"
|
||||
type="primary"
|
||||
@click="handleTaskUser"
|
||||
>
|
||||
减签
|
||||
</el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> 终止 </el-button>
|
||||
<el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen"> 退回 </el-button>
|
||||
<el-button :disabled="buttonDisabled" @click="cancel">取消</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<!-- 抄送 -->
|
||||
<UserSelect ref="userSelectCopyRef" :multiple="true" :data="selectCopyUserIds" @confirm-call-back="userSelectCopyCallBack"></UserSelect>
|
||||
<!-- 转办 -->
|
||||
<UserSelect ref="transferTaskRef" :multiple="false" @confirm-call-back="handleTransferTask"></UserSelect>
|
||||
<!-- 委托 -->
|
||||
<UserSelect ref="delegateTaskRef" :multiple="false" @confirm-call-back="handleDelegateTask"></UserSelect>
|
||||
<!-- 加签组件 -->
|
||||
<UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect>
|
||||
|
||||
<!-- 驳回开始 -->
|
||||
<el-dialog v-model="backVisible" draggable title="驳回" width="40%" :close-on-click-modal="false">
|
||||
<el-form v-if="task.flowStatus === 'waiting'" v-loading="backLoading" :model="backForm" label-width="120px">
|
||||
<el-form-item label="驳回节点">
|
||||
<el-select v-model="backForm.nodeCode" clearable placeholder="请选择" style="width: 300px">
|
||||
<el-option v-for="item in taskNodeList" :key="item.nodeCode" :label="item.nodeName" :value="item.nodeCode" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="消息提醒">
|
||||
<el-checkbox-group v-model="backForm.messageType">
|
||||
<el-checkbox label="1" name="type" disabled>站内信</el-checkbox>
|
||||
<el-checkbox label="2" name="type">邮件</el-checkbox>
|
||||
<el-checkbox label="3" name="type">短信</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
|
||||
<fileUpload v-model="backForm.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见">
|
||||
<el-input v-model="backForm.message" type="textarea" resize="none" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="float: right; padding-bottom: 20px">
|
||||
<el-button :disabled="backButtonDisabled" type="primary" @click="handleBackProcess">确认</el-button>
|
||||
<el-button :disabled="backButtonDisabled" @click="backVisible = false">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 驳回结束 -->
|
||||
<el-dialog v-model="deleteSignatureVisible" draggable title="减签人员" width="700px" height="400px" append-to-body :close-on-click-modal="false">
|
||||
<div>
|
||||
<el-table :data="deleteUserList" border>
|
||||
<el-table-column prop="nodeName" label="任务名称" />
|
||||
<el-table-column prop="nickName" label="办理人" />
|
||||
<el-table-column label="操作" align="center" width="160">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" size="small" icon="Delete" @click="deleteMultiInstanceUser(scope.row)">删除 </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ComponentInternalInstance } from 'vue';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { completeTask, backProcess, getTask, taskOperation, terminationTask, getBackTaskNode, currentTaskAllUser } from '@/api/workflow/task';
|
||||
import UserSelect from '@/components/UserSelect';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
import { UserVO } from '@/api/system/user/types';
|
||||
import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types';
|
||||
|
||||
const userSelectCopyRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const transferTaskRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const delegateTaskRef = ref<InstanceType<typeof UserSelect>>();
|
||||
const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>();
|
||||
|
||||
const props = defineProps({
|
||||
taskVariables: {
|
||||
type: Object as () => Record<string, any>,
|
||||
default: () => {}
|
||||
}
|
||||
});
|
||||
//遮罩层
|
||||
const loading = ref(true);
|
||||
//按钮
|
||||
const buttonDisabled = ref(true);
|
||||
//任务id
|
||||
const taskId = ref<string>('');
|
||||
//抄送人
|
||||
const selectCopyUserList = ref<UserVO[]>([]);
|
||||
//抄送人id
|
||||
const selectCopyUserIds = ref<string>(undefined);
|
||||
//可减签的人员
|
||||
const deleteUserList = ref<any>([]);
|
||||
//驳回是否显示
|
||||
const backVisible = ref(false);
|
||||
const backLoading = ref(true);
|
||||
const backButtonDisabled = ref(true);
|
||||
// 可驳回得任务节点
|
||||
const taskNodeList = ref([]);
|
||||
//任务
|
||||
const task = ref<FlowTaskVO>({
|
||||
id: undefined,
|
||||
createTime: undefined,
|
||||
updateTime: undefined,
|
||||
tenantId: undefined,
|
||||
definitionId: undefined,
|
||||
instanceId: undefined,
|
||||
flowName: undefined,
|
||||
businessId: undefined,
|
||||
nodeCode: undefined,
|
||||
nodeName: undefined,
|
||||
flowCode: undefined,
|
||||
flowStatus: undefined,
|
||||
formCustom: undefined,
|
||||
formPath: undefined,
|
||||
nodeType: undefined,
|
||||
nodeRatio: undefined
|
||||
});
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '提示'
|
||||
});
|
||||
//减签弹窗
|
||||
const deleteSignatureVisible = ref(false);
|
||||
const form = ref<Record<string, any>>({
|
||||
taskId: undefined,
|
||||
message: undefined,
|
||||
variables: {},
|
||||
messageType: ['1'],
|
||||
flowCopyList: []
|
||||
});
|
||||
const backForm = ref<Record<string, any>>({
|
||||
taskId: undefined,
|
||||
nodeCode: undefined,
|
||||
message: undefined,
|
||||
variables: {},
|
||||
messageType: ['1']
|
||||
});
|
||||
//打开弹窗
|
||||
const openDialog = (id?: string) => {
|
||||
selectCopyUserIds.value = undefined;
|
||||
selectCopyUserList.value = [];
|
||||
form.value.fileId = undefined;
|
||||
taskId.value = id;
|
||||
form.value.message = undefined;
|
||||
dialog.visible = true;
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
nextTick(() => {
|
||||
getTask(taskId.value).then((response) => {
|
||||
task.value = response.data;
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {});
|
||||
const emits = defineEmits(['submitCallback', 'cancelCallback']);
|
||||
|
||||
/** 办理流程 */
|
||||
const handleCompleteTask = async () => {
|
||||
form.value.taskId = taskId.value;
|
||||
form.value.taskVariables = props.taskVariables;
|
||||
if (selectCopyUserList.value && selectCopyUserList.value.length > 0) {
|
||||
let flowCopyList = [];
|
||||
selectCopyUserList.value.forEach((e) => {
|
||||
let copyUser = {
|
||||
userId: e.userId,
|
||||
userName: e.nickName
|
||||
};
|
||||
flowCopyList.push(copyUser);
|
||||
});
|
||||
form.value.flowCopyList = flowCopyList;
|
||||
}
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
try {
|
||||
await completeTask(form.value);
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 驳回弹窗打开 */
|
||||
const handleBackProcessOpen = async () => {
|
||||
backForm.value = {};
|
||||
backForm.value.messageType = ['1'];
|
||||
backVisible.value = true;
|
||||
backLoading.value = true;
|
||||
backButtonDisabled.value = true;
|
||||
let data = await getBackTaskNode(task.value.definitionId, task.value.nodeCode);
|
||||
taskNodeList.value = data.data;
|
||||
backLoading.value = false;
|
||||
backButtonDisabled.value = false;
|
||||
backForm.value.nodeCode = taskNodeList.value[0].nodeCode;
|
||||
};
|
||||
/** 驳回流程 */
|
||||
const handleBackProcess = async () => {
|
||||
backForm.value.taskId = taskId.value;
|
||||
await proxy?.$modal.confirm('是否确认驳回到申请人?');
|
||||
loading.value = true;
|
||||
backLoading.value = true;
|
||||
backButtonDisabled.value = true;
|
||||
await backProcess(backForm.value).finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
backLoading.value = false;
|
||||
backButtonDisabled.value = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
//取消
|
||||
const cancel = async () => {
|
||||
dialog.visible = false;
|
||||
buttonDisabled.value = false;
|
||||
emits('cancelCallback');
|
||||
};
|
||||
//打开抄送人员
|
||||
const openUserSelectCopy = () => {
|
||||
userSelectCopyRef.value.open();
|
||||
};
|
||||
//确认抄送人员
|
||||
const userSelectCopyCallBack = (data: UserVO[]) => {
|
||||
if (data && data.length > 0) {
|
||||
selectCopyUserList.value = data;
|
||||
selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
|
||||
}
|
||||
};
|
||||
//删除抄送人员
|
||||
const handleCopyCloseTag = (user: UserVO) => {
|
||||
const userId = user.userId;
|
||||
// 使用split删除用户
|
||||
const index = selectCopyUserList.value.findIndex((item) => item.userId === userId);
|
||||
selectCopyUserList.value.splice(index, 1);
|
||||
selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
|
||||
};
|
||||
//加签
|
||||
const openMultiInstanceUser = async () => {
|
||||
multiInstanceUserRef.value.open();
|
||||
};
|
||||
//加签
|
||||
const addMultiInstanceUser = async (data) => {
|
||||
if (data && data.length > 0) {
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userIds: data.map((e) => e.userId),
|
||||
taskId: taskId.value,
|
||||
message: form.value.message
|
||||
});
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await taskOperation(taskOperationBo, 'addSignature').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning('请选择用户!');
|
||||
}
|
||||
};
|
||||
//减签
|
||||
const deleteMultiInstanceUser = async (row) => {
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userIds: [row.userId],
|
||||
taskId: taskId.value,
|
||||
message: form.value.message
|
||||
});
|
||||
await taskOperation(taskOperationBo, 'reductionSignature').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
//打开转办
|
||||
const openTransferTask = () => {
|
||||
transferTaskRef.value.open();
|
||||
};
|
||||
//转办
|
||||
const handleTransferTask = async (data) => {
|
||||
if (data && data.length > 0) {
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userId: data[0].userId,
|
||||
taskId: taskId.value,
|
||||
message: form.value.message
|
||||
});
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await taskOperation(taskOperationBo, 'transferTask').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning('请选择用户!');
|
||||
}
|
||||
};
|
||||
|
||||
//打开委托
|
||||
const openDelegateTask = () => {
|
||||
delegateTaskRef.value.open();
|
||||
};
|
||||
//委托
|
||||
const handleDelegateTask = async (data) => {
|
||||
if (data && data.length > 0) {
|
||||
const taskOperationBo = reactive<TaskOperationBo>({
|
||||
userId: data[0].userId,
|
||||
taskId: taskId.value,
|
||||
message: form.value.message
|
||||
});
|
||||
await proxy?.$modal.confirm('是否确认提交?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await taskOperation(taskOperationBo, 'delegateTask').finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
} else {
|
||||
proxy?.$modal.msgWarning('请选择用户!');
|
||||
}
|
||||
};
|
||||
//终止任务
|
||||
const handleTerminationTask = async () => {
|
||||
let params = {
|
||||
taskId: taskId.value,
|
||||
comment: form.value.message
|
||||
};
|
||||
await proxy?.$modal.confirm('是否确认终止?');
|
||||
loading.value = true;
|
||||
buttonDisabled.value = true;
|
||||
await terminationTask(params).finally(() => {
|
||||
loading.value = false;
|
||||
buttonDisabled.value = false;
|
||||
});
|
||||
dialog.visible = false;
|
||||
emits('submitCallback');
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
};
|
||||
const handleTaskUser = async () => {
|
||||
let data = await currentTaskAllUser(taskId.value);
|
||||
deleteUserList.value = data.data;
|
||||
if (deleteUserList.value && deleteUserList.value.length > 0) {
|
||||
deleteUserList.value.forEach((e) => {
|
||||
e.nodeName = task.value.nodeName;
|
||||
});
|
||||
}
|
||||
deleteSignatureVisible.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 对外暴露子组件方法
|
||||
*/
|
||||
defineExpose({
|
||||
openDialog
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user