feat(projects): 新增加签功能
This commit is contained in:
parent
188533adc9
commit
55dceca28b
@ -251,7 +251,7 @@ watch(visible, () => {
|
||||
:title="$t('page.system.user.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
class="sm:flex-1-hidden card-wrapper lt-sm:overflow-auto"
|
||||
class="card-wrapper sm:flex-1-hidden lt-sm:overflow-auto"
|
||||
>
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
|
@ -128,12 +128,7 @@ async function initData() {
|
||||
activeTab.value = 'image';
|
||||
instanceId.value = undefined;
|
||||
hisTask.value = [];
|
||||
startLoading();
|
||||
try {
|
||||
await getData();
|
||||
} finally {
|
||||
endLoading();
|
||||
}
|
||||
await getData();
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
|
@ -1,16 +1,19 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, watch } from 'vue';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { fetchTaskOperate, fetchTerminateTask } from '@/service/api/workflow/task';
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
import { useBoolean, useLoading } from '@sa/hooks';
|
||||
import { fetchGetTask, fetchTaskOperate, fetchTerminateTask } from '@/service/api/workflow/task';
|
||||
|
||||
defineOptions({
|
||||
name: 'FlowInterveneModal'
|
||||
});
|
||||
|
||||
const { bool: multiInstanceVisible, setTrue: openMultiInstanceModal } = useBoolean();
|
||||
const { loading, startLoading, endLoading } = useLoading();
|
||||
const { bool: addSignatureVisible, setTrue: openAddSignatureModal } = useBoolean();
|
||||
const { bool: transferVisible, setTrue: openTransferModal } = useBoolean();
|
||||
interface Props {
|
||||
rowData: Api.Workflow.Task;
|
||||
taskId: CommonType.IdType;
|
||||
assigneeIds: CommonType.IdType[];
|
||||
assigneeNames: string[];
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
@ -21,24 +24,25 @@ interface Emits {
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const isWaiting = computed(() => props.rowData.flowStatus === 'waiting');
|
||||
const taskInfo = ref<Api.Workflow.Task>();
|
||||
|
||||
const isWaiting = computed(() => taskInfo.value?.flowStatus === 'waiting');
|
||||
|
||||
// 流程签署比例值 大于0为票签,会签
|
||||
const isTicketOrSignInstance = computed(() => Number(props.rowData.nodeRatio) > 0);
|
||||
const isTicketOrSignInstance = computed(() => Number(taskInfo.value?.nodeRatio) > 0);
|
||||
|
||||
const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
|
||||
type Model = Api.Workflow.TaskOperateParams;
|
||||
|
||||
const model: Model = reactive(createDefaultModel());
|
||||
|
||||
function createDefaultModel(): Model {
|
||||
return {
|
||||
taskId: null,
|
||||
userId: null,
|
||||
userIds: null,
|
||||
userId: undefined,
|
||||
userIds: undefined,
|
||||
message: ''
|
||||
};
|
||||
}
|
||||
@ -77,6 +81,30 @@ function handleTransferConfirm(ids: CommonType.IdType[]) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleAddSignatureConfirm(ids: CommonType.IdType[]) {
|
||||
if (ids.length === 0) {
|
||||
window.$message?.error('请选择加签用户');
|
||||
return;
|
||||
}
|
||||
model.userIds = ids;
|
||||
window.$dialog?.warning({
|
||||
title: '提示',
|
||||
content: '是否确认加签?',
|
||||
positiveText: '确认加签',
|
||||
positiveButtonProps: {
|
||||
type: 'primary'
|
||||
},
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
const { error } = await fetchTaskOperate(model, 'addSignature');
|
||||
if (error) return;
|
||||
window.$message?.success('加签成功');
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleTerminate() {
|
||||
window.$dialog?.warning({
|
||||
title: '提示',
|
||||
@ -96,62 +124,72 @@ function handleTerminate() {
|
||||
});
|
||||
}
|
||||
|
||||
async function getTaskInfo() {
|
||||
startLoading();
|
||||
const { error, data } = await fetchGetTask(props.taskId);
|
||||
if (error) return;
|
||||
taskInfo.value = data;
|
||||
endLoading();
|
||||
}
|
||||
|
||||
watch(visible, () => {
|
||||
if (visible.value) {
|
||||
Object.assign(model, createDefaultModel());
|
||||
model.taskId = props.rowData.id;
|
||||
Object.assign(terminateModel, createDefaultTerminateModel());
|
||||
terminateModel.taskId = props.rowData.id;
|
||||
getTaskInfo();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="visible" class="max-h-520px max-w-90% w-700px" title="流程干预" preset="card" size="medium">
|
||||
<NDescriptions :title="props.rowData.flowName" label-placement="left" :column="2" size="small" bordered>
|
||||
<NDescriptionsItem label="任务名称">
|
||||
{{ props.rowData.nodeName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="节点编码">
|
||||
{{ props.rowData.nodeCode }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="开始时间">
|
||||
{{ props.rowData.createTime }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="流程实例ID">
|
||||
{{ props.rowData.instanceId }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="办理人">
|
||||
<GroupTag :value="props.rowData.assigneeNames" />
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="版本号">
|
||||
<NTag type="info" size="small">v{{ props.rowData.version }}.0</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="业务ID">
|
||||
{{ props.rowData.businessId }}
|
||||
</NDescriptionsItem>
|
||||
</NDescriptions>
|
||||
<NModal
|
||||
v-model:show="visible"
|
||||
class="max-h-520px max-w-90% w-700px"
|
||||
title="流程干预"
|
||||
preset="card"
|
||||
size="medium"
|
||||
:native-scrollbar="false"
|
||||
>
|
||||
<NSpin :show="loading">
|
||||
<NDescriptions :title="taskInfo?.flowName" label-placement="left" :column="2" size="small" bordered>
|
||||
<NDescriptionsItem label="任务名称">
|
||||
{{ taskInfo?.nodeName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="节点编码">
|
||||
{{ taskInfo?.nodeCode }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="开始时间">
|
||||
{{ taskInfo?.createTime }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="流程实例ID">
|
||||
{{ taskInfo?.instanceId }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="办理人">
|
||||
<GroupTag :value="assigneeNames" />
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="版本号">
|
||||
<NTag type="info" size="small">v{{ taskInfo?.version }}.0</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="业务ID">
|
||||
{{ taskInfo?.businessId }}
|
||||
</NDescriptionsItem>
|
||||
</NDescriptions>
|
||||
</NSpin>
|
||||
|
||||
<template #footer>
|
||||
<NSpace justify="end" :size="16">
|
||||
<NButton v-if="isWaiting" type="primary" @click="openTransferModal">转办</NButton>
|
||||
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary" @click="openMultiInstanceModal">
|
||||
加签
|
||||
</NButton>
|
||||
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary" @click="openAddSignatureModal">加签</NButton>
|
||||
<NButton v-if="isWaiting && isTicketOrSignInstance" type="primary">减签</NButton>
|
||||
<NButton v-if="isWaiting" type="error" @click="handleTerminate">中止</NButton>
|
||||
</NSpace>
|
||||
</template>
|
||||
<!-- 转办用户选择器 -->
|
||||
<UserSelectModal
|
||||
v-model:visible="transferVisible"
|
||||
:disabled-ids="props.rowData.assigneeIds.split(',')"
|
||||
@confirm="handleTransferConfirm"
|
||||
/>
|
||||
<UserSelectModal v-model:visible="transferVisible" :disabled-ids="assigneeIds" @confirm="handleTransferConfirm" />
|
||||
<!-- 加签用户选择器 -->
|
||||
<UserSelectModal
|
||||
v-model:visible="multiInstanceVisible"
|
||||
v-model:visible="addSignatureVisible"
|
||||
multiple
|
||||
:disabled-ids="props.rowData.assigneeIds.split(',')"
|
||||
:disabled-ids="assigneeIds"
|
||||
@confirm="handleAddSignatureConfirm"
|
||||
/>
|
||||
</NModal>
|
||||
</template>
|
||||
|
@ -25,6 +25,6 @@ const iframeUrl = `${baseURL}/warm-flow-ui/index.html?${stringify(urlParams)}`;
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<iframe :src="iframeUrl" class="h-[400px] w-full" />
|
||||
<iframe :src="iframeUrl" class="h-[600px] w-full" />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -155,7 +155,7 @@ function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<WorkflowCategorySearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard title="流程分类列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="流程分类列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -226,7 +226,7 @@ function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<LeaveSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="请假申请列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="请假申请列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -410,7 +410,7 @@ const selectable = computed(() => {
|
||||
</template>
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<DefinitionSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header>
|
||||
<NSpace>
|
||||
<NRadioGroup v-model:value="isPublish" on-up size="small">
|
||||
|
@ -365,7 +365,7 @@ async function handlePreview(row: Api.Workflow.ProcessInstance) {
|
||||
</template>
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<ProcessInstanceSearch v-model:model="searchParams" @reset="handleResetSearch" @search="getDataByPage" />
|
||||
<NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header>
|
||||
<NSpace>
|
||||
<NRadioGroup v-model:value="runningStatus" on-up size="small">
|
||||
|
@ -30,8 +30,6 @@ const { bool: viewVisible, setTrue: showViewDrawer } = useBoolean();
|
||||
const { bool: interveneVisible, setTrue: showInterveneDrawer } = useBoolean();
|
||||
const dynamicComponent = shallowRef();
|
||||
|
||||
type Task = Api.Workflow.Task;
|
||||
|
||||
const waitingStatus = ref<boolean>(true);
|
||||
const waitingStatusOptions = ref<WaitingStatusOption[]>([
|
||||
{ label: '待办任务', value: true },
|
||||
@ -123,7 +121,7 @@ const operateColumns = ref<NaiveUI.TableColumn<Api.Workflow.TaskOrHisTask>[]>([
|
||||
type="info"
|
||||
icon="material-symbols:edit-document"
|
||||
tooltipContent="流程干预"
|
||||
onClick={() => handleIntervene(row)}
|
||||
onClick={() => handleIntervene(row as Api.Workflow.Task)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -222,9 +220,13 @@ async function handleView(row: Api.Workflow.TaskOrHisTask) {
|
||||
}
|
||||
}
|
||||
|
||||
const interveneRowData = ref<Api.Workflow.TaskOrHisTask>();
|
||||
function handleIntervene(row: Api.Workflow.TaskOrHisTask) {
|
||||
interveneRowData.value = row;
|
||||
const taskId = ref<CommonType.IdType>('');
|
||||
const assigneeIds = ref<CommonType.IdType[]>([]);
|
||||
const assigneeNames = ref<string[]>([]);
|
||||
function handleIntervene(row: Api.Workflow.Task) {
|
||||
taskId.value = row.id;
|
||||
assigneeIds.value = row.assigneeIds?.split(',') || [];
|
||||
assigneeNames.value = row.assigneeNames?.split(',') || [];
|
||||
showInterveneDrawer();
|
||||
}
|
||||
</script>
|
||||
@ -264,7 +266,7 @@ function handleIntervene(row: Api.Workflow.TaskOrHisTask) {
|
||||
</template>
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<AllTaskWaitingSearch v-model:model="searchParams" @reset="handleResetSearch" @search="getDataByPage" />
|
||||
<NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header>
|
||||
<NSpace>
|
||||
<NRadioGroup v-model:value="waitingStatus" on-up size="small">
|
||||
@ -306,7 +308,9 @@ function handleIntervene(row: Api.Workflow.TaskOrHisTask) {
|
||||
<component :is="dynamicComponent" :visible="viewVisible" operate-type="detail" :business-id="businessId" />
|
||||
<FlowInterveneModal
|
||||
v-model:visible="interveneVisible"
|
||||
:row-data="interveneRowData as Task"
|
||||
:task-id="taskId"
|
||||
:assignee-ids="assigneeIds"
|
||||
:assignee-names="assigneeNames"
|
||||
@refresh="getData"
|
||||
/>
|
||||
</NCard>
|
||||
|
Loading…
Reference in New Issue
Block a user