feat(system/dept): 部门管理新增组织架构视图

This commit is contained in:
KAI
2025-01-09 08:48:08 +00:00
committed by Charles7c
parent 113c6e3a71
commit 4b61e4027e
5 changed files with 119 additions and 6 deletions

View File

@@ -56,6 +56,7 @@
"vue-echarts": "^6.5.5",
"vue-json-pretty": "^2.4.0",
"vue-router": "^4.3.3",
"vue3-tree-org": "^4.2.2",
"xe-utils": "^3.5.7",
"xgplayer": "^2.31.6"
},

18
pnpm-lock.yaml generated
View File

@@ -134,6 +134,9 @@ importers:
vue-router:
specifier: ^4.3.3
version: 4.3.3(vue@3.5.12(typescript@5.0.4))
vue3-tree-org:
specifier: ^4.2.2
version: 4.2.2(vue@3.5.12(typescript@5.0.4))
xe-utils:
specifier: ^3.5.7
version: 3.5.26
@@ -1839,6 +1842,9 @@ packages:
core-js-compat@3.37.1:
resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==}
core-js@3.40.0:
resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==}
cors@2.8.5:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
@@ -4625,6 +4631,11 @@ packages:
peerDependencies:
typescript: '*'
vue3-tree-org@4.2.2:
resolution: {integrity: sha512-AG2SykyD6dw0jIyqBm8iuF9j9GWli6KrwudxR1RjULCCBTDFsoNm7MmP/weKT7wowN/sPk+e2RsnvEJMw2OJMw==}
peerDependencies:
vue: ^3.0.0
vue@3.5.12:
resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==}
peerDependencies:
@@ -6587,6 +6598,8 @@ snapshots:
dependencies:
browserslist: 4.23.0
core-js@3.40.0: {}
cors@2.8.5:
dependencies:
object-assign: 4.1.1
@@ -9618,6 +9631,11 @@ snapshots:
semver: 7.6.2
typescript: 5.0.4
vue3-tree-org@4.2.2(vue@3.5.12(typescript@5.0.4)):
dependencies:
core-js: 3.40.0
vue: 3.5.12(typescript@5.0.4)
vue@3.5.12(typescript@5.0.4):
dependencies:
'@vue/compiler-dom': 3.5.12

View File

@@ -5,7 +5,7 @@ import type { LabelValueState } from '@/types/global'
const BASE_URL = '/common'
/** @desc 查询部门树 */
export function listDeptTree(query: { description: string }) {
export function listDeptTree(query: { description: string | unknown }) {
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query)
}

View File

@@ -32,5 +32,5 @@ export function deleteDept(id: string) {
/** @desc 导出部门 */
export function exportDept(query: T.DeptQuery) {
return http.download<any>(`${BASE_URL}/export`, query)
return http.download(`${BASE_URL}/export`, query)
}

View File

@@ -1,6 +1,13 @@
<template>
<div class="table-page">
<div class="header-actions">
<a-radio-group v-model="viewType" type="button" size="small" style="margin-bottom: 16px;">
<a-radio value="table">表格视图</a-radio>
<a-radio value="tree">组织架构图</a-radio>
</a-radio-group>
</div>
<GiTable
v-show="viewType === 'table'"
ref="tableRef"
title="部门管理"
row-key="id"
@@ -58,12 +65,36 @@
</a-space>
</template>
</GiTable>
<!-- 组织架构图视图 -->
<div v-show="viewType === 'tree'">
<a-card>
<a-dropdown trigger="contextMenu">
<Vue3TreeOrg
v-if="dataList.length"
:data="dataList[0]"
:collapsable="true"
:horizontal="false"
:define-menus="menus"
:expand-all="true"
:default-expand-level="999"
:props="{ id: 'id', parentId: 'parentId', label: 'name', children: 'children' }"
center
:node-add="handleAdd"
:node-delete="onDelete"
:node-edit="onUpdate"
@on-expand-all="bool => nodeExpandAll = bool"
>
</Vue3TreeOrg>
</a-dropdown>
</a-card>
</div>
<DeptAddModal ref="DeptAddModalRef" :depts="dataList" @save-success="search" />
</div>
</template>
<script setup lang="ts">
import 'vue3-tree-org/lib/vue3-tree-org.css'
import { Vue3TreeOrg } from 'vue3-tree-org'
import DeptAddModal from './DeptAddModal.vue'
import { type DeptQuery, type DeptResp, deleteDept, exportDept, listDept } from '@/apis/system/dept'
import type { TableInstanceColumns } from '@/components/GiTable/type'
@@ -89,7 +120,16 @@ const {
})
},
})
// 查看视图类型
const viewType = ref('table')
// 组织架构图右键菜单
const menus = [
{ name: '添加部门', command: 'add' },
{ name: '编辑部门', command: 'edit' },
{ name: '删除部门', command: 'delete' },
]
// 所有节点展开状态
const nodeExpandAll = ref<boolean>(true)
// 过滤树
const searchData = (name: string) => {
const loop = (data: DeptResp[]) => {
@@ -162,11 +202,65 @@ const DeptAddModalRef = ref<InstanceType<typeof DeptAddModal>>()
const onAdd = (parentId?: string) => {
DeptAddModalRef.value?.onAdd(parentId)
}
const handleAdd = (record: DeptResp) => {
onAdd(record.id)
}
// 修改
const onUpdate = (record: DeptResp) => {
DeptAddModalRef.value?.onUpdate(record.id)
}
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
:deep(.zm-draggable) {
margin-top: 4px;
}
:deep(.zm-tree-org .zoom-container) {
background-color: var(--color-bg-1);
color: var(--color-text-1);
}
:deep(.tree-org-node__content) {
background-color: var(--color-bg-2);
color: var(--color-text-1);
cursor: pointer;
position: relative;
}
.zm-tree-org {
background-color: var(--color-bg-1);
height: calc(100vh - 265px);
}
:global(.zm-tree-contextmenu) {
color: var(--color-text-1) !important;
position: fixed !important;
background: var(--color-bg-2) !important;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1) !important;
border: 1px solid var(--color-border) !important;
border-radius: 4px !important;
padding: 4px 0 !important;
min-width: 120px !important;
z-index: 999 !important;
ul {
background: var(--color-bg-1) !important;
list-style-type: none !important;
padding: 10px !important;
margin: 0 !important;
}
.zm-tree-menu-item {
background-color: var(--color-bg-1) !important;
padding: 5px 15px !important;
margin-top: 10px !important;
cursor: pointer !important;
transition: background-color 0.1s ease !important;
list-style: none !important;
}
}
:deep(.tree-org-node__expand){
background-color: var(--color-bg-1) !important;
}
</style>