feat: 完成部门管理前端页面
功能: - dept.js API文件:部门CRUD接口 - dept.vue 页面:树形表格展示部门层级 - 支持添加子部门、编辑、删除 - 上级部门选择(树形下拉) - 表单验证和错误处理 - 路由配置:/system/dept
This commit is contained in:
parent
29207d2e3c
commit
bcd163a093
64
fund-admin/src/api/dept.js
Normal file
64
fund-admin/src/api/dept.js
Normal file
@ -0,0 +1,64 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
/**
|
||||
* 获取部门树
|
||||
*/
|
||||
export const getDeptTree = () => {
|
||||
return request({
|
||||
url: '/sys/api/v1/dept/tree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门列表
|
||||
*/
|
||||
export const getDeptList = (params) => {
|
||||
return request({
|
||||
url: '/sys/api/v1/dept/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门详情
|
||||
*/
|
||||
export const getDeptById = (id) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/dept/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建部门
|
||||
*/
|
||||
export const createDept = (data) => {
|
||||
return request({
|
||||
url: '/sys/api/v1/dept',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新部门
|
||||
*/
|
||||
export const updateDept = (id, data) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/dept/${id}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
*/
|
||||
export const deleteDept = (id) => {
|
||||
return request({
|
||||
url: `/sys/api/v1/dept/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@ -31,6 +31,12 @@ const routes = [
|
||||
component: () => import('../views/system/user.vue'),
|
||||
meta: { title: '用户管理' }
|
||||
},
|
||||
{
|
||||
path: 'dept',
|
||||
name: 'Dept',
|
||||
component: () => import('../views/system/dept.vue'),
|
||||
meta: { title: '部门管理' }
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'Role',
|
||||
|
||||
257
fund-admin/src/views/system/dept.vue
Normal file
257
fund-admin/src/views/system/dept.vue
Normal file
@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>部门管理</span>
|
||||
<el-button type="primary" @click="handleAdd(null)">新增部门</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table
|
||||
:data="tableData"
|
||||
row-key="deptId"
|
||||
border
|
||||
v-loading="loading"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
default-expand-all
|
||||
>
|
||||
<el-table-column prop="deptName" label="部门名称" width="250" />
|
||||
<el-table-column prop="deptCode" label="部门编码" width="150" />
|
||||
<el-table-column prop="leader" label="负责人" width="120" />
|
||||
<el-table-column prop="phone" label="联系电话" width="140" />
|
||||
<el-table-column prop="email" label="邮箱" width="200" />
|
||||
<el-table-column prop="sortOrder" label="排序" width="80" align="center" />
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
||||
{{ scope.row.status === 1 ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleAdd(scope.row)">添加子部门</el-button>
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="上级部门">
|
||||
<el-tree-select
|
||||
v-model="form.parentId"
|
||||
:data="deptTreeOptions"
|
||||
:props="{ label: 'deptName', value: 'deptId', children: 'children' }"
|
||||
placeholder="请选择上级部门"
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="部门名称" prop="deptName">
|
||||
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="部门编码" prop="deptCode">
|
||||
<el-input v-model="form.deptCode" placeholder="请输入部门编码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="负责人">
|
||||
<el-input v-model="form.leader" placeholder="请输入负责人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="排序">
|
||||
<el-input-number v-model="form.sortOrder" :min="0" :max="999" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getDeptTree, createDept, updateDept, deleteDept } from '../../api/dept'
|
||||
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
const deptTreeOptions = ref([])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formRef = ref(null)
|
||||
const form = reactive({
|
||||
deptId: null,
|
||||
parentId: 0,
|
||||
deptName: '',
|
||||
deptCode: '',
|
||||
leader: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
sortOrder: 0,
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
deptName: [{ required: true, message: '请输入部门名称', trigger: 'blur' }],
|
||||
deptCode: [{ required: true, message: '请输入部门编码', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
// 加载部门树
|
||||
const loadDeptTree = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDeptTree()
|
||||
tableData.value = res || []
|
||||
|
||||
// 构建部门树选项(用于上级部门选择)
|
||||
deptTreeOptions.value = [
|
||||
{ deptId: 0, deptName: '顶级部门', children: res || [] }
|
||||
]
|
||||
} catch (error) {
|
||||
console.error('加载部门树失败:', error)
|
||||
ElMessage.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 新增部门
|
||||
const handleAdd = (row) => {
|
||||
dialogTitle.value = row ? '添加子部门' : '新增部门'
|
||||
resetForm()
|
||||
if (row) {
|
||||
form.parentId = row.deptId
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 编辑部门
|
||||
const handleEdit = (row) => {
|
||||
dialogTitle.value = '编辑部门'
|
||||
resetForm()
|
||||
Object.assign(form, {
|
||||
deptId: row.deptId,
|
||||
parentId: row.parentId,
|
||||
deptName: row.deptName,
|
||||
deptCode: row.deptCode,
|
||||
leader: row.leader,
|
||||
phone: row.phone,
|
||||
email: row.email,
|
||||
sortOrder: row.sortOrder,
|
||||
remark: row.remark
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
form.deptId = null
|
||||
form.parentId = 0
|
||||
form.deptName = ''
|
||||
form.deptCode = ''
|
||||
form.leader = ''
|
||||
form.phone = ''
|
||||
form.email = ''
|
||||
form.sortOrder = 0
|
||||
form.remark = ''
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
} catch (error) {
|
||||
ElMessage.warning('请检查表单填写是否完整')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (form.deptId) {
|
||||
await updateDept(form.deptId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createDept(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
await loadDeptTree()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
ElMessage.error(error.message || '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确定要删除该部门吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteDept(row.deptId)
|
||||
ElMessage.success('删除成功')
|
||||
await loadDeptTree()
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
ElMessage.error(error.message || '删除失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadDeptTree()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user