diff --git a/src/components/UserSelectForm/index.vue b/src/components/UserSelectForm/index.vue index 2dc94587..d4cf6f2b 100644 --- a/src/components/UserSelectForm/index.vue +++ b/src/components/UserSelectForm/index.vue @@ -15,7 +15,7 @@ @@ -36,21 +41,24 @@ import * as UserApi from '@/api/system/user' defineOptions({ name: 'UserSelectForm' }) const emit = defineEmits<{ - confirm: [userList: any[]] + confirm: [id: any, userList: any[]] }>() const { t } = useI18n() // 国际 const deptList = ref([]) // 部门树形结构化 const userList: any = ref([]) // 用户列表 const message = useMessage() // 消息弹窗 -const selectedUserList: any = ref([]) // 选中的用户列表 +const selectedUserIdList: any = ref([]) // 选中的用户列表 const dialogVisible = ref(false) // 弹窗的是否展示 const formLoading = ref(false) // 表单的加载中 +const activityId = ref() // 主键id /** 打开弹窗 */ -const open = async () => { +const open = async (id, selectedList?) => { + activityId.value = id resetForm() deptList.value = handleTree(await DeptApi.getSimpleDeptList()) await getUserList() + selectedUserIdList.value = selectedList?.map((item) => item.id) // 修改时,设置数据 dialogVisible.value = true } @@ -71,8 +79,9 @@ const submitForm = async () => { try { message.success(t('common.updateSuccess')) dialogVisible.value = false + const emitUserList = userList.value.filter((user) => selectedUserIdList.value.includes(user.id)) // 发送操作成功的事件 - emit('confirm', selectedUserList.value) + emit('confirm', activityId.value, emitUserList) } finally { formLoading.value = false } @@ -80,13 +89,12 @@ const submitForm = async () => { const resetForm = () => { deptList.value = [] userList.value = [] - selectedUserList.value = [] + selectedUserIdList.value = [] } /** 处理部门被点击 */ const handleNodeClick = async (row: { [key: string]: any }) => { getUserList(row.id) } - defineExpose({ open }) // 提供 open 方法,用于打开弹窗 diff --git a/src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue b/src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue index 442cfffc..18a3ba72 100644 --- a/src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue +++ b/src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue @@ -19,40 +19,7 @@ v-model="detailForm.value" :option="detailForm.option" @submit="submitForm" - > - - + /> @@ -62,6 +29,8 @@ :activity-nodes="activityNodes" :show-status-icon="false" :startUserSelectTasks="startUserSelectTasks" + :startUserSelectAssignees="startUserSelectAssignees" + @select-user-confirm="selectUserConfirm" /> @@ -104,8 +73,7 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config' import { useTagsViewStore } from '@/store/modules/tagsView' import * as ProcessInstanceApi from '@/api/bpm/processInstance' import * as DefinitionApi from '@/api/bpm/definition' -// import * as UserApi from '@/api/system/user' -import { activityNodes as aN, startUserSelectTasks as sUs } from './mock' +// import { activityNodes as aN, startUserSelectTasks as sUs } from './mock' defineOptions({ name: 'ProcessDefinitionDetail' }) const props = defineProps<{ @@ -122,11 +90,8 @@ const detailForm: any = ref({ }) // 流程表单详情 const fApi = ref() // 指定审批人 -const startUserSelectAssigneesFormRef = ref() // 发起人选择审批人的表单 Ref const startUserSelectTasks: any = ref([]) // 发起人需要选择审批人的用户任务列表 const startUserSelectAssignees = ref({}) // 发起人选择审批人的数据 -const startUserSelectAssigneesFormRules = ref({}) // 发起人选择审批人的表单 Rules -// const userList = ref([]) // 用户列表 const bpmnXML: any = ref(null) // BPMN 数据 /** 当前的Tab */ const activeTab = ref('form') @@ -139,7 +104,6 @@ const initProcessInfo = async (row: any, formVariables?: any) => { // 重置指定审批人 startUserSelectTasks.value = [] startUserSelectAssignees.value = {} - startUserSelectAssigneesFormRules.value = {} // 情况一:流程表单 if (row.formType == 10) { @@ -164,25 +128,13 @@ const initProcessInfo = async (row: any, formVariables?: any) => { if (processDefinitionDetail) { bpmnXML.value = processDefinitionDetail.bpmnXml startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks - startUserSelectTasks.value = sUs // 设置指定审批人 - // if (startUserSelectTasks.value?.length > 0) { - // detailForm.value.rule.push({ - // type: 'startUserSelect', - // props: { - // title: '指定审批人' - // } - // }) - // // 设置校验规则 - // for (const userTask of startUserSelectTasks.value) { - // startUserSelectAssignees.value[userTask.id] = [] - // startUserSelectAssigneesFormRules.value[userTask.id] = [ - // { required: true, message: '请选择审批人', trigger: 'blur' } - // ] - // } - // // 加载用户列表 - // userList.value = await UserApi.getSimpleUserList() - // } + if (startUserSelectTasks.value?.length > 0) { + for (const userTask of startUserSelectTasks.value) { + // 初始化数据 + startUserSelectAssignees.value[userTask.id] = [] + } + } } // 情况二:业务表单 } else if (row.formCustomCreatePath) { @@ -206,19 +158,23 @@ const getApprovalDetail = async (row: any) => { } // 获取审批节点,显示 Timeline 的数据 activityNodes.value = data.activityNodes - activityNodes.value = aN } finally { } } /** 提交按钮 */ const submitForm = async (formData: any) => { - debugger if (!fApi.value || !props.selectProcessDefinition) { return } // 如果有指定审批人,需要校验 if (startUserSelectTasks.value?.length > 0) { - await startUserSelectAssigneesFormRef.value.validate() + for (const userTask of startUserSelectTasks.value) { + if ( + Array.isArray(startUserSelectAssignees.value[userTask.id]) && + startUserSelectAssignees.value[userTask.id].length === 0 + ) + return message.warning(`请选择${userTask.name}的审批人`) + } } // 提交请求 @@ -245,6 +201,10 @@ const handleCancel = () => { emit('cancel') } +const selectUserConfirm = (id, userList) => { + startUserSelectAssignees.value[id] = userList?.map((item) => item.id) +} + defineExpose({ initProcessInfo }) diff --git a/src/views/bpm/processInstance/create/mock.ts b/src/views/bpm/processInstance/create/mock.ts deleted file mode 100644 index 2cb1394c..00000000 --- a/src/views/bpm/processInstance/create/mock.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { ProcessInstanceVO, User, ApprovalTaskInfo, ApprovalNodeInfo } from '@/api/bpm/processInstance'; -import { NodeType } from '@/components/SimpleProcessDesignerV2/src/consts' - -const users: User[] = [ - { id: 1, nickname: 'Alice', avatar: 'https://picsum.photos/200?r=1' }, - { id: 2, nickname: 'Bob', avatar: 'https://picsum.photos/200?r=2' }, - { id: 3, nickname: 'Charlie', avatar: 'https://picsum.photos/200?r=3' }, - { id: 4, nickname: 'David', avatar: 'https://picsum.photos/200?r=4' } -]; - -const approvalTask1: ApprovalTaskInfo = { - id: 1, - ownerUser: users[0], // Alice is the owner (initiator) - assigneeUser: users[1], // Bob is the assignee - status: 1, // In Progress - reason: 'Please review and approve the request.' -}; - -const approvalTask2: ApprovalTaskInfo = { - id: 2, - ownerUser: users[1], // Bob is the owner (approver) - assigneeUser: users[2], // Charlie is the assignee - status: 0, // Pending approval - reason: 'Awaiting Bob’s decision.' -}; - -const approvalTask3: ApprovalTaskInfo = { - id: 3, - ownerUser: users[2], // Charlie is the owner (approver) - assigneeUser: users[3], // David is the assignee - status: 0, // Pending approval - reason: 'Awaiting Charlie’s decision.' -}; - -const approvalNode1: ApprovalNodeInfo = { - id: 101, - name: 'Start Review', - nodeType: NodeType.START_USER_NODE, - status: 1, // In Progress - startTime: new Date('2024-11-01T10:00:00Z'), - tasks: [approvalTask1] -}; - -const approvalNode2: ApprovalNodeInfo = { - id: 102, - name: 'First Review', - nodeType: NodeType.USER_TASK_NODE, - status: 0, // Pending approval - startTime: new Date('2024-11-01T11:00:00Z'), - tasks: [approvalTask2], - candidateUsers: [users[2], users[3]] // Candidate users: Charlie and David -}; - -const approvalNode3: ApprovalNodeInfo = { - id: 103, - name: 'Second Review', - nodeType: NodeType.USER_TASK_NODE, - status: 0, // Pending approval - startTime: new Date('2024-11-01T12:00:00Z'), - tasks: [approvalTask3], - candidateUsers: [users[1], users[3]] // Candidate users: Bob and David -}; - -const processInstance: ProcessInstanceVO = { - id: 1001, - name: 'Request Approval Process', - processDefinitionId: 'proc-2024-001', - category: 'Approval Process', - result: 0, // Ongoing - tasks: [{ id: '1', name: 'Start Review' }, { id: '2', name: 'First Review' }, { id: '3', name: 'Second Review' }], - fields: ['field1', 'field2'], - status: 1, // In Progress - remark: 'This is a sample approval process.', - businessKey: 'BUS-12345', - createTime: '2024-11-01T09:00:00Z', - endTime: '', - processDefinition: undefined // Not populated in this example -}; - -// 模拟的 activityNodes 数据,传递给 ProcessInstanceTimeline 组件 -const activityNodes: ApprovalNodeInfo[] = [approvalNode1, approvalNode2, approvalNode3]; - -export { processInstance, activityNodes, users }; - - -export const startUserSelectTasks = users.map(user => ({id: user.id,name:user.nickname})) diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue index 1d3e7a1c..10993735 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue @@ -38,11 +38,29 @@
- + + +
+ + + {{ user.nickname.substring(0, 1) }} + + {{ user.nickname }} +
@@ -152,10 +170,12 @@ withDefaults( activityNodes: ProcessInstanceApi.ApprovalNodeInfo[] // 审批节点信息 showStatusIcon?: boolean // 是否显示头像右下角状态图标 startUserSelectTasks?: any[] // 发起人需要选择审批人的用户任务列表 + startUserSelectAssignees?: any // 发起人选择审批人的数据 }>(), { showStatusIcon: true, // 默认值为 true - startUserSelectTasks: () => [] // 默认值为空数组 + startUserSelectTasks: () => [], // 默认值为空数组 + startUserSelectAssignees: () => {} } ) @@ -256,11 +276,16 @@ const getApprovalNodeTime = (node: ProcessInstanceApi.ApprovalNodeInfo) => { // 选择自定义审批人 const userSelectFormRef = ref() -const handleSelectUser = () => { - userSelectFormRef.value.open() +const handleSelectUser = (activityId, selectedList) => { + userSelectFormRef.value.open(activityId, selectedList) } +const emit = defineEmits<{ + selectUserConfirm: [id: any, userList: any[]] +}>() +const customApprover: any = ref({}) // 选择完成 -const handleUserSelectConfirm = (userList) => { - console.log('[ userList ] >', userList) +const handleUserSelectConfirm = (activityId, userList) => { + customApprover.value[activityId] = userList || [] + emit('selectUserConfirm', activityId, userList) }