From 728cf15c45174c9a6f980d1faab48d4f25564fa8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 23 Mar 2024 00:54:33 +0800 Subject: [PATCH] =?UTF-8?q?BPM=EF=BC=9A=E5=A2=9E=E5=8A=A0=E3=80=8C?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E4=BA=BA=E8=87=AA=E9=80=89=E3=80=8D=E7=9A=84?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=AE=A1=E6=89=B9=E4=BA=BA=E7=9A=84=E5=88=86?= =?UTF-8?q?=E9=85=8D=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bpm/definition/index.ts | 5 +- .../penal/task/task-components/UserTask.vue | 6 +- src/views/bpm/definition/index.vue | 8 +- src/views/bpm/oa/leave/create.vue | 82 +++++++++++++++++- .../bpm/processInstance/create/index.vue | 85 +++++++++++++++++-- .../detail/ProcessInstanceBpmnViewer.vue | 17 ++-- .../bpm/processInstance/detail/index.vue | 8 +- 7 files changed, 182 insertions(+), 29 deletions(-) diff --git a/src/api/bpm/definition/index.ts b/src/api/bpm/definition/index.ts index c0e51fab..cb6d4271 100644 --- a/src/api/bpm/definition/index.ts +++ b/src/api/bpm/definition/index.ts @@ -1,8 +1,9 @@ import request from '@/config/axios' -export const getProcessDefinitionBpmnXML = async (id: number) => { +export const getProcessDefinition = async (id: number, key: string) => { return await request.get({ - url: '/bpm/process-definition/get-bpmn-xml?id=' + id + url: '/bpm/process-definition/get', + params: { id, key } }) } diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/UserTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/UserTask.vue index 6431eca1..166fb409 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/UserTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/UserTask.vue @@ -65,11 +65,7 @@ @@ -133,12 +133,12 @@ const handleFormDetail = async (row) => { /** 流程图的详情按钮操作 */ const bpmnDetailVisible = ref(false) -const bpmnXML = ref(null) +const bpmnXml = ref(null) const bpmnControlForm = ref({ prefix: 'flowable' }) const handleBpmnDetail = async (row) => { - bpmnXML.value = await DefinitionApi.getProcessDefinitionBpmnXML(row.id) + bpmnXml.value = (await DefinitionApi.getProcessDefinition(row.id))?.bpmnXml bpmnDetailVisible.value = true } diff --git a/src/views/bpm/oa/leave/create.vue b/src/views/bpm/oa/leave/create.vue index a22392f9..28a15af7 100644 --- a/src/views/bpm/oa/leave/create.vue +++ b/src/views/bpm/oa/leave/create.vue @@ -37,6 +37,36 @@ + + + + + + + + + + + + 确 定 @@ -46,10 +76,15 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import * as LeaveApi from '@/api/bpm/leave' import { useTagsViewStore } from '@/store/modules/tagsView' +import * as DefinitionApi from '@/api/bpm/definition' +import * as UserApi from '@/api/system/user' defineOptions({ name: 'BpmOALeaveCreate' }) const message = useMessage() // 消息弹窗 +const { delView } = useTagsViewStore() // 视图操作 +const { push, currentRoute } = useRouter() // 路由 + const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const formData = ref({ type: undefined, @@ -64,18 +99,34 @@ const formRules = reactive({ endTime: [{ required: true, message: '请假结束时间不能为空', trigger: 'change' }] }) const formRef = ref() // 表单 Ref -const { delView } = useTagsViewStore() // 视图操作 -const { push, currentRoute } = useRouter() // 路由 + +// 指定审批人 +const processDefineKey = 'oa_leave' // 流程定义 Key +const startUserSelectTasks = ref([]) // 发起人需要选择审批人的用户任务列表 +const startUserSelectAssignees = ref({}) // 发起人选择审批人的数据 +const startUserSelectAssigneesFormRef = ref() // 发起人选择审批人的表单 Ref +const startUserSelectAssigneesFormRules = ref({}) // 发起人选择审批人的表单 Rules +const userList = ref([]) // 用户列表 + /** 提交表单 */ const submitForm = async () => { // 校验表单 if (!formRef) return const valid = await formRef.value.validate() if (!valid) return + // 校验指定审批人 + if (startUserSelectTasks.value?.length > 0) { + await startUserSelectAssigneesFormRef.value.validate() + } + // 提交请求 formLoading.value = true try { - const data = formData.value as unknown as LeaveApi.LeaveVO + const data = { ...formData.value } as unknown as LeaveApi.LeaveVO + // 设置指定审批人 + if (startUserSelectTasks.value?.length > 0) { + data.startUserSelectAssignees = startUserSelectAssignees.value + } await LeaveApi.createLeave(data) message.success('发起成功') // 关闭当前 Tab @@ -85,4 +136,29 @@ const submitForm = async () => { formLoading.value = false } } + +/** 初始化 */ +onMounted(async () => { + const processDefinitionDetail = await DefinitionApi.getProcessDefinition( + undefined, + processDefineKey + ) + if (!processDefinitionDetail) { + message.error('OA 请假的流程模型未配置,请检查!') + return + } + startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks + // 设置指定审批人 + if (startUserSelectTasks.value?.length > 0) { + // 设置校验规则 + for (const userTask of startUserSelectTasks.value) { + startUserSelectAssignees.value[userTask.id] = [] + startUserSelectAssigneesFormRules.value[userTask.id] = [ + { required: true, message: '请选择审批人', trigger: 'blur' } + ] + } + // 加载用户列表 + userList.value = await UserApi.getSimpleUserList() + } +}) diff --git a/src/views/bpm/processInstance/create/index.vue b/src/views/bpm/processInstance/create/index.vue index bd782fef..99bcdb06 100644 --- a/src/views/bpm/processInstance/create/index.vue +++ b/src/views/bpm/processInstance/create/index.vue @@ -54,7 +54,40 @@ v-model="detailForm.value" :option="detailForm.option" @submit="submitForm" - /> + > + + @@ -69,6 +102,7 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config' import ProcessInstanceBpmnViewer from '../detail/ProcessInstanceBpmnViewer.vue' import { CategoryApi } from '@/api/bpm/category' import { useTagsViewStore } from '@/store/modules/tagsView' +import * as UserApi from '@/api/system/user' defineOptions({ name: 'BpmProcessInstanceCreate' }) @@ -124,7 +158,6 @@ const categoryProcessDefinitionList = computed(() => { }) // ========== 表单相关 ========== -const bpmnXML = ref(null) // BPMN 数据 const fApi = ref() const detailForm = ref({ rule: [], @@ -133,17 +166,53 @@ const detailForm = ref({ }) // 流程表单详情 const selectProcessDefinition = ref() // 选择的流程定义 +// 指定审批人 +const bpmnXML = ref(null) // BPMN 数据 +const startUserSelectTasks = ref([]) // 发起人需要选择审批人的用户任务列表 +const startUserSelectAssignees = ref({}) // 发起人选择审批人的数据 +const startUserSelectAssigneesFormRef = ref() // 发起人选择审批人的表单 Ref +const startUserSelectAssigneesFormRules = ref({}) // 发起人选择审批人的表单 Rules +const userList = ref([]) // 用户列表 + /** 处理选择流程的按钮操作 **/ const handleSelect = async (row, formVariables) => { // 设置选择的流程 selectProcessDefinition.value = row + // 重置指定审批人 + startUserSelectTasks.value = [] + startUserSelectAssignees.value = {} + startUserSelectAssigneesFormRules.value = {} + // 情况一:流程表单 if (row.formType == 10) { // 设置表单 setConfAndFields2(detailForm, row.formConf, row.formFields, formVariables) // 加载流程图 - bpmnXML.value = await DefinitionApi.getProcessDefinitionBpmnXML(row.id) + const processDefinitionDetail = await DefinitionApi.getProcessDefinition(row.id) + if (processDefinitionDetail) { + bpmnXML.value = processDefinitionDetail.bpmnXml + startUserSelectTasks.value = processDefinitionDetail.startUserSelectTasks + + // 设置指定审批人 + 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() + } + } // 情况二:业务表单 } else if (row.formCustomCreatePath) { await push({ @@ -158,19 +227,25 @@ const submitForm = async (formData) => { if (!fApi.value || !selectProcessDefinition.value) { return } + // 如果有指定审批人,需要校验 + if (startUserSelectTasks.value?.length > 0) { + await startUserSelectAssigneesFormRef.value.validate() + } + // 提交请求 fApi.value.btn.loading(true) try { await ProcessInstanceApi.createProcessInstance({ processDefinitionId: selectProcessDefinition.value.id, - variables: formData + variables: formData, + startUserSelectAssignees: startUserSelectAssignees.value }) // 提示 message.success('发起流程成功') // 跳转回去 delView(unref(currentRoute)) await push({ - name: 'BpmProcessInstance' + name: 'BpmProcessInstanceMy' }) } finally { fApi.value.btn.loading(false) diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue b/src/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue index dcf3bcc4..8912593a 100644 --- a/src/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue +++ b/src/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue @@ -34,14 +34,17 @@ const bpmnControlForm = ref({ }) const activityList = ref([]) // 任务列表 -/** 初始化 */ -onMounted(async () => { - if (props.id) { - activityList.value = await ActivityApi.getActivityList({ - processInstanceId: props.id - }) +/** 只有 loading 完成时,才去加载流程列表 */ +watch( + () => props.loading, + async (value) => { + if (value && props.id) { + activityList.value = await ActivityApi.getActivityList({ + processInstanceId: props.id + }) + } } -}) +)