mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-08 22:57:11 +08:00
feat(system/dept): 部门管理新增组织架构视图
This commit is contained in:
@@ -56,6 +56,7 @@
|
|||||||
"vue-echarts": "^6.5.5",
|
"vue-echarts": "^6.5.5",
|
||||||
"vue-json-pretty": "^2.4.0",
|
"vue-json-pretty": "^2.4.0",
|
||||||
"vue-router": "^4.3.3",
|
"vue-router": "^4.3.3",
|
||||||
|
"vue3-tree-org": "^4.2.2",
|
||||||
"xe-utils": "^3.5.7",
|
"xe-utils": "^3.5.7",
|
||||||
"xgplayer": "^2.31.6"
|
"xgplayer": "^2.31.6"
|
||||||
},
|
},
|
||||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -134,6 +134,9 @@ importers:
|
|||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.3.3
|
specifier: ^4.3.3
|
||||||
version: 4.3.3(vue@3.5.12(typescript@5.0.4))
|
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:
|
xe-utils:
|
||||||
specifier: ^3.5.7
|
specifier: ^3.5.7
|
||||||
version: 3.5.26
|
version: 3.5.26
|
||||||
@@ -1839,6 +1842,9 @@ packages:
|
|||||||
core-js-compat@3.37.1:
|
core-js-compat@3.37.1:
|
||||||
resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==}
|
resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==}
|
||||||
|
|
||||||
|
core-js@3.40.0:
|
||||||
|
resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@@ -4625,6 +4631,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '*'
|
typescript: '*'
|
||||||
|
|
||||||
|
vue3-tree-org@4.2.2:
|
||||||
|
resolution: {integrity: sha512-AG2SykyD6dw0jIyqBm8iuF9j9GWli6KrwudxR1RjULCCBTDFsoNm7MmP/weKT7wowN/sPk+e2RsnvEJMw2OJMw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.0.0
|
||||||
|
|
||||||
vue@3.5.12:
|
vue@3.5.12:
|
||||||
resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==}
|
resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -6587,6 +6598,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.0
|
browserslist: 4.23.0
|
||||||
|
|
||||||
|
core-js@3.40.0: {}
|
||||||
|
|
||||||
cors@2.8.5:
|
cors@2.8.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
@@ -9618,6 +9631,11 @@ snapshots:
|
|||||||
semver: 7.6.2
|
semver: 7.6.2
|
||||||
typescript: 5.0.4
|
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):
|
vue@3.5.12(typescript@5.0.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-dom': 3.5.12
|
'@vue/compiler-dom': 3.5.12
|
||||||
|
@@ -5,7 +5,7 @@ import type { LabelValueState } from '@/types/global'
|
|||||||
const BASE_URL = '/common'
|
const BASE_URL = '/common'
|
||||||
|
|
||||||
/** @desc 查询部门树 */
|
/** @desc 查询部门树 */
|
||||||
export function listDeptTree(query: { description: string }) {
|
export function listDeptTree(query: { description: string | unknown }) {
|
||||||
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query)
|
return http.get<TreeNodeData[]>(`${BASE_URL}/tree/dept`, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,5 +32,5 @@ export function deleteDept(id: string) {
|
|||||||
|
|
||||||
/** @desc 导出部门 */
|
/** @desc 导出部门 */
|
||||||
export function exportDept(query: T.DeptQuery) {
|
export function exportDept(query: T.DeptQuery) {
|
||||||
return http.download<any>(`${BASE_URL}/export`, query)
|
return http.download(`${BASE_URL}/export`, query)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="table-page">
|
<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
|
<GiTable
|
||||||
|
v-show="viewType === 'table'"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
title="部门管理"
|
title="部门管理"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
@@ -58,12 +65,36 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</GiTable>
|
</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" />
|
<DeptAddModal ref="DeptAddModalRef" :depts="dataList" @save-success="search" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 DeptAddModal from './DeptAddModal.vue'
|
||||||
import { type DeptQuery, type DeptResp, deleteDept, exportDept, listDept } from '@/apis/system/dept'
|
import { type DeptQuery, type DeptResp, deleteDept, exportDept, listDept } from '@/apis/system/dept'
|
||||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
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 searchData = (name: string) => {
|
||||||
const loop = (data: DeptResp[]) => {
|
const loop = (data: DeptResp[]) => {
|
||||||
@@ -162,11 +202,65 @@ const DeptAddModalRef = ref<InstanceType<typeof DeptAddModal>>()
|
|||||||
const onAdd = (parentId?: string) => {
|
const onAdd = (parentId?: string) => {
|
||||||
DeptAddModalRef.value?.onAdd(parentId)
|
DeptAddModalRef.value?.onAdd(parentId)
|
||||||
}
|
}
|
||||||
|
const handleAdd = (record: DeptResp) => {
|
||||||
|
onAdd(record.id)
|
||||||
|
}
|
||||||
// 修改
|
// 修改
|
||||||
const onUpdate = (record: DeptResp) => {
|
const onUpdate = (record: DeptResp) => {
|
||||||
DeptAddModalRef.value?.onUpdate(record.id)
|
DeptAddModalRef.value?.onUpdate(record.id)
|
||||||
}
|
}
|
||||||
</script>
|
</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>
|
||||||
|
Reference in New Issue
Block a user