第三十二节:部门组织管理(el‑tree 组织树

第三十二节:部门组织管理(el‑tree 组织树)

目标:实现部门树形管理,新增、编辑、删除部门;后续用户管理页面可以选择归属部门。

业务:部门是树形层级结构,支持一级部门、二级子部门。

1、mock 接口 src/mock/index.js

复制代码
// 获取全部部门树
'/api/dept/tree': () => {
  return {
    code: 200,
    data: [
      {
        id: 1,
        deptName: '总公司',
        parentId: 0,
        children: [
          { id:11, deptName:'研发部', parentId:1, children:[] },
          { id:12, deptName:'市场部', parentId:1, children:[] }
        ]
      }
    ]
  }
},
//新增部门
'/api/dept/add':({body})=>{
  return {code:200,msg:'新增部门成功'}
},
//编辑部门
'/api/dept/update':({body})=>{
  return {code:200,msg:'编辑部门成功'}
},
//删除部门
'/api/dept/remove':({body})=>{
  return {code:200,msg:'删除部门成功'}
}

2、新建 api/dept.js

复制代码
import request from '@/utils/request'

//获取部门树
export function getDeptTree(){
  return request({url:'/api/dept/tree',method:'get'})
}
//新增部门
export function addDept(data){
  return request({url:'/api/dept/add',method:'post',data})
}
//编辑部门
export function updateDept(data){
  return request({url:'/api/dept/update',method:'post',data})
}
//删除部门
export function deleteDept(data){
  return request({url:'/api/dept/remove',method:'post',data})
}

3、封装部门弹窗组件 src/views/system/dept/components/DeptDialog.vue

复制代码
<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isEdit ? '编辑部门' : '新增部门'"
    width="460px"
    @close="handleClose"
  >
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="90px">
      <el-form-item prop="deptName" label="部门名称">
        <el-input v-model="formData.deptName" placeholder="请输入部门名称"/>
      </el-form-item>
      <el-form-item prop="parentId" label="上级部门">
        <!-- 简易下拉选择父部门,真实项目这里可以用el‑tree‑select -->
        <el-select v-model="formData.parentId" placeholder="选择上级部门">
          <el-option label="无(顶级部门)" :value="0"/>
          <el-option label="总公司" :value="1"/>
          <el-option label="研发部" :value="11"/>
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible=false">取消</el-button>
      <el-button type="primary" @click="submitForm">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import {ref,watch} from 'vue'
import { ElMessage } from 'element-plus'

const props = defineProps({
  visible:{type:Boolean,default:false},
  rowData:{type:Object,default:null}
})
const emit = defineEmits(['update:visible','success'])

const dialogVisible = ref(false)
const formRef = ref(null)
const isEdit = ref(false)

const formData = ref({
  id:null,
  deptName:'',
  parentId:0
})

const formRules = ref({
  deptName:[{required:true,message:'请输入部门名称',trigger:'blur'}]
})

watch(()=>props.visible,val=>{
  dialogVisible.value = val
  if(val){
    openDialog()
  }
})

function openDialog(){
  formRef.value?.resetFields()
  if(props.rowData){
    isEdit.value = true
    formData.value = {...props.rowData}
  }else{
    isEdit.value = false
    formData.value = {id:null,deptName:'',parentId:0}
  }
}

async function submitForm(){
  await formRef.value.validate()
  emit('success',{form:formData.value,isEdit:isEdit.value})
  dialogVisible.value = false
}

function handleClose(){
  emit('update:visible',false)
}
</script>

4、部门管理主页面 src/views/system/dept/index.vue

复制代码
<template>
  <div class="dept-page">
    <h2>部门管理</h2>
    <div style="margin:12px 0;">
      <el-button type="primary" @click="openAdd">新增部门</el-button>
    </div>

    <!-- 树形表格 el‑table‑tree 实现树形表格 -->
    <el-table
      :data="deptTreeData"
      row-key="id"
      border
    >
      <el-table-column label="部门名称" prop="deptName"/>
      <el-table-column label="上级ID" prop="parentId"/>
      <el-table-column label="操作">
        <template #default="scope">
          <el-link type="primary" @click="openEdit(scope.row)">编辑</el-link>
          <el-link type="danger" style="margin‑left:10px" @click="handleDelete(scope.row)">删除</el-link>
        </template>
      </el-table-column>
    </el-table>

    <DeptDialog
      v-model:visible="dialogShow"
      :row-data="currentRow"
      @success="handleDialogSuccess"
    />
  </div>
</template>

<script setup>
import {ref,onMounted} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import DeptDialog from './components/DeptDialog.vue'
import {getDeptTree,addDept,updateDept,deleteDept} from '@/api/dept'

const deptTreeData = ref([])
const dialogShow = ref(false)
const currentRow = ref(null)

async function getDeptList(){
  const res = await getDeptTree()
  deptTreeData.value = res.data
}

function openAdd(){
  currentRow.value = null
  dialogShow.value = true
}
function openEdit(row){
  currentRow.value = row
  dialogShow.value = true
}

async function handleDialogSuccess({form,isEdit}){
  if(isEdit){
    await updateDept(form)
    ElMessage.success('编辑部门成功')
  }else{
    await addDept(form)
    ElMessage.success('新增部门成功')
  }
  getDeptList()
}

async function handleDelete(row){
  ElMessageBox.confirm('确定删除该部门?','提示',{type:'warning'})
  .then(async ()=>{
    await deleteDept({id:row.id})
    ElMessage.success('删除成功')
    getDeptList()
  }).catch(()=>{})
}

onMounted(()=>{
  getDeptList()
})
</script>

5、路由配置新增部门管理路由

打开router/index.js,在后端动态返回的菜单 mock 中增加部门管理路由。

复制代码
{
  path:'/system/dept',
  component:'/system/dept/index',
  meta:{title:'部门管理',icon:'OfficeBuilding'}
}

测试

  1. 进入部门管理页面,树形表格渲染,父子部门层级展示
  2. 新增顶级部门、新增子部门;编辑、删除部门,mock 接收请求。
相关推荐
leoZ2311 小时前
第 7 篇:进阶——校验、联动、列表页
开发语言·前端·javascript·vue.js·人工智能·目标检测·ecmascript
VeryCool1 小时前
别吹了,依赖图像识别的GPT‑6 Astra永远快不起来
前端·javascript·aigc
hunterandroid1 小时前
Android 测试全景:从单元测试到 UI 自动化的完整实践
android·前端
leoZ2311 小时前
第 8 篇:与 AI 协作的工作流 + 完整案例
前端·人工智能·神经网络·自然语言处理·性能优化·c#·php
背对疾风1 小时前
提前还贷,缩短年限和降低月供其实是一样的
前端
2501_928996222 小时前
Agent 开发 API 选型:硅碳相变下 Function Calling 兼容性与多模型路由拆解
前端
invicinble2 小时前
做数字产品的核心内容--数据的设计与展示
大数据·前端
LabVIEW开发2 小时前
LabVIEW运行时动态修改控件标题
前端·labview·labview知识·labview功能·labview程序
晴天162 小时前
ES6+ 核心语法
前端·es6·状态模式