Pre Merge pull request !168 from Jason/dev
commit
fccbf91d68
|
@ -35,7 +35,7 @@ export namespace BpmProcessInstanceApi {
|
||||||
candidateStrategy?: BpmCandidateStrategyEnum;
|
candidateStrategy?: BpmCandidateStrategyEnum;
|
||||||
candidateUsers?: User[];
|
candidateUsers?: User[];
|
||||||
endTime?: Date;
|
endTime?: Date;
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
nodeType: BpmNodeTypeEnum;
|
nodeType: BpmNodeTypeEnum;
|
||||||
startTime?: Date;
|
startTime?: Date;
|
||||||
|
|
|
@ -186,6 +186,12 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildSelect = () => {
|
const buildSelect = () => {
|
||||||
|
const {
|
||||||
|
modelValue,
|
||||||
|
'onUpdate:modelValue': onUpdateModelValue,
|
||||||
|
...restAttrs
|
||||||
|
} = attrs;
|
||||||
|
|
||||||
if (props.multiple) {
|
if (props.multiple) {
|
||||||
// fix:多写此步是为了解决 multiple 属性问题
|
// fix:多写此步是为了解决 multiple 属性问题
|
||||||
return (
|
return (
|
||||||
|
@ -193,7 +199,9 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
class="w-full"
|
class="w-full"
|
||||||
loading={loading.value}
|
loading={loading.value}
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
{...attrs}
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
|
value={modelValue as any}
|
||||||
|
{...restAttrs}
|
||||||
// TODO: remote 对等实现
|
// TODO: remote 对等实现
|
||||||
// remote={props.remote}
|
// remote={props.remote}
|
||||||
{...(props.remote && { remoteMethod })}
|
{...(props.remote && { remoteMethod })}
|
||||||
|
@ -212,7 +220,9 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
<Select
|
<Select
|
||||||
class="w-full"
|
class="w-full"
|
||||||
loading={loading.value}
|
loading={loading.value}
|
||||||
{...attrs}
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
|
value={modelValue as any}
|
||||||
|
{...restAttrs}
|
||||||
// TODO: @dhb52 remote 对等实现, 还是说没作用
|
// TODO: @dhb52 remote 对等实现, 还是说没作用
|
||||||
// remote={props.remote}
|
// remote={props.remote}
|
||||||
{...(props.remote && { remoteMethod })}
|
{...(props.remote && { remoteMethod })}
|
||||||
|
@ -228,6 +238,11 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const buildCheckbox = () => {
|
const buildCheckbox = () => {
|
||||||
|
const {
|
||||||
|
modelValue,
|
||||||
|
'onUpdate:modelValue': onUpdateModelValue,
|
||||||
|
...restAttrs
|
||||||
|
} = attrs;
|
||||||
if (isEmpty(options.value)) {
|
if (isEmpty(options.value)) {
|
||||||
options.value = [
|
options.value = [
|
||||||
{ label: '选项1', value: '选项1' },
|
{ label: '选项1', value: '选项1' },
|
||||||
|
@ -235,7 +250,12 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<CheckboxGroup class="w-full" {...attrs}>
|
<CheckboxGroup
|
||||||
|
class="w-full"
|
||||||
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
|
value={modelValue as any}
|
||||||
|
{...restAttrs}
|
||||||
|
>
|
||||||
{options.value.map(
|
{options.value.map(
|
||||||
(item: { label: any; value: any }, index: any) => (
|
(item: { label: any; value: any }, index: any) => (
|
||||||
<Checkbox key={index} value={item.value}>
|
<Checkbox key={index} value={item.value}>
|
||||||
|
@ -247,6 +267,11 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const buildRadio = () => {
|
const buildRadio = () => {
|
||||||
|
const {
|
||||||
|
modelValue,
|
||||||
|
'onUpdate:modelValue': onUpdateModelValue,
|
||||||
|
...restAttrs
|
||||||
|
} = attrs;
|
||||||
if (isEmpty(options.value)) {
|
if (isEmpty(options.value)) {
|
||||||
options.value = [
|
options.value = [
|
||||||
{ label: '选项1', value: '选项1' },
|
{ label: '选项1', value: '选项1' },
|
||||||
|
@ -254,7 +279,12 @@ export const useApiSelect = (option: ApiSelectProps) => {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<RadioGroup class="w-full" {...attrs}>
|
<RadioGroup
|
||||||
|
class="w-full"
|
||||||
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
|
value={modelValue as any}
|
||||||
|
{...restAttrs}
|
||||||
|
>
|
||||||
{options.value.map(
|
{options.value.map(
|
||||||
(item: { label: any; value: any }, index: any) => (
|
(item: { label: any; value: any }, index: any) => (
|
||||||
<Radio key={index} value={item.value}>
|
<Radio key={index} value={item.value}>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { BpmProcessDefinitionApi } from '#/api/bpm/definition';
|
import type { BpmProcessDefinitionApi } from '#/api/bpm/definition';
|
||||||
|
import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
|
||||||
|
|
||||||
import { computed, nextTick, ref, watch } from 'vue';
|
import { computed, nextTick, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ import {
|
||||||
BpmModelFormType,
|
BpmModelFormType,
|
||||||
BpmModelType,
|
BpmModelType,
|
||||||
BpmNodeIdEnum,
|
BpmNodeIdEnum,
|
||||||
BpmNodeTypeEnum,
|
|
||||||
decodeFields,
|
decodeFields,
|
||||||
setConfAndFields2,
|
setConfAndFields2,
|
||||||
} from '#/utils';
|
} from '#/utils';
|
||||||
|
@ -39,22 +39,6 @@ interface UserTask {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApprovalNodeInfo {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
candidateStrategy: BpmCandidateStrategyEnum;
|
|
||||||
candidateUsers?: Array<{
|
|
||||||
avatar: string;
|
|
||||||
id: number;
|
|
||||||
nickname: string;
|
|
||||||
}>;
|
|
||||||
endTime?: Date;
|
|
||||||
nodeType: BpmNodeTypeEnum;
|
|
||||||
startTime?: Date;
|
|
||||||
status: number;
|
|
||||||
tasks: any[];
|
|
||||||
}
|
|
||||||
|
|
||||||
defineOptions({ name: 'BpmProcessInstanceCreateForm' });
|
defineOptions({ name: 'BpmProcessInstanceCreateForm' });
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -86,7 +70,7 @@ const bpmnXML = ref<string | undefined>(undefined);
|
||||||
const simpleJson = ref<string | undefined>(undefined);
|
const simpleJson = ref<string | undefined>(undefined);
|
||||||
const timelineRef = ref<any>();
|
const timelineRef = ref<any>();
|
||||||
const activeTab = ref('form');
|
const activeTab = ref('form');
|
||||||
const activityNodes = ref<ApprovalNodeInfo[]>([]);
|
const activityNodes = ref<BpmProcessInstanceApi.ApprovalNodeInfo[]>([]);
|
||||||
const processInstanceStartLoading = ref(false);
|
const processInstanceStartLoading = ref(false);
|
||||||
|
|
||||||
/** 提交按钮 */
|
/** 提交按钮 */
|
||||||
|
@ -217,7 +201,7 @@ async function getApprovalDetail(row: {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取审批节点
|
// 获取审批节点
|
||||||
activityNodes.value = data.activityNodes as unknown as ApprovalNodeInfo[];
|
activityNodes.value = data.activityNodes;
|
||||||
|
|
||||||
// 获取发起人自选的任务
|
// 获取发起人自选的任务
|
||||||
startUserSelectTasks.value = (data.activityNodes?.filter(
|
startUserSelectTasks.value = (data.activityNodes?.filter(
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
import { formatDateTime, isEmpty } from '@vben/utils';
|
import { formatDateTime, isEmpty } from '@vben/utils';
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ const nodeTypeSvgMap = {
|
||||||
color: '#14bb83',
|
color: '#14bb83',
|
||||||
icon: 'icon-park-outline:tree-diagram',
|
icon: 'icon-park-outline:tree-diagram',
|
||||||
},
|
},
|
||||||
};
|
} as Record<BpmNodeTypeEnum, { color: string; icon: string }>;
|
||||||
|
|
||||||
// 只有状态是 -1、0、1 才展示头像右小角状态小icon
|
// 只有状态是 -1、0、1 才展示头像右小角状态小icon
|
||||||
const onlyStatusIconShow = [-1, 0, 1];
|
const onlyStatusIconShow = [-1, 0, 1];
|
||||||
|
@ -150,21 +151,27 @@ function getApprovalNodeTime(node: BpmProcessInstanceApi.ApprovalNodeInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择自定义审批人
|
// 选择自定义审批人
|
||||||
const userSelectFormRef = ref();
|
const [UserSelectModalComp, userSelectModalApi] = useVbenModal({
|
||||||
|
connectedComponent: UserSelectModal,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
const selectedActivityNodeId = ref<string>();
|
const selectedActivityNodeId = ref<string>();
|
||||||
const customApproveUsers = ref<Record<string, any[]>>({}); // key:activityId,value:用户列表
|
const customApproveUsers = ref<Record<string, any[]>>({}); // key:activityId,value:用户列表
|
||||||
|
|
||||||
// 打开选择用户弹窗
|
// 打开选择用户弹窗
|
||||||
const handleSelectUser = (activityId: string, selectedList: any[]) => {
|
const handleSelectUser = (activityId: string, selectedList: any[]) => {
|
||||||
selectedActivityNodeId.value = activityId;
|
selectedActivityNodeId.value = activityId;
|
||||||
userSelectFormRef.value.open(
|
userSelectModalApi
|
||||||
selectedList?.length ? selectedList.map((item) => item.id) : [],
|
.setData({ userIds: selectedList.map((item) => item.id) })
|
||||||
);
|
.open();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选择用户完成
|
// 选择用户完成
|
||||||
const selectedUsers = ref<number[]>([]);
|
const selectedUsers = ref<number[]>([]);
|
||||||
function handleUserSelectConfirm(userList: any[]) {
|
function handleUserSelectConfirm(userList: any[]) {
|
||||||
|
if (!selectedActivityNodeId.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
customApproveUsers.value[selectedActivityNodeId.value] = userList || [];
|
customApproveUsers.value[selectedActivityNodeId.value] = userList || [];
|
||||||
|
|
||||||
emit('selectUserConfirm', selectedActivityNodeId.value, userList);
|
emit('selectUserConfirm', selectedActivityNodeId.value, userList);
|
||||||
|
@ -289,8 +296,12 @@ function handleUserSelectCancel() {
|
||||||
type="primary"
|
type="primary"
|
||||||
size="middle"
|
size="middle"
|
||||||
ghost
|
ghost
|
||||||
|
class="flex items-center justify-center"
|
||||||
@click="
|
@click="
|
||||||
handleSelectUser(activity.id, customApproveUsers[activity.id])
|
handleSelectUser(
|
||||||
|
activity.id,
|
||||||
|
customApproveUsers[activity.id] ?? [],
|
||||||
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
|
@ -445,8 +456,7 @@ function handleUserSelectCancel() {
|
||||||
</Timeline>
|
</Timeline>
|
||||||
|
|
||||||
<!-- 用户选择弹窗 -->
|
<!-- 用户选择弹窗 -->
|
||||||
<UserSelectModal
|
<UserSelectModalComp
|
||||||
ref="userSelectFormRef"
|
|
||||||
v-model:value="selectedUsers"
|
v-model:value="selectedUsers"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
title="选择用户"
|
title="选择用户"
|
||||||
|
|
Loading…
Reference in New Issue