<script lang="ts" setup name="SystemEditDept"> import type { Ref } from 'vue' import { nextTick, reactive } from 'vue' import { ElButton, ElCol, ElDialog, ElForm, ElFormItem, ElInput, ElInputNumber, ElMessage, ElMessageBox, ElOption, ElRow, ElSelect } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import type { DeptInfo, DeptTypeInfo } from './dept-interface' import { addDept, getDeptTypeList, updateDept } from '@/api/system/dept' import useDictStore from '@/store/modules/dict' import DeptSelect from '@/components/DeptSelect/index.vue' // ----------------------- 以下是字段定义 emits props --------------------- const emits = defineEmits(['closeRefresh']) // 对话框类型:create,update const dialogStatus = ref('create') const dialogVisible = ref(false) // 显示标题 const textMap: { [key: string]: string } = { update: '编辑', create: '新增', } const defaultFormData: DeptInfo = { id: '', simpleName: '', fullName: '', deptType: '', pid: '', num: 0, version: '', tips: '', } // 表单数据对象 const formData: DeptInfo = reactive({ ...defaultFormData }) // 保存按钮加载状态 const btnLoading = ref(false) // ---------------表单提交-------------------------------- // 表单对象 const dataFormRef = ref<FormInstance>() // 校验规则 const rules: FormRules = reactive({ simpleName: [{ required: true, message: '组织名称不可为空', trigger: ['blur', 'change'] }], fullName: [{ required: true, message: '组织全称不可为空', trigger: ['blur', 'change'] }], pid: [{ required: true, message: '父组织必选', trigger: ['blur', 'change'] }], deptType: [{ required: true, message: '组织类型必选', trigger: ['blur', 'change'] }], num: [{ required: true, message: '排序不可为空', trigger: 'blur' }, { pattern: /^\d+(\.\d+)?$/, trigger: ['blur', 'change'], message: '' }], }) const submitForm = async (formEl: FormInstance | undefined) => { if (!formEl) { return } await formEl.validate((valid, fields) => { if (valid) { if (valid) { if (dialogStatus.value === 'create') { createData() } else if (dialogStatus.value === 'update') { updateData() } } } }) } // 新增数据 function createData() { btnLoading.value = true addDept(formData).then((res) => { ElMessageBox.confirm( '新增成功,是否继续新增?', '提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'info', }, ).then(() => { resetForm() }).catch(() => { closeRefresh() }).finally(() => { clearBuffer() }) btnLoading.value = false }).catch((_) => { btnLoading.value = false }) } // 更新数据 function updateData() { updateDept(formData).then((res) => { ElMessage.success('修改成功') btnLoading.value = false clearBuffer() closeRefresh() }).catch((_) => { // 异常情况,loading置为false btnLoading.value = false }) } const dictStore = useDictStore() // 部门选择组件 const deptSelect = ref() // 在组织变更后清空pinia中缓存 function clearBuffer() { dictStore.setAllCompanyList([]) dictStore.setAllDeptList([]) deptSelect.value.refreshTree() // 刷新组件 } // 重置表单 function resetForm() { const form = formData const keys = Object.keys(formData) keys.forEach((key) => { form[key] = defaultFormData[key] }) Object.assign(formData, form) nextTick(() => { dataFormRef.value?.clearValidate() }) } const deptTypeList: Ref<DeptTypeInfo[]> = ref([]) // 获取所有组织类型 function getDeptType() { getDeptTypeList().then((res) => { deptTypeList.value = res.data }) } getDeptType() // ----------初始化、关闭对话框相关----------------- function initDialog(dialogstatus: string, row: DeptInfo) { dialogStatus.value = dialogstatus dialogVisible.value = true btnLoading.value = false if (dialogstatus === 'create') { resetForm() nextTick(() => { dataFormRef.value?.clearValidate() }) } else if (dialogstatus === 'update') { formData.id = row.id formData.simpleName = row.simpleName formData.fullName = row.fullName formData.deptType = row.deptType formData.pid = row.pid formData.num = row.num formData.version = row.version formData.tips = row.tips } } // 关闭并刷新 function closeRefresh() { dialogVisible.value = false resetForm() emits('closeRefresh') } // 关闭弹窗 function dialogClose() { resetForm() dialogVisible.value = false } // ----------------------- 以下是暴露的方法内容 ---------------------------- defineExpose({ initDialog }) </script> <template> <el-dialog v-model="dialogVisible" :title="textMap[dialogStatus]" width="50%" :before-close="dialogClose" append-to-body :open-delay="0" :close-on-click-modal="false" > <el-form ref="dataFormRef" :model="formData" :rules="rules" label-position="left" label-width="110px" class="form-container" size="default" @submit.prevent > <el-row :gutter="10"> <el-col :span="12" class="grid-cell"> <el-form-item label="组织名称" prop="simpleName" class="required"> <el-input v-model.trim="formData.simpleName" type="text" placeholder="必填" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="组织全称" prop="fullName" class="required"> <el-input v-model.trim="formData.fullName" type="text" placeholder="必填" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="父组织" prop="pid" class="required"> <dept-select ref="deptSelect" v-model="formData.pid" :dept-show="true" /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="组织类型" prop="deptType" class="required"> <el-select v-model="formData.deptType" class="full-width-input" clearable placeholder="请选择"> <el-option v-for="(item, index) in deptTypeList" :key="index" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="排序" prop="num" class="required"> <el-input-number v-model="formData.num" class="full-width-input" controls-position="right" :min="0" :max="999" :precision="0" :step="1" /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="备注" prop="tips"> <el-input v-model.trim="formData.tips" type="text" placeholder="非必填" clearable /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> <el-button :loading="btnLoading" type="primary" @click="submitForm(dataFormRef)"> 保存 </el-button> <el-button @click="dialogClose"> 取消 </el-button> </div> </template> </el-dialog> </template> <style lang="scss" scoped> .form-container { width: 100%; .full-width-input { width: 100%; } } </style>