feat: 选择下一步审批人权限
This commit is contained in:
parent
e78f4e984d
commit
6170da0870
@ -1,5 +1,6 @@
|
||||
import type {
|
||||
CompleteTaskReqData,
|
||||
NextNodeInfo,
|
||||
StartWorkFlowReqData,
|
||||
TaskInfo,
|
||||
TaskOperationData,
|
||||
@ -156,3 +157,16 @@ export function getBackTaskNode(definitionId: string, nodeCode: string) {
|
||||
export function currentTaskAllUser(taskId: ID) {
|
||||
return requestClient.get<any>(`/workflow/task/currentTaskAllUser/${taskId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下一节点
|
||||
* @param data data
|
||||
* @param data.taskId taskId
|
||||
* @returns NextNodeInfo
|
||||
*/
|
||||
export function getNextNodeList(data: { taskId: string }) {
|
||||
return requestClient.post<NextNodeInfo[]>(
|
||||
'/workflow/task/getNextNodeList',
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
27
apps/web-antd/src/api/workflow/task/model.d.ts
vendored
27
apps/web-antd/src/api/workflow/task/model.d.ts
vendored
@ -45,6 +45,8 @@ export interface CompleteTaskReqData {
|
||||
variables: any;
|
||||
// 附件ID 1,2,3,4形式
|
||||
fileId?: string;
|
||||
// 选人 key为节点code value为用户ID join(,)
|
||||
assigneeMap: { [key: string]: string };
|
||||
}
|
||||
|
||||
export interface StartWorkFlowReqData {
|
||||
@ -79,3 +81,28 @@ export type TaskOperationType =
|
||||
| 'delegateTask'
|
||||
| 'reductionSignature'
|
||||
| 'transferTask';
|
||||
|
||||
export interface NextNodeInfo {
|
||||
skipList: string[];
|
||||
id: string;
|
||||
createTime: string;
|
||||
updateTime: string;
|
||||
tenantId: string;
|
||||
delFlag: string;
|
||||
nodeType: number;
|
||||
definitionId: string;
|
||||
nodeCode: string;
|
||||
nodeName: string;
|
||||
permissionFlag: string;
|
||||
nodeRatio: string;
|
||||
coordinate: string;
|
||||
version: string;
|
||||
anyNodeSkip: any;
|
||||
listenerType: any;
|
||||
listenerPath: any;
|
||||
handlerType: any;
|
||||
handlerPath: any;
|
||||
formCustom: string;
|
||||
formPath: any;
|
||||
ext: string;
|
||||
}
|
||||
|
@ -1,14 +1,21 @@
|
||||
<!-- 审批同意的弹窗 -->
|
||||
<script setup lang="ts">
|
||||
import type { CompleteTaskReqData } from '#/api/workflow/task/model';
|
||||
import type { User } from '#/api/system/user/model';
|
||||
import type {
|
||||
CompleteTaskReqData,
|
||||
NextNodeInfo,
|
||||
} from '#/api/workflow/task/model';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { cloneDeep } from '@vben/utils';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { omit } from 'lodash-es';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { completeTask } from '#/api/workflow/task';
|
||||
import { completeTask, getNextNodeList } from '#/api/workflow/task';
|
||||
|
||||
import { CopyComponent } from '.';
|
||||
|
||||
@ -77,6 +84,11 @@ const [BasicForm, formApi] = useVbenForm({
|
||||
defaultValue: [],
|
||||
label: '抄送人',
|
||||
},
|
||||
{
|
||||
fieldName: 'assigneeMap',
|
||||
component: 'Input',
|
||||
label: '下一步审批人',
|
||||
},
|
||||
{
|
||||
fieldName: 'message',
|
||||
component: 'Textarea',
|
||||
@ -92,8 +104,12 @@ interface ModalProps {
|
||||
taskId: string;
|
||||
// 是否具有抄送权限
|
||||
copyPermission: boolean;
|
||||
// 是有具有选人权限
|
||||
assignPermission: boolean;
|
||||
}
|
||||
|
||||
// 自定义添加选人属性 给组件v-for绑定
|
||||
const nextNodeInfo = ref<(NextNodeInfo & { selectUserList: User[] })[]>([]);
|
||||
const [BasicModal, modalApi] = useVbenModal({
|
||||
title: '审批通过',
|
||||
fullscreenButton: false,
|
||||
@ -106,18 +122,36 @@ const [BasicModal, modalApi] = useVbenModal({
|
||||
}
|
||||
modalApi.modalLoading(true);
|
||||
|
||||
const { taskId, copyPermission } = modalApi.getData() as ModalProps;
|
||||
const { taskId, copyPermission, assignPermission } =
|
||||
modalApi.getData() as ModalProps;
|
||||
// 是否显示抄送选择
|
||||
formApi.updateSchema([
|
||||
{
|
||||
fieldName: 'flowCopyList',
|
||||
dependencies: {
|
||||
show: copyPermission,
|
||||
if: copyPermission,
|
||||
triggerFields: [''],
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'assigneeMap',
|
||||
dependencies: {
|
||||
if: assignPermission,
|
||||
triggerFields: [''],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// 获取下一节点名称
|
||||
if (assignPermission) {
|
||||
const resp = await getNextNodeList({ taskId });
|
||||
nextNodeInfo.value = resp.map((item) => ({
|
||||
...item,
|
||||
// 用于给组件绑定
|
||||
selectUserList: [],
|
||||
}));
|
||||
}
|
||||
|
||||
await formApi.setFieldValue('taskId', taskId);
|
||||
|
||||
modalApi.modalLoading(false);
|
||||
@ -144,6 +178,26 @@ async function handleSubmit() {
|
||||
variables: {},
|
||||
flowCopyList,
|
||||
} as CompleteTaskReqData;
|
||||
|
||||
// 选人
|
||||
if (modalApi.getData()?.assignPermission) {
|
||||
// 判断是否选中
|
||||
for (const item of nextNodeInfo.value) {
|
||||
if (item.selectUserList.length === 0) {
|
||||
message.warn(`未选择节点[${item.nodeName}]审批人`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const assigneeMap: { [key: string]: string } = {};
|
||||
nextNodeInfo.value.forEach((item) => {
|
||||
assigneeMap[item.nodeCode] = item.selectUserList
|
||||
.map((u) => u.userId)
|
||||
.join(',');
|
||||
});
|
||||
requestData.assigneeMap = assigneeMap;
|
||||
}
|
||||
|
||||
await completeTask(requestData);
|
||||
modalApi.close();
|
||||
emit('complete');
|
||||
@ -161,6 +215,24 @@ async function handleSubmit() {
|
||||
<template #flowCopyList="slotProps">
|
||||
<CopyComponent v-model:user-list="slotProps.modelValue" />
|
||||
</template>
|
||||
<template #assigneeMap>
|
||||
<div
|
||||
v-for="item in nextNodeInfo"
|
||||
:key="item.nodeCode"
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<template v-if="item.permissionFlag">
|
||||
<span class="opacity-70">{{ item.nodeName }}</span>
|
||||
<CopyComponent
|
||||
:allow-user-ids="item.permissionFlag"
|
||||
v-model:user-list="item.selectUserList"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-red-500">没有权限, 请联系管理员</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
@ -256,7 +256,13 @@ const [ApprovalModal, approvalModalApi] = useVbenModal({
|
||||
function handleApproval() {
|
||||
// 是否具有抄送权限
|
||||
const copyPermission = buttonPermissions.value?.copy ?? false;
|
||||
approvalModalApi.setData({ taskId: props.task?.id, copyPermission });
|
||||
// 是否具有选人权限
|
||||
const assignPermission = buttonPermissions.value?.pop ?? false;
|
||||
approvalModalApi.setData({
|
||||
taskId: props.task?.id,
|
||||
copyPermission,
|
||||
assignPermission,
|
||||
});
|
||||
approvalModalApi.open();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
<!--抄送组件-->
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
import type { User } from '#/api/system/user/model';
|
||||
|
||||
import { computed, type PropType } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal, VbenAvatar } from '@vben/common-ui';
|
||||
|
||||
@ -15,12 +17,19 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<{ ellipseNumber?: number }>(), {
|
||||
/**
|
||||
* 最大显示的头像数量 超过显示为省略号头像
|
||||
*/
|
||||
ellipseNumber: 3,
|
||||
});
|
||||
const props = withDefaults(
|
||||
defineProps<{ allowUserIds?: string; ellipseNumber?: number }>(),
|
||||
{
|
||||
/**
|
||||
* 最大显示的头像数量 超过显示为省略号头像
|
||||
*/
|
||||
ellipseNumber: 3,
|
||||
/**
|
||||
* 允许选择允许选择的人员ID 会当做参数拼接在uselist接口
|
||||
*/
|
||||
allowUserIds: '',
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{ cancel: []; finish: [User[]] }>();
|
||||
|
||||
@ -80,6 +89,10 @@ const displayedList = computed(() => {
|
||||
</Tooltip>
|
||||
</AvatarGroup>
|
||||
<a-button size="small" @click="handleOpen">选择人员</a-button>
|
||||
<UserSelectModal @cancel="$emit('cancel')" @finish="handleFinish" />
|
||||
<UserSelectModal
|
||||
:allow-user-ids="allowUserIds"
|
||||
@cancel="$emit('cancel')"
|
||||
@finish="handleFinish"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -18,9 +18,16 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<{ mode?: 'multiple' | 'single' }>(), {
|
||||
mode: 'multiple',
|
||||
});
|
||||
const props = withDefaults(
|
||||
defineProps<{ allowUserIds?: string; mode?: 'multiple' | 'single' }>(),
|
||||
{
|
||||
mode: 'multiple',
|
||||
/**
|
||||
* 允许选择允许选择的人员ID 会当做参数拼接在uselist接口
|
||||
*/
|
||||
allowUserIds: '',
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
/**
|
||||
@ -136,11 +143,17 @@ const gridOptions: VxeGridProps = {
|
||||
}
|
||||
}
|
||||
|
||||
return await userList({
|
||||
const params: any = {
|
||||
pageNum: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
});
|
||||
};
|
||||
// 添加参数
|
||||
if (props.allowUserIds) {
|
||||
params.userIds = props.allowUserIds;
|
||||
}
|
||||
|
||||
return await userList(params);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -27,7 +27,7 @@ import { ApprovalCard, ApprovalPanel } from '../components';
|
||||
|
||||
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
|
||||
const taskList = ref<(TaskInfo & { active: boolean })[]>([]);
|
||||
const taskTotal = ref(0);
|
||||
const page = ref(1);
|
||||
const loading = ref(false);
|
||||
|
@ -29,7 +29,7 @@ import { ApprovalCard, ApprovalPanel, CopyComponent } from '../components';
|
||||
|
||||
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
|
||||
const taskList = ref<(TaskInfo & { active: boolean })[]>([]);
|
||||
const taskTotal = ref(0);
|
||||
const page = ref(1);
|
||||
const loading = ref(false);
|
||||
|
@ -29,7 +29,7 @@ import { ApprovalCard, ApprovalPanel, CopyComponent } from '../components';
|
||||
|
||||
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
|
||||
const taskList = ref<(TaskInfo & { active: boolean })[]>([]);
|
||||
const taskTotal = ref(0);
|
||||
const page = ref(1);
|
||||
const loading = ref(false);
|
||||
|
@ -30,7 +30,7 @@ import { ApprovalCard, ApprovalPanel, CopyComponent } from '../components';
|
||||
|
||||
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
|
||||
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
|
||||
const taskList = ref<(TaskInfo & { active: boolean })[]>([]);
|
||||
const taskTotal = ref(0);
|
||||
const page = ref(1);
|
||||
const loading = ref(false);
|
||||
|
Loading…
Reference in New Issue
Block a user