refactor: 重构审批详情footer及相关代码 移除之前iframe方案过时代码
新增 `FlowActions` 审批操作按钮组件,统一处理我的申请、审批、管理员等不同场景下的操作逻辑。 重构 `ApprovalPanel` 组件,将操作按钮抽离为独立组件,简化原有代码结构。 移除了 `ApprovalDetails` 中冗余的 iframe 高度控制属性。 优化 `FlowPreview` 组件,调整 iframe 样式并增强主题切换时与子页面的通信逻辑。 新增 `ApprovalType` 类型定义文件,明确各审批场景类型。
This commit is contained in:
parent
ab756b3434
commit
9b59a8acdb
@ -0,0 +1,420 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { ApprovalType } from '../type';
|
||||||
|
|
||||||
|
import type { User } from '#/api/core/user';
|
||||||
|
import type { TaskInfo } from '#/api/workflow/task/model';
|
||||||
|
|
||||||
|
import { computed, h } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { cn, getPopupContainer } from '@vben/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ArrowLeftOutlined,
|
||||||
|
CheckOutlined,
|
||||||
|
EditOutlined,
|
||||||
|
ExclamationCircleOutlined,
|
||||||
|
MenuOutlined,
|
||||||
|
RollbackOutlined,
|
||||||
|
UsergroupAddOutlined,
|
||||||
|
UsergroupDeleteOutlined,
|
||||||
|
UserOutlined,
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
import { Dropdown, Menu, MenuItem, Modal, Space } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
cancelProcessApply,
|
||||||
|
deleteByInstanceIds,
|
||||||
|
} from '#/api/workflow/instance';
|
||||||
|
import {
|
||||||
|
taskOperation,
|
||||||
|
terminationTask,
|
||||||
|
updateAssignee,
|
||||||
|
} from '#/api/workflow/task';
|
||||||
|
|
||||||
|
import { approvalModal, approvalRejectionModal, flowInterfereModal } from '..';
|
||||||
|
import { approveWithReasonModal } from '../helper';
|
||||||
|
import userSelectModal from '../user-select-modal.vue';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* 行数据的taskInfo?
|
||||||
|
*/
|
||||||
|
task?: TaskInfo;
|
||||||
|
/**
|
||||||
|
* 审批类型 根据不同类型显示按钮
|
||||||
|
*/
|
||||||
|
type: ApprovalType;
|
||||||
|
/**
|
||||||
|
* 为审批类型时候 显示的按钮(按钮权限)
|
||||||
|
*/
|
||||||
|
buttonPermissions: Record<string, boolean>;
|
||||||
|
}
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
reload: [];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 是否显示 `其他` 按钮
|
||||||
|
const showButtonOther = computed(() => {
|
||||||
|
const moreCollections = new Set(['addSign', 'subSign', 'transfer', 'trust']);
|
||||||
|
return Object.keys(props.buttonPermissions).some(
|
||||||
|
(key) => moreCollections.has(key) && props.buttonPermissions[key],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 进行中 可以撤销
|
||||||
|
const revocable = computed(() => props.task?.flowStatus === 'waiting');
|
||||||
|
async function handleCancel() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要撤销该申请吗?',
|
||||||
|
centered: true,
|
||||||
|
okButtonProps: { danger: true },
|
||||||
|
onOk: async () => {
|
||||||
|
await cancelProcessApply({
|
||||||
|
businessId: props.task!.businessId,
|
||||||
|
message: '申请人撤销流程!',
|
||||||
|
});
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可编辑/删除
|
||||||
|
*/
|
||||||
|
const editableAndRemoveable = computed(() => {
|
||||||
|
if (!props.task) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ['back', 'cancel', 'draft'].includes(props.task.flowStatus);
|
||||||
|
});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
function handleEdit() {
|
||||||
|
const path = props.task?.formPath;
|
||||||
|
if (path) {
|
||||||
|
router.push({ path, query: { id: props.task!.businessId } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRemove() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定删除该申请吗?',
|
||||||
|
centered: true,
|
||||||
|
okButtonProps: { danger: true },
|
||||||
|
onOk: async () => {
|
||||||
|
await deleteByInstanceIds([props.task!.id]);
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批驳回
|
||||||
|
*/
|
||||||
|
const [RejectionModal, rejectionModalApi] = useVbenModal({
|
||||||
|
connectedComponent: approvalRejectionModal,
|
||||||
|
});
|
||||||
|
function handleRejection() {
|
||||||
|
rejectionModalApi.setData({
|
||||||
|
taskId: props.task?.id,
|
||||||
|
definitionId: props.task?.definitionId,
|
||||||
|
nodeCode: props.task?.nodeCode,
|
||||||
|
});
|
||||||
|
rejectionModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批终止
|
||||||
|
*/
|
||||||
|
function handleTermination() {
|
||||||
|
approveWithReasonModal({
|
||||||
|
title: '审批终止',
|
||||||
|
description: '确定终止当前审批流程吗?',
|
||||||
|
onOk: async (reason) => {
|
||||||
|
await terminationTask({ taskId: props.task!.id, comment: reason });
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批通过
|
||||||
|
*/
|
||||||
|
const [ApprovalModal, approvalModalApi] = useVbenModal({
|
||||||
|
connectedComponent: approvalModal,
|
||||||
|
});
|
||||||
|
function handleApproval() {
|
||||||
|
const { buttonPermissions } = props;
|
||||||
|
// 是否具有抄送权限
|
||||||
|
const copyPermission = buttonPermissions?.copy ?? false;
|
||||||
|
// 是否具有选人权限
|
||||||
|
const assignPermission = buttonPermissions?.pop ?? false;
|
||||||
|
approvalModalApi.setData({
|
||||||
|
taskId: props.task?.id,
|
||||||
|
copyPermission,
|
||||||
|
assignPermission,
|
||||||
|
});
|
||||||
|
approvalModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 委托
|
||||||
|
*/
|
||||||
|
const [DelegationModal, delegationModalApi] = useVbenModal({
|
||||||
|
connectedComponent: userSelectModal,
|
||||||
|
});
|
||||||
|
function handleDelegation(userList: User[]) {
|
||||||
|
if (userList.length === 0) return;
|
||||||
|
const current = userList[0];
|
||||||
|
approveWithReasonModal({
|
||||||
|
title: '委托',
|
||||||
|
description: `确定委托给[${current?.nickName}]吗?`,
|
||||||
|
onOk: async (reason) => {
|
||||||
|
await taskOperation(
|
||||||
|
{ taskId: props.task!.id, userId: current!.userId, message: reason },
|
||||||
|
'delegateTask',
|
||||||
|
);
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转办
|
||||||
|
*/
|
||||||
|
const [TransferModal, transferModalApi] = useVbenModal({
|
||||||
|
connectedComponent: userSelectModal,
|
||||||
|
});
|
||||||
|
function handleTransfer(userList: User[]) {
|
||||||
|
if (userList.length === 0) return;
|
||||||
|
const current = userList[0];
|
||||||
|
approveWithReasonModal({
|
||||||
|
title: '转办',
|
||||||
|
description: `确定转办给[${current?.nickName}]吗?`,
|
||||||
|
onOk: async (reason) => {
|
||||||
|
await taskOperation(
|
||||||
|
{ taskId: props.task!.id, userId: current!.userId, message: reason },
|
||||||
|
'transferTask',
|
||||||
|
);
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const [AddSignatureModal, addSignatureModalApi] = useVbenModal({
|
||||||
|
connectedComponent: userSelectModal,
|
||||||
|
});
|
||||||
|
function handleAddSignature(userList: User[]) {
|
||||||
|
if (userList.length === 0) return;
|
||||||
|
const userIds = userList.map((user) => user.userId);
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确认加签吗?',
|
||||||
|
centered: true,
|
||||||
|
onOk: async () => {
|
||||||
|
await taskOperation({ taskId: props.task!.id, userIds }, 'addSignature');
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const [ReductionSignatureModal, reductionSignatureModalApi] = useVbenModal({
|
||||||
|
connectedComponent: userSelectModal,
|
||||||
|
});
|
||||||
|
function handleReductionSignature(userList: User[]) {
|
||||||
|
if (userList.length === 0) return;
|
||||||
|
const userIds = userList.map((user) => user.userId);
|
||||||
|
Modal.confirm({
|
||||||
|
title: '提示',
|
||||||
|
content: '确认减签吗?',
|
||||||
|
centered: true,
|
||||||
|
onOk: async () => {
|
||||||
|
await taskOperation(
|
||||||
|
{ taskId: props.task!.id, userIds },
|
||||||
|
'reductionSignature',
|
||||||
|
);
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 流程干预
|
||||||
|
const [FlowInterfereModal, flowInterfereModalApi] = useVbenModal({
|
||||||
|
connectedComponent: flowInterfereModal,
|
||||||
|
});
|
||||||
|
function handleFlowInterfere() {
|
||||||
|
flowInterfereModalApi.setData({ taskId: props.task?.id });
|
||||||
|
flowInterfereModalApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改办理人
|
||||||
|
const [UpdateAssigneeModal, updateAssigneeModalApi] = useVbenModal({
|
||||||
|
connectedComponent: userSelectModal,
|
||||||
|
});
|
||||||
|
function handleUpdateAssignee(userList: User[]) {
|
||||||
|
if (userList.length === 0) return;
|
||||||
|
const current = userList[0];
|
||||||
|
if (!current) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: '修改办理人',
|
||||||
|
content: `确定修改办理人为${current?.nickName}吗?`,
|
||||||
|
centered: true,
|
||||||
|
onOk: async () => {
|
||||||
|
await updateAssignee([props.task!.id], current.userId);
|
||||||
|
emit('reload');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示 加签/减签操作
|
||||||
|
*/
|
||||||
|
const showMultiActions = computed(() => {
|
||||||
|
if (!props.task) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Number(props.task.nodeRatio) > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:class="
|
||||||
|
cn(
|
||||||
|
'absolute bottom-0 left-0',
|
||||||
|
'border-t-solid border-t-[1px]',
|
||||||
|
'bg-background w-full p-3',
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<Space v-if="type === 'myself'">
|
||||||
|
<a-button
|
||||||
|
v-if="revocable"
|
||||||
|
danger
|
||||||
|
ghost
|
||||||
|
type="primary"
|
||||||
|
:icon="h(RollbackOutlined)"
|
||||||
|
@click="handleCancel"
|
||||||
|
>
|
||||||
|
撤销申请
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
ghost
|
||||||
|
v-if="editableAndRemoveable"
|
||||||
|
:icon="h(EditOutlined)"
|
||||||
|
@click="handleEdit"
|
||||||
|
>
|
||||||
|
重新编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="editableAndRemoveable"
|
||||||
|
danger
|
||||||
|
ghost
|
||||||
|
type="primary"
|
||||||
|
:icon="h(EditOutlined)"
|
||||||
|
@click="handleRemove"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
|
</Space>
|
||||||
|
<Space v-if="type === 'approve'">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
ghost
|
||||||
|
:icon="h(CheckOutlined)"
|
||||||
|
@click="handleApproval"
|
||||||
|
>
|
||||||
|
通过
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="buttonPermissions?.termination"
|
||||||
|
danger
|
||||||
|
ghost
|
||||||
|
type="primary"
|
||||||
|
:icon="h(ExclamationCircleOutlined)"
|
||||||
|
@click="handleTermination"
|
||||||
|
>
|
||||||
|
终止
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="buttonPermissions?.back"
|
||||||
|
danger
|
||||||
|
ghost
|
||||||
|
type="primary"
|
||||||
|
:icon="h(ArrowLeftOutlined)"
|
||||||
|
@click="handleRejection"
|
||||||
|
>
|
||||||
|
驳回
|
||||||
|
</a-button>
|
||||||
|
<Dropdown
|
||||||
|
:get-popup-container="getPopupContainer"
|
||||||
|
placement="bottomRight"
|
||||||
|
>
|
||||||
|
<template #overlay>
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
v-if="buttonPermissions?.trust"
|
||||||
|
key="1"
|
||||||
|
@click="() => delegationModalApi.open()"
|
||||||
|
>
|
||||||
|
<UserOutlined class="mr-2" />委托
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
v-if="buttonPermissions?.transfer"
|
||||||
|
key="2"
|
||||||
|
@click="() => transferModalApi.open()"
|
||||||
|
>
|
||||||
|
<RollbackOutlined class="mr-2" /> 转办
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
v-if="showMultiActions && buttonPermissions?.addSign"
|
||||||
|
key="3"
|
||||||
|
@click="() => addSignatureModalApi.open()"
|
||||||
|
>
|
||||||
|
<UsergroupAddOutlined class="mr-2" /> 加签
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
v-if="showMultiActions && buttonPermissions?.subSign"
|
||||||
|
key="4"
|
||||||
|
@click="() => reductionSignatureModalApi.open()"
|
||||||
|
>
|
||||||
|
<UsergroupDeleteOutlined class="mr-2" /> 减签
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</template>
|
||||||
|
<a-button v-if="showButtonOther" :icon="h(MenuOutlined)">
|
||||||
|
其他
|
||||||
|
</a-button>
|
||||||
|
</Dropdown>
|
||||||
|
<ApprovalModal @complete="$emit('reload')" />
|
||||||
|
<RejectionModal @complete="$emit('reload')" />
|
||||||
|
<DelegationModal mode="single" @finish="handleDelegation" />
|
||||||
|
<TransferModal mode="single" @finish="handleTransfer" />
|
||||||
|
<AddSignatureModal mode="multiple" @finish="handleAddSignature" />
|
||||||
|
<ReductionSignatureModal
|
||||||
|
mode="multiple"
|
||||||
|
@finish="handleReductionSignature"
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
<Space v-if="type === 'admin'">
|
||||||
|
<a-button @click="handleFlowInterfere"> 流程干预 </a-button>
|
||||||
|
<a-button @click="() => updateAssigneeModalApi.open()">
|
||||||
|
修改办理人
|
||||||
|
</a-button>
|
||||||
|
<FlowInterfereModal @complete="$emit('reload')" />
|
||||||
|
<UpdateAssigneeModal mode="single" @finish="handleUpdateAssignee" />
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export { default as FlowActions } from './flow-actions.vue';
|
||||||
@ -20,8 +20,6 @@ defineOptions({
|
|||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
currentFlowInfo: FlowInfoResponse;
|
currentFlowInfo: FlowInfoResponse;
|
||||||
iframeHeight: number;
|
|
||||||
iframeLoaded: boolean;
|
|
||||||
task: TaskInfo;
|
task: TaskInfo;
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,87 +1,52 @@
|
|||||||
<!-- 该文件需要重构 但我没空 -->
|
<!-- 该文件需要重构 但我没空 -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { User } from '#/api/core/user';
|
import type { ApprovalType } from './type';
|
||||||
|
|
||||||
import type { FlowInfoResponse } from '#/api/workflow/instance/model';
|
import type { FlowInfoResponse } from '#/api/workflow/instance/model';
|
||||||
import type { TaskInfo } from '#/api/workflow/task/model';
|
import type { TaskInfo } from '#/api/workflow/task/model';
|
||||||
|
|
||||||
import { computed, h, onUnmounted, ref, watch } from 'vue';
|
import { computed, onUnmounted, ref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import { Fallback, useVbenModal, VbenAvatar } from '@vben/common-ui';
|
import { Fallback, VbenAvatar } from '@vben/common-ui';
|
||||||
import { DictEnum } from '@vben/constants';
|
import { DictEnum } from '@vben/constants';
|
||||||
import { cn, getPopupContainer } from '@vben/utils';
|
import { cn } from '@vben/utils';
|
||||||
|
|
||||||
import {
|
import { CopyOutlined } from '@ant-design/icons-vue';
|
||||||
ArrowLeftOutlined,
|
import { useClipboard } from '@vueuse/core';
|
||||||
CheckOutlined,
|
import { Card, Divider, message, TabPane, Tabs } from 'ant-design-vue';
|
||||||
CopyOutlined,
|
|
||||||
EditOutlined,
|
|
||||||
ExclamationCircleOutlined,
|
|
||||||
MenuOutlined,
|
|
||||||
RollbackOutlined,
|
|
||||||
UsergroupAddOutlined,
|
|
||||||
UsergroupDeleteOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
} from '@ant-design/icons-vue';
|
|
||||||
import { useClipboard, useEventListener } from '@vueuse/core';
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
Divider,
|
|
||||||
Dropdown,
|
|
||||||
Menu,
|
|
||||||
MenuItem,
|
|
||||||
message,
|
|
||||||
Modal,
|
|
||||||
Space,
|
|
||||||
TabPane,
|
|
||||||
Tabs,
|
|
||||||
} from 'ant-design-vue';
|
|
||||||
import { isObject } from 'lodash-es';
|
|
||||||
|
|
||||||
import {
|
import { flowInfo } from '#/api/workflow/instance';
|
||||||
cancelProcessApply,
|
import { getTaskByTaskId } from '#/api/workflow/task';
|
||||||
deleteByInstanceIds,
|
|
||||||
flowInfo,
|
|
||||||
} from '#/api/workflow/instance';
|
|
||||||
import {
|
|
||||||
getTaskByTaskId,
|
|
||||||
taskOperation,
|
|
||||||
terminationTask,
|
|
||||||
updateAssignee,
|
|
||||||
} from '#/api/workflow/task';
|
|
||||||
import { renderDict } from '#/utils/render';
|
import { renderDict } from '#/utils/render';
|
||||||
|
|
||||||
import { approvalModal, approvalRejectionModal, flowInterfereModal } from '.';
|
import { FlowActions } from './actions';
|
||||||
import ApprovalDetails from './approval-details.vue';
|
import ApprovalDetails from './approval-details.vue';
|
||||||
import FlowPreview from './flow-preview.vue';
|
import FlowPreview from './flow-preview.vue';
|
||||||
import { approveWithReasonModal } from './helper';
|
|
||||||
import userSelectModal from './user-select-modal.vue';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'ApprovalPanel',
|
name: 'ApprovalPanel',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = defineProps<{ task?: TaskInfo; type: ApprovalType }>();
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下面按钮点击后会触发的事件
|
* 下面按钮点击后会触发的事件
|
||||||
*/
|
*/
|
||||||
const emit = defineEmits<{ reload: [] }>();
|
defineEmits<{ reload: [] }>();
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* 行数据(list)的info
|
||||||
|
*/
|
||||||
|
task?: TaskInfo;
|
||||||
|
/**
|
||||||
|
* 审批类型
|
||||||
|
*/
|
||||||
|
type: ApprovalType;
|
||||||
|
}
|
||||||
|
|
||||||
const currentTask = ref<TaskInfo>();
|
const currentTask = ref<TaskInfo>();
|
||||||
/**
|
|
||||||
* 是否显示 加签/减签操作
|
|
||||||
*/
|
|
||||||
const showMultiActions = computed(() => {
|
|
||||||
if (!currentTask.value) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Number(currentTask.value.nodeRatio) > 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按钮权限
|
* 按钮权限
|
||||||
@ -97,21 +62,6 @@ const buttonPermissions = computed(() => {
|
|||||||
return record;
|
return record;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 是否显示 `其他` 按钮
|
|
||||||
const showButtonOther = computed(() => {
|
|
||||||
const moreCollections = new Set(['addSign', 'subSign', 'transfer', 'trust']);
|
|
||||||
return Object.keys(buttonPermissions.value).some(
|
|
||||||
(key) => moreCollections.has(key) && buttonPermissions.value[key],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* myself 我发起的
|
|
||||||
* readonly 只读 只用于查看
|
|
||||||
* approve 审批
|
|
||||||
* admin 流程监控 - 待办任务使用
|
|
||||||
*/
|
|
||||||
type ApprovalType = 'admin' | 'approve' | 'myself' | 'readonly';
|
|
||||||
const showFooter = computed(() => {
|
const showFooter = computed(() => {
|
||||||
if (props.type === 'readonly') {
|
if (props.type === 'readonly') {
|
||||||
return false;
|
return false;
|
||||||
@ -131,35 +81,20 @@ const currentFlowInfo = ref<FlowInfoResponse>();
|
|||||||
* card的loading状态
|
* card的loading状态
|
||||||
*/
|
*/
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const iframeLoaded = ref(false);
|
|
||||||
const iframeHeight = ref(300);
|
|
||||||
useEventListener('message', (event) => {
|
|
||||||
const data = event.data as { [key: string]: any; type: string };
|
|
||||||
if (!isObject(data)) return;
|
|
||||||
/**
|
|
||||||
* iframe通信 加载完毕后才显示表单 解决卡顿问题
|
|
||||||
*/
|
|
||||||
if (data.type === 'mounted') {
|
|
||||||
iframeLoaded.value = true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 高度与表单高度保持一致
|
|
||||||
*/
|
|
||||||
if (data.type === 'height') {
|
|
||||||
const height = data.height;
|
|
||||||
iframeHeight.value = height;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleLoadInfo(task: TaskInfo | undefined) {
|
async function handleLoadInfo(task: TaskInfo | undefined) {
|
||||||
try {
|
try {
|
||||||
if (!task) return null;
|
if (!task) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
iframeLoaded.value = false;
|
|
||||||
const resp = await flowInfo(task.businessId);
|
|
||||||
currentFlowInfo.value = resp;
|
|
||||||
|
|
||||||
const taskResp = await getTaskByTaskId(props.task!.id);
|
const [flowResp, taskResp] = await Promise.all([
|
||||||
|
flowInfo(task.businessId),
|
||||||
|
getTaskByTaskId(task.id),
|
||||||
|
]);
|
||||||
|
|
||||||
|
currentFlowInfo.value = flowResp;
|
||||||
currentTask.value = taskResp;
|
currentTask.value = taskResp;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -172,215 +107,6 @@ watch(() => props.task, handleLoadInfo);
|
|||||||
|
|
||||||
onUnmounted(() => (currentFlowInfo.value = undefined));
|
onUnmounted(() => (currentFlowInfo.value = undefined));
|
||||||
|
|
||||||
// 进行中 可以撤销
|
|
||||||
const revocable = computed(() => props.task?.flowStatus === 'waiting');
|
|
||||||
async function handleCancel() {
|
|
||||||
Modal.confirm({
|
|
||||||
title: '提示',
|
|
||||||
content: '确定要撤销该申请吗?',
|
|
||||||
centered: true,
|
|
||||||
okButtonProps: { danger: true },
|
|
||||||
onOk: async () => {
|
|
||||||
await cancelProcessApply({
|
|
||||||
businessId: props.task!.businessId,
|
|
||||||
message: '申请人撤销流程!',
|
|
||||||
});
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否可编辑/删除
|
|
||||||
*/
|
|
||||||
const editableAndRemoveable = computed(() => {
|
|
||||||
if (!props.task) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ['back', 'cancel', 'draft'].includes(props.task.flowStatus);
|
|
||||||
});
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
function handleEdit() {
|
|
||||||
const path = props.task?.formPath;
|
|
||||||
if (path) {
|
|
||||||
router.push({ path, query: { id: props.task!.businessId } });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRemove() {
|
|
||||||
Modal.confirm({
|
|
||||||
title: '提示',
|
|
||||||
content: '确定删除该申请吗?',
|
|
||||||
centered: true,
|
|
||||||
okButtonProps: { danger: true },
|
|
||||||
onOk: async () => {
|
|
||||||
await deleteByInstanceIds([props.task!.id]);
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审批驳回
|
|
||||||
*/
|
|
||||||
const [RejectionModal, rejectionModalApi] = useVbenModal({
|
|
||||||
connectedComponent: approvalRejectionModal,
|
|
||||||
});
|
|
||||||
function handleRejection() {
|
|
||||||
rejectionModalApi.setData({
|
|
||||||
taskId: props.task?.id,
|
|
||||||
definitionId: props.task?.definitionId,
|
|
||||||
nodeCode: props.task?.nodeCode,
|
|
||||||
});
|
|
||||||
rejectionModalApi.open();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 审批终止
|
|
||||||
*/
|
|
||||||
function handleTermination() {
|
|
||||||
approveWithReasonModal({
|
|
||||||
title: '审批终止',
|
|
||||||
description: '确定终止当前审批流程吗?',
|
|
||||||
onOk: async (reason) => {
|
|
||||||
await terminationTask({ taskId: props.task!.id, comment: reason });
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审批通过
|
|
||||||
*/
|
|
||||||
const [ApprovalModal, approvalModalApi] = useVbenModal({
|
|
||||||
connectedComponent: approvalModal,
|
|
||||||
});
|
|
||||||
function handleApproval() {
|
|
||||||
// 是否具有抄送权限
|
|
||||||
const copyPermission = buttonPermissions.value?.copy ?? false;
|
|
||||||
// 是否具有选人权限
|
|
||||||
const assignPermission = buttonPermissions.value?.pop ?? false;
|
|
||||||
approvalModalApi.setData({
|
|
||||||
taskId: props.task?.id,
|
|
||||||
copyPermission,
|
|
||||||
assignPermission,
|
|
||||||
});
|
|
||||||
approvalModalApi.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: 1提取公共函数 2原版是可以填写意见的(message参数)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 委托
|
|
||||||
*/
|
|
||||||
const [DelegationModal, delegationModalApi] = useVbenModal({
|
|
||||||
connectedComponent: userSelectModal,
|
|
||||||
});
|
|
||||||
function handleDelegation(userList: User[]) {
|
|
||||||
if (userList.length === 0) return;
|
|
||||||
const current = userList[0];
|
|
||||||
approveWithReasonModal({
|
|
||||||
title: '委托',
|
|
||||||
description: `确定委托给[${current?.nickName}]吗?`,
|
|
||||||
onOk: async (reason) => {
|
|
||||||
await taskOperation(
|
|
||||||
{ taskId: props.task!.id, userId: current!.userId, message: reason },
|
|
||||||
'delegateTask',
|
|
||||||
);
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转办
|
|
||||||
*/
|
|
||||||
const [TransferModal, transferModalApi] = useVbenModal({
|
|
||||||
connectedComponent: userSelectModal,
|
|
||||||
});
|
|
||||||
function handleTransfer(userList: User[]) {
|
|
||||||
if (userList.length === 0) return;
|
|
||||||
const current = userList[0];
|
|
||||||
approveWithReasonModal({
|
|
||||||
title: '转办',
|
|
||||||
description: `确定转办给[${current?.nickName}]吗?`,
|
|
||||||
onOk: async (reason) => {
|
|
||||||
await taskOperation(
|
|
||||||
{ taskId: props.task!.id, userId: current!.userId, message: reason },
|
|
||||||
'transferTask',
|
|
||||||
);
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [AddSignatureModal, addSignatureModalApi] = useVbenModal({
|
|
||||||
connectedComponent: userSelectModal,
|
|
||||||
});
|
|
||||||
function handleAddSignature(userList: User[]) {
|
|
||||||
if (userList.length === 0) return;
|
|
||||||
const userIds = userList.map((user) => user.userId);
|
|
||||||
Modal.confirm({
|
|
||||||
title: '提示',
|
|
||||||
content: '确认加签吗?',
|
|
||||||
centered: true,
|
|
||||||
onOk: async () => {
|
|
||||||
await taskOperation({ taskId: props.task!.id, userIds }, 'addSignature');
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [ReductionSignatureModal, reductionSignatureModalApi] = useVbenModal({
|
|
||||||
connectedComponent: userSelectModal,
|
|
||||||
});
|
|
||||||
function handleReductionSignature(userList: User[]) {
|
|
||||||
if (userList.length === 0) return;
|
|
||||||
const userIds = userList.map((user) => user.userId);
|
|
||||||
Modal.confirm({
|
|
||||||
title: '提示',
|
|
||||||
content: '确认减签吗?',
|
|
||||||
centered: true,
|
|
||||||
onOk: async () => {
|
|
||||||
await taskOperation(
|
|
||||||
{ taskId: props.task!.id, userIds },
|
|
||||||
'reductionSignature',
|
|
||||||
);
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 流程干预
|
|
||||||
const [FlowInterfereModal, flowInterfereModalApi] = useVbenModal({
|
|
||||||
connectedComponent: flowInterfereModal,
|
|
||||||
});
|
|
||||||
function handleFlowInterfere() {
|
|
||||||
flowInterfereModalApi.setData({ taskId: props.task?.id });
|
|
||||||
flowInterfereModalApi.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改办理人
|
|
||||||
const [UpdateAssigneeModal, updateAssigneeModalApi] = useVbenModal({
|
|
||||||
connectedComponent: userSelectModal,
|
|
||||||
});
|
|
||||||
function handleUpdateAssignee(userList: User[]) {
|
|
||||||
if (userList.length === 0) return;
|
|
||||||
const current = userList[0];
|
|
||||||
if (!current) return;
|
|
||||||
Modal.confirm({
|
|
||||||
title: '修改办理人',
|
|
||||||
content: `确定修改办理人为${current?.nickName}吗?`,
|
|
||||||
centered: true,
|
|
||||||
onOk: async () => {
|
|
||||||
await updateAssignee([props.task!.id], current.userId);
|
|
||||||
emit('reload');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 不加legacy在本地开发没有问题
|
* 不加legacy在本地开发没有问题
|
||||||
* 打包后在一些设备会无法复制 使用legacy来保证兼容性
|
* 打包后在一些设备会无法复制 使用legacy来保证兼容性
|
||||||
@ -407,6 +133,7 @@ async function handleCopy(text: string) {
|
|||||||
<CopyOutlined class="cursor-pointer" @click="handleCopy(task.id)" />
|
<CopyOutlined class="cursor-pointer" @click="handleCopy(task.id)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a-button size="small" @click="() => handleLoadInfo(task)">
|
<a-button size="small" @click="() => handleLoadInfo(task)">
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
@ -414,6 +141,7 @@ async function handleCopy(text: string) {
|
|||||||
</div>
|
</div>
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="flex flex-col gap-5 p-4">
|
<div class="flex flex-col gap-5 p-4">
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
@ -426,19 +154,24 @@ async function handleCopy(text: string) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<VbenAvatar
|
<VbenAvatar
|
||||||
:alt="task?.createByName ?? ''"
|
:alt="task?.createByName ?? ''"
|
||||||
class="bg-primary size-[28px] rounded-full text-white"
|
class="bg-primary size-[28px] rounded-full text-white"
|
||||||
src=""
|
src=""
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span>{{ task.createByName }}</span>
|
<span>{{ task.createByName }}</span>
|
||||||
|
|
||||||
<div class="flex items-center opacity-50">
|
<div class="flex items-center opacity-50">
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<span class="icon-[bxs--category-alt] size-[16px]"></span>
|
<span class="icon-[bxs--category-alt] size-[16px]"></span>
|
||||||
流程分类: {{ task.categoryName }}
|
流程分类: {{ task.categoryName }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider type="vertical" />
|
<Divider type="vertical" />
|
||||||
|
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<span class="icon-[mdi--clock-outline] size-[16px]"></span>
|
<span class="icon-[mdi--clock-outline] size-[16px]"></span>
|
||||||
提交时间: {{ task.createTime }}
|
提交时间: {{ task.createTime }}
|
||||||
@ -446,154 +179,32 @@ async function handleCopy(text: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs v-if="currentFlowInfo" class="flex-1">
|
<Tabs v-if="currentFlowInfo" class="flex-1">
|
||||||
<TabPane key="1" tab="审批详情">
|
<TabPane key="1" tab="审批详情">
|
||||||
<ApprovalDetails
|
<ApprovalDetails
|
||||||
:current-flow-info="currentFlowInfo"
|
:current-flow-info="currentFlowInfo"
|
||||||
:iframe-loaded="iframeLoaded"
|
|
||||||
:iframe-height="iframeHeight"
|
|
||||||
:task="task"
|
:task="task"
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|
||||||
<TabPane key="2" tab="审批流程图">
|
<TabPane key="2" tab="审批流程图">
|
||||||
<FlowPreview :instance-id="currentFlowInfo.instanceId" />
|
<FlowPreview :instance-id="currentFlowInfo.instanceId" />
|
||||||
</TabPane>
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<!-- 固定底部 -->
|
|
||||||
|
<!-- 固定底部 占位高度 -->
|
||||||
<div class="h-[58px]"></div>
|
<div class="h-[58px]"></div>
|
||||||
<div
|
<FlowActions
|
||||||
v-if="showFooter"
|
v-if="showFooter"
|
||||||
:class="
|
:type="type"
|
||||||
cn(
|
:task="task"
|
||||||
'absolute bottom-0 left-0',
|
:button-permissions="buttonPermissions"
|
||||||
'border-t-solid border-t-[1px]',
|
@reload="$emit('reload')"
|
||||||
'bg-background w-full p-3',
|
/>
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="flex justify-end">
|
|
||||||
<Space v-if="type === 'myself'">
|
|
||||||
<a-button
|
|
||||||
v-if="revocable"
|
|
||||||
danger
|
|
||||||
ghost
|
|
||||||
type="primary"
|
|
||||||
:icon="h(RollbackOutlined)"
|
|
||||||
@click="handleCancel"
|
|
||||||
>
|
|
||||||
撤销申请
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
ghost
|
|
||||||
v-if="editableAndRemoveable"
|
|
||||||
:icon="h(EditOutlined)"
|
|
||||||
@click="handleEdit"
|
|
||||||
>
|
|
||||||
重新编辑
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
v-if="editableAndRemoveable"
|
|
||||||
danger
|
|
||||||
ghost
|
|
||||||
type="primary"
|
|
||||||
:icon="h(EditOutlined)"
|
|
||||||
@click="handleRemove"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</a-button>
|
|
||||||
</Space>
|
|
||||||
<Space v-if="type === 'approve'">
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
ghost
|
|
||||||
:icon="h(CheckOutlined)"
|
|
||||||
@click="handleApproval"
|
|
||||||
>
|
|
||||||
通过
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
v-if="buttonPermissions?.termination"
|
|
||||||
danger
|
|
||||||
ghost
|
|
||||||
type="primary"
|
|
||||||
:icon="h(ExclamationCircleOutlined)"
|
|
||||||
@click="handleTermination"
|
|
||||||
>
|
|
||||||
终止
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
|
||||||
v-if="buttonPermissions?.back"
|
|
||||||
danger
|
|
||||||
ghost
|
|
||||||
type="primary"
|
|
||||||
:icon="h(ArrowLeftOutlined)"
|
|
||||||
@click="handleRejection"
|
|
||||||
>
|
|
||||||
驳回
|
|
||||||
</a-button>
|
|
||||||
<Dropdown
|
|
||||||
:get-popup-container="getPopupContainer"
|
|
||||||
placement="bottomRight"
|
|
||||||
>
|
|
||||||
<template #overlay>
|
|
||||||
<Menu>
|
|
||||||
<MenuItem
|
|
||||||
v-if="buttonPermissions?.trust"
|
|
||||||
key="1"
|
|
||||||
@click="() => delegationModalApi.open()"
|
|
||||||
>
|
|
||||||
<UserOutlined class="mr-2" />委托
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
v-if="buttonPermissions?.transfer"
|
|
||||||
key="2"
|
|
||||||
@click="() => transferModalApi.open()"
|
|
||||||
>
|
|
||||||
<RollbackOutlined class="mr-2" /> 转办
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
v-if="showMultiActions && buttonPermissions?.addSign"
|
|
||||||
key="3"
|
|
||||||
@click="() => addSignatureModalApi.open()"
|
|
||||||
>
|
|
||||||
<UsergroupAddOutlined class="mr-2" /> 加签
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
v-if="showMultiActions && buttonPermissions?.subSign"
|
|
||||||
key="4"
|
|
||||||
@click="() => reductionSignatureModalApi.open()"
|
|
||||||
>
|
|
||||||
<UsergroupDeleteOutlined class="mr-2" /> 减签
|
|
||||||
</MenuItem>
|
|
||||||
</Menu>
|
|
||||||
</template>
|
|
||||||
<a-button v-if="showButtonOther" :icon="h(MenuOutlined)">
|
|
||||||
其他
|
|
||||||
</a-button>
|
|
||||||
</Dropdown>
|
|
||||||
<ApprovalModal @complete="$emit('reload')" />
|
|
||||||
<RejectionModal @complete="$emit('reload')" />
|
|
||||||
<DelegationModal mode="single" @finish="handleDelegation" />
|
|
||||||
<TransferModal mode="single" @finish="handleTransfer" />
|
|
||||||
<AddSignatureModal mode="multiple" @finish="handleAddSignature" />
|
|
||||||
<ReductionSignatureModal
|
|
||||||
mode="multiple"
|
|
||||||
@finish="handleReductionSignature"
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
<Space v-if="type === 'admin'">
|
|
||||||
<a-button @click="handleFlowInterfere"> 流程干预 </a-button>
|
|
||||||
<a-button @click="() => updateAssigneeModalApi.open()">
|
|
||||||
修改办理人
|
|
||||||
</a-button>
|
|
||||||
<FlowInterfereModal @complete="$emit('reload')" />
|
|
||||||
<UpdateAssigneeModal mode="single" @finish="handleUpdateAssignee" />
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<slot v-else name="empty">
|
<slot v-else name="empty">
|
||||||
<Fallback title="点击左侧选择" />
|
<Fallback title="点击左侧选择" />
|
||||||
</slot>
|
</slot>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
<!-- 流程图预览组件 -->
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAppConfig } from '@vben/hooks';
|
import { useAppConfig } from '@vben/hooks';
|
||||||
import { stringify } from '@vben/request';
|
import { stringify } from '@vben/request';
|
||||||
@ -7,7 +9,14 @@ import { useWarmflowIframe } from './hook';
|
|||||||
|
|
||||||
defineOptions({ name: 'FlowPreview' });
|
defineOptions({ name: 'FlowPreview' });
|
||||||
|
|
||||||
const props = defineProps<{ instanceId: string }>();
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* 流程实例ID
|
||||||
|
*/
|
||||||
|
instanceId: string;
|
||||||
|
}
|
||||||
|
|
||||||
const { clientId } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
const { clientId } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||||
|
|
||||||
@ -21,6 +30,7 @@ const params = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* iframe地址
|
* iframe地址
|
||||||
|
* 后端地址 + 固定flow地址拼接
|
||||||
*/
|
*/
|
||||||
const url = `${import.meta.env.VITE_GLOB_API_URL}/warm-flow-ui/index.html?${stringify(params)}`;
|
const url = `${import.meta.env.VITE_GLOB_API_URL}/warm-flow-ui/index.html?${stringify(params)}`;
|
||||||
|
|
||||||
@ -28,5 +38,9 @@ const { iframeRef } = useWarmflowIframe();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<iframe ref="iframeRef" :src="url" class="h-[500px] w-full border"></iframe>
|
<iframe
|
||||||
|
ref="iframeRef"
|
||||||
|
:src="url"
|
||||||
|
class="h-[600px] w-full rounded-[6px] border"
|
||||||
|
></iframe>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -10,20 +10,26 @@ export function useWarmflowIframe() {
|
|||||||
const iframeRef = useTemplateRef<HTMLIFrameElement>('iframeRef');
|
const iframeRef = useTemplateRef<HTMLIFrameElement>('iframeRef');
|
||||||
const { isDark } = usePreferences();
|
const { isDark } = usePreferences();
|
||||||
|
|
||||||
|
async function iframeLoadEvent() {
|
||||||
|
/**
|
||||||
|
* TODO: 这里可以优化 因为拿不到内部vue的mount状态
|
||||||
|
*/
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
const theme = isDark.value ? 'theme-dark' : 'theme-light';
|
||||||
|
iframeRef.value?.contentWindow?.postMessage({ type: theme });
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
/**
|
/**
|
||||||
* load只是iframe加载完 而非vue加载完
|
* load只是iframe加载完 而非vue加载完
|
||||||
*/
|
*/
|
||||||
iframeRef.value?.addEventListener('load', async () => {
|
iframeRef.value?.addEventListener('load', iframeLoadEvent);
|
||||||
/**
|
|
||||||
* TODO: 这里可以优化 因为拿不到内部vue的mount状态
|
|
||||||
*/
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
||||||
const theme = isDark.value ? 'theme-dark' : 'theme-light';
|
|
||||||
iframeRef.value?.contentWindow?.postMessage({ type: theme });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// onBeforeUnmount(() => {
|
||||||
|
// iframeRef.value?.removeEventListener('load', iframeLoadEvent);
|
||||||
|
// });
|
||||||
|
|
||||||
// 监听主题切换 通知iframe切换
|
// 监听主题切换 通知iframe切换
|
||||||
watch(isDark, (dark) => {
|
watch(isDark, (dark) => {
|
||||||
if (!iframeRef.value) {
|
if (!iframeRef.value) {
|
||||||
|
|||||||
8
apps/web-antd/src/views/workflow/components/type.d.ts
vendored
Normal file
8
apps/web-antd/src/views/workflow/components/type.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export {};
|
||||||
|
/**
|
||||||
|
* myself 我发起的
|
||||||
|
* readonly 只读 只用于查看
|
||||||
|
* approve 审批(我的待办)
|
||||||
|
* admin 流程监控 - 待办任务使用
|
||||||
|
*/
|
||||||
|
export type ApprovalType = 'admin' | 'approve' | 'myself' | 'readonly';
|
||||||
Loading…
Reference in New Issue
Block a user