<!-- 审批弹窗 --> <script lang="ts" setup name="ApprovalDialog"> import type { FormInstance, FormRules } from 'element-plus' import { ElMessage } from 'element-plus' import dayjs from 'dayjs' import useUserStore from '@/store/modules/user' import { fetchApproval, submitApproval } from '@/api/approval' import { addApprovalUser, getProcessDetail } from '@/api/system/process' import { getUserList } from '@/api/system/user' import request from '@/api/index' /** * 审批弹窗 */ const $props = defineProps({ /** * 提示文字 */ title: { type: String, default: '审批结论', }, // 同意的接口地址 agree: { type: String, required: true, }, lastName: { type: String, required: true, }, showNextText: { type: Boolean, default: false, }, formId: { type: String, default: '', }, defaultTitle: { type: Boolean, default: false, }, }) const emit = defineEmits(['onSuccess', 'refuse', 'reject', 'sendApprovalRecord']) const currentApprovalNode = ref('') // 当前审批节点名称 // 弹窗显示状态 const dialogVisible = ref(false) // 默认表单 const defaultFormData = { type: '', // 审批类型 taskId: '', // 任务id comments: '', // 备注 user: '', // 当前用户 approvalTime: '', // 当前时间 id: '', userList: [] as any, processId: '', // situationAnalysisType: undefined, } // 弹窗类型 agree同意 refuse拒绝 reject驳回 revoke取消 const type = ref('agree') // 表单数据对象 const formData = reactive({ ...defaultFormData }) // 保存按钮加载状态 const btnLoading = ref(false) // agree同意 refuse拒绝 reject驳回 revoke取消 const userInfo = useUserStore() // 是否展示 下一节点审批节点 审批人 const isShowUser = ref(false) const nextText = ref('') // 下一审批节点名称 // ---------------表单提交-------------------------------- // 表单对象 const dataFormRef = ref<FormInstance>() // 校验规则 const rules: FormRules = reactive({ // comments: [{ required: true, message: '审批结论必填', trigger: ['blur', 'change'] }], userList: [{ required: true, message: '节点审批人必选', trigger: ['blur', 'change'] }], // situationAnalysisType: [{ required: true, message: '处理意见必填', trigger: ['blur', 'change'] }], }) /** * 初始化审批弹窗 * @param type 审批类型 * @param taskId 任务id * @param id 列表id */ function initDialog(type: string, taskId: string, id?: string, processId?: string) { console.log(processId, 'processId') isShowUser.value = true nextText.value = '' getApprovalRecord(processId!) formData.type = type formData.taskId = taskId formData.userList = [] formData.user = userInfo.name formData.approvalTime = dayjs().format('YYYY-MM-DD HH:mm:ss') formData.comments = '' formData.processId = processId! // formData.situationAnalysisType = undefined formData.id = id! dialogVisible.value = true } const $route = useRoute() // 提交表单 function submitForm() { if (dataFormRef) { dataFormRef.value?.validate((valid: boolean) => { if (valid) { if (formData.userList.includes(userInfo.id)) { ElMessage.warning('下一节点审批人不能含有当前用户') return } btnLoading.value = true if (formData.type === 'agree') { const agree = () => { request({ url: $props.agree, method: 'post', // data, data: { taskId: formData.taskId, comments: formData.comments }, }).then((res) => { ElMessage.success('审批完成') btnLoading.value = false dialogVisible.value = false emit('onSuccess') }).catch((_) => { btnLoading.value = false }) } if (isShowUser.value) { addApprovalUser({ assignees: formData.userList, processInstanceId: formData.processId, }).then(() => { agree() }) } else { agree() } // submitApproval(formData.type, { taskId: formData.taskId, comments: formData.comments }).then((res) => { // ElMessage.success('审批完成') // btnLoading.value = false // dialogVisible.value = false // emit('onSuccess') // }).catch((_) => { // btnLoading.value = false // }) } else if (formData.type === 'reject') { dialogVisible.value = false btnLoading.value = false emit('reject', formData.comments, formData.taskId, formData.id) } else if (formData.type === 'refuse') { dialogVisible.value = false btnLoading.value = false emit('refuse', formData.comments, formData.taskId, formData.id) } } }) } } // 关闭弹窗 function handleClose() { dialogVisible.value = false } // 获取字典 const userList = ref<any[]>([]) const fetchDict = () => { getUserList({ offset: 1, limit: 99999 }).then((res) => { userList.value = res.data.rows }) } fetchDict() // 获取当前审批节点的下一节点 const getApprovalNextRecord = (data: any[]) => { if (!$props.formId) { nextText.value = '' return } if (!data.length) { nextText.value = '' } else { getProcessDetail($props.formId).then((res) => { if (res.data?.nodeConfig) { function flattenObject(obj: any, parentKey = '', result: any = {}): any { for (const key in obj) { if (obj.hasOwnProperty(key)) { const newKey = parentKey ? `${parentKey}.${key}` : key if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) { flattenObject(obj[key], newKey, result) } else { result[newKey] = obj[key] } } } return result } const response = flattenObject(res.data.nodeConfig) const result = [] for (const key in response) { if (key.includes('nodeName')) { // console.log(key) result.push(response[key]) } } nextText.value = result[data.length] || '' } else { nextText.value = '' } }) } } // 获取审批记录 根据当前节点判断显示 审批人选择 const approvalRecord = ref([]) function getApprovalRecord(processId: string) { fetchApproval(processId).then((res) => { // console.log(res.data, 'res') approvalRecord.value = res.data if (res.data.length) { const data = res.data[res.data.length - 1] if (data.length) { currentApprovalNode.value = data[data.length - 1].taskName if (data[data.length - 1].taskName === $props.lastName) { isShowUser.value = false } } emit('sendApprovalRecord', res.data) // 获取当前审批节点的下一节点 getApprovalNextRecord(res.data) } else { emit('sendApprovalRecord', []) // 获取当前审批节点的下一节点 getApprovalNextRecord([]) } }) } // ----------------------- 以下是暴露的方法内容 ---------------------------- defineExpose({ initDialog, approvalRecord }) </script> <template> <el-dialog v-model="dialogVisible" title="审批操作" width="700" :before-close="handleClose" :close-on-click-modal="false" > <el-form ref="dataFormRef" label-position="right" label-width="130px" :model="formData" :rules="rules" > <el-row :gutter="24"> <el-col :span="24"> <el-form-item label="审批意见:"> <el-radio-group v-model="formData.type" disabled> <el-radio label="agree" size="large"> 同意 </el-radio> <el-radio label="reject" size="large"> 驳回 </el-radio> <el-radio label="refuse" size="large"> 拒绝 </el-radio> </el-radio-group> </el-form-item> </el-col> </el-row> <el-row :gutter="24"> <el-col :span="24"> <el-form-item :label="(currentApprovalNode.includes('部门负责人') && $props.defaultTitle) ? '原因分析:' : `${$props.title}:`" prop="comments"> <el-input v-model="formData.comments" :rows="4" show-word-limit type="textarea" /> </el-form-item> </el-col> </el-row> <!-- 当前审批节点 --> <el-row v-if="!correctMerge" :gutter="24"> <el-col :span="24"> <el-form-item label="当前审批节点"> <el-input v-model="currentApprovalNode" show-word-limit type="textarea" disabled autosize /> </el-form-item> </el-col> </el-row> <el-row v-if="isShowUser && formData.type === 'agree'" :gutter="24"> <el-col :span="24"> <el-form-item :label="nextText || '下一节点审批人:'" prop="userList"> <el-select v-model="formData.userList" filterable multiple placeholder="审批人" style="width: 100%;"> <el-option v-for="(item) in userList" :key="item.id" :label="item.name" :value="item.id"> <span style="float: left;">{{ item.name }}</span> <span style="float: right; color: #8492a6; font-size: 13px;">{{ item.deptName }}</span> </el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row v-if="showNextText && nextText" :gutter="24"> <el-col :span="24"> <el-form-item label="下一节点:"> <el-input v-model="nextText" placeholder="下一节点" disabled /> </el-form-item> </el-col> </el-row> <el-row :gutter="24"> <el-col :span="12"> <el-form-item label="审批人:"> <el-input v-model="formData.user" placeholder="审批人" disabled /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="审批时间:"> <el-input v-model="formData.approvalTime" style="width: 100%;" placeholder="审批时间" disabled /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <el-button type="primary" :loading="btnLoading" @click="submitForm"> 提交 </el-button> <el-button type="info" @click="handleClose"> 取消 </el-button> </template> </el-dialog> </template> <style lang="scss" scoped> // 样式 </style>