<script lang="ts" setup name="SystemEditResource"> import type { Ref } from 'vue' import { nextTick, reactive } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import type { ResourceInfo, ResourceTypeInfo } from './resource-interface' import { addResource, getResourceTreeList, updateResource } from '@/api/system/resource' import { toTreeList } from '@/utils/structure' import { getDictByCode } from '@/api/system/dict' import type { dictType } from '@/global' import { delResource, getResourceList, getResourceTypeList } from '@/api/system/resource' import { approvalAdd } from '@/api/system/user' const emits = defineEmits(['closeRefresh']) const useApproval = ref('') // 是否走审批 // 对话框类型:create,update const dialogStatus = ref('create') const dialogVisible = ref(false) // 显示标题 const textMap: { [key: string]: string } = { update: '编辑', create: '新增', detail: '详情', } // 表单数据对象 const formData: Ref<ResourceInfo> = ref({ name: '', id: '', url: '', code: '', pid: '', resourceType: '', bizType: '', // 业务类型 num: 0, icon: '', }) // 保存按钮加载状态 const btnLoading = ref(false) // ---------------表单提交-------------------------------- // 表单对象 const dataFormRef = ref<FormInstance>() // 校验规则 const rules = reactive<FormRules>({ name: [{ required: true, message: '资源名称不可为空', trigger: ['blur', 'change'] }], url: [{ required: true, message: '资源路径不可为空', trigger: ['blur', 'change'] }], code: [{ required: true, message: '资源编码不可为空', trigger: ['blur', 'change'] }], pid: [{ required: true, message: '父资源必选', trigger: ['blur', 'change'] }], resourceType: [{ required: true, message: '资源类型必选', trigger: ['blur', 'change'] }], num: [{ required: true, message: '排序不可为空', trigger: 'blur' }, { pattern: /^\d+(\.\d+)?$/, trigger: ['blur', 'change'], message: '' }], bizType: [{ required: true, message: '业务类型必选', trigger: ['blur', 'change'] }], }) // -----------------------------------------字典-------------------------------------------------------------- const bizTypeList = ref<dictType[]>([]) // 业务类型 const resourceTypeList: any = ref([]) // 获取资源类型列表 const getDict = async () => { // 业务类型 getDictByCode('bizType').then((response) => { bizTypeList.value = response.data }) getResourceTypeList().then((res) => { resourceTypeList.value = res.data }) } getDict() // ------------------------------------------------------------------------------------------- function submitForm() { if (dataFormRef) { dataFormRef.value?.validate((valid: boolean) => { if (valid) { if (dialogStatus.value === 'create') { createData() } else if (dialogStatus.value === 'update') { updateData() } } }) } } // 新增数据 function createData() { btnLoading.value = true if (useApproval.value !== 'true') { addResource(formData.value).then((res) => { ElMessageBox.confirm( '新增成功,是否继续新增?', '提示', { confirmButtonText: '是', cancelButtonText: '否', type: 'info', }, ).then(() => { resetForm() nextTick(() => { console.log('clearValidate') dataFormRef.value?.clearValidate(['name', 'url']) fetchResourceTree() }) }).catch(() => { closeRefresh() }) btnLoading.value = false }).catch((_) => { btnLoading.value = false }) } else { const params = { jsonContext: formData.value, // 操作内容 operationRemark: '资源新增', // 操作备注 title: '资源新增', // 申请标题 status: '0', operationType: 'resource_add', id: '', } approvalAdd(params).then(() => { ElMessage.success('审批提交成功,请耐心等待审批!') resetForm() nextTick(() => { console.log('clearValidate') dataFormRef.value?.clearValidate(['name', 'url']) btnLoading.value = false fetchResourceTree() closeRefresh() }) }).catch(() => { ElMessage.warning('审批提交失败,请重新申请或联系管理员!') btnLoading.value = false }) } } // 更新数据 function updateData() { if (useApproval.value !== 'true') { updateResource(formData.value).then((res) => { ElMessage.success('修改成功') fetchResourceTree() btnLoading.value = false closeRefresh() }).catch((_) => { // 异常情况,loading置为false btnLoading.value = false }) } else { const params = { jsonContext: formData.value, // 操作内容 operationRemark: '资源修改', // 操作备注 title: '资源修改', // 申请标题 status: '0', operationType: 'resource_update', id: '', } approvalAdd(params).then(() => { ElMessage.success('审批提交成功,请耐心等待审批!') closeRefresh() }).catch(() => { ElMessage.warning('审批提交失败,请重新申请或联系管理员!') btnLoading.value = false }) } } // 重置表单 function resetForm() { formData.value = { name: '', id: '', url: '', code: '', pid: '', resourceType: '', bizType: '', // 业务类型 num: 0, icon: '', } console.log('resetForm') nextTick(() => { dataFormRef.value?.clearValidate() }) } // 树列表配置 const resourceTreeProps = { parent: 'pid', value: 'id', label: 'name', children: 'children', } const resourceTree: Ref<ResourceInfo[]> = ref([]) // 获取资源树列表 function fetchResourceTree() { getResourceTreeList().then((response) => { if (response.data) { resourceTree.value = toTreeList(response.data, '0', true) } }) } // const filterTree = (value: string, data: { name: string }) => data.name?.includes(value) onBeforeMount(() => { fetchResourceTree() }) // ----------初始化、关闭对话框相关----------------- function initDialog(dialogstatus: string, row: ResourceInfo, useApprovalParam = '') { dialogStatus.value = dialogstatus useApproval.value = useApprovalParam dialogVisible.value = true btnLoading.value = false if (dialogstatus === 'create') { resetForm() nextTick(() => { dataFormRef.value?.clearValidate() }) } else if (dialogstatus === 'update' || dialogstatus === 'detail') { formData.value = { id: row.id, name: row.name, url: row.url, code: row.code, pid: row.pid, resourceType: row.resourceType, bizType: row.bizType, // 业务类型 num: row.num, icon: row.icon, } if (dialogstatus === 'detail') { getResourceTypeList().then((res) => { resourceTypeList.value = res.data }) } } } // 关闭并刷新 function closeRefresh() { dialogVisible.value = false resetForm() emits('closeRefresh') } // 关闭弹窗 function dialogClose() { dialogVisible.value = false resetForm() } // ----------------------- 以下是暴露的方法内容 ---------------------------- 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="80px" class="form-container" size="default" @submit.prevent > <el-row :gutter="10"> <el-col :span="12" class="grid-cell"> <el-form-item label="资源名称" prop="name" class="required"> <el-input v-model="formData.name" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="资源路径" prop="url" class="required"> <el-input v-model="formData.url" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="资源编码" prop="code" class="required"> <el-input v-model="formData.code" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="父资源" prop="pid" class="required"> <el-tree-select v-model="formData.pid" :data="resourceTree" node-key="id" :filter-node-method="filterTree" :props="resourceTreeProps" :expand-on-click-node="false" :render-after-expand="false" check-strictly check-on-click-node filterable class="full-width-input" :disabled="dialogStatus === 'detail'" /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="资源类型" prop="resourceType" class="required"> <el-select v-model="formData.resourceType" :disabled="dialogStatus === 'detail'" class="full-width-input" clearable placeholder="请选择"> <el-option v-for="(item, index) in resourceTypeList" :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="bizType" class="required"> <el-select v-model="formData.bizType" :disabled="dialogStatus === 'detail'" class="full-width-input" clearable placeholder="请选择"> <el-option v-for="(item, index) in bizTypeList" :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" :disabled="dialogStatus === 'detail'" /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="图标" prop="icon"> <el-input v-model="formData.icon" :disabled="dialogStatus === 'detail'" type="text" placeholder="非必填" clearable /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> <el-button v-if="dialogStatus !== 'detail'" :loading="btnLoading" type="primary" @click="submitForm"> 保存 </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>