You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vue3-org-chart/src/views/organization-chart.vue

229 lines
6.2 KiB
Vue

<template>
<div style="display: flex; padding: 10px;">
<div style="margin-right: 10px"><el-switch v-model="horizontal"></el-switch> 横向</div>
<div style="margin-right: 10px">
维度:
<el-select v-model="params.virtualType" class="m-2" placeholder="Select" @change="handleSelectChange">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div style="margin-right: 10px">
根节点:
<el-tree-select
v-model="params.root"
:data="rootData"
check-strictly
:render-after-expand="false"
style="width: 240px"
@change="handleRootChange"
/>
</div>
<div style="margin-right: 10px">
层级:
<el-select v-model="params.level" class="m-2" placeholder="Select" @change="handleLevelChange">
<el-option
v-for="item in levelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div style="margin-right: 10px"><el-button @click="exportToPDF" type="primary">导出PDF</el-button></div>
<div style="margin-right: 10px"><el-button @click="exportImage" type="primary">导出图片</el-button></div>
</div>
<div id="tree-container" style="height: 600px;">
<vue3-tree-org
ref="treeChart"
:data="treeData"
center
:props="{children: 'childrens'}"
:define-menus="defineMenus"
:horizontal="horizontal"
:clone-node-drag="cloneNodeDrag"
:node-draggable="nodeDraggable"
:collapsable="collapsable"
:label-style="style"
@on-expand="onExpand"
@on-node-click="onNodeClick"
/>
</div>
<view-dialog ref="viewDialog"/>
</template>
<script>
import { ElSwitch, ElButton, ElMessage,ElSelect,ElTreeSelect } from 'element-plus'
import html2pdf from 'html2pdf.js'
import domToImage from 'dom-to-image';
import {selectOrganizationChart,selectVirtualTop,selectRootTop,selectLevelTop} from '@/api/chart'
import ViewDialog from '@/components/ViewDialog.vue'
import { ref } from 'vue'
export default {
name: "organization-chart",
components: {
ElSwitch,
ViewDialog,
ElButton,
ElSelect,
ElTreeSelect
},
setup() {
const cloneNodeDrag = ref(true);
return {
cloneNodeDrag
}
},
data() {
return {
treeData:{},
horizontal: false,
collapsable: true,
onlyOneNode: false,
nodeDraggable:false,
expandAll: true,
disaled: false,
defineMenus:[],
params:{
virtualType:'',
level:'',
root:''
},
style: {
background: "#fff",
color: "#5e6d82",
fontWeight: "500"
},
options: [],
levelOptions:[],
rootData: []
};
},
async created() {
await this.virtualTop();
this.organizationChart();
this.handleRootTop(this.params.virtualType);
},
methods: {
exportImage() {
const treeOrgEl = this.$refs.treeChart.$el;
domToImage.toPng(treeOrgEl) // 转换为 PNG 格式
.then(function (dataURL) {
const link = document.createElement('a');
link.href = dataURL;
link.download = 'tree_image.png';
link.click();
link.remove();
})
.catch(function (error) {
console.error('导出图片出错:', error);
});
},
exportToPDF() {
const element = document.getElementById('tree-container') // 获取 TreeOrg 组件的容器元素
const options = {
filename: 'tree-structure.pdf', // 导出的文件名,可以根据实际需求更改
jsPDF: { format: 'a4',orientation: 'landscape',unit: 'pt', }
}
html2pdf().set(options).from(element).save();
},
virtualTop() {
return new Promise(resolve => {
selectVirtualTop(this.params).then(res=>{
this.options = res.data.data;
this.options.length > 0 ? this.params.virtualType = this.options[0].value : '';
resolve();
})
.catch(err=>{
ElMessage.error(err.msg);
})
});
},
organizationChart() {
selectOrganizationChart(this.params).then(res=>{
this.treeData = res.data.data;
this.toggleExpand(res.data.data, this.expandAll);
})
.catch(err=>{
ElMessage.error(err.msg);
})
},
handleRootTop(value) {
const params = {
"virtualType":value
}
selectRootTop(params).then(res=>{
this.rootData = res.data.data;
})
.catch(err=>{
ElMessage.error(err.msg);
});
},
handleLevelTop(value) {
const params = {
"virtualType":this.params.virtualType,
"id":value
}
selectLevelTop(params).then(res=>{
this.levelOptions = res.data.data;
})
.catch(err=>{
ElMessage.error(err.msg);
});
},
handleSelectChange(value) {
this.params.virtualType = value;
this.params.root = '';
this.params.level = '';
this.handleRootTop(value);
this.organizationChart();
},
handleLevelChange(value) {
this.params.level = value;
this.organizationChart();
},
handleRootChange(value) {
this.params.root = value;
this.params.level = '';
this.handleLevelTop(value);
this.organizationChart();
},
onExpand(e, data) {
//console.log(e, data);
},
onExpandAll(b) {
//console.log(b)
},
onNodeClick(e, data) {
this.$refs.viewDialog.openDialog(data,2);
},
expandChange() {
// this.toggleExpand(this.data, this.expandAll);
},
toggleExpand(data, val) {
if (Array.isArray(data)) {
data.forEach((item) => {
item.expand = val
if (item.childrens) {
this.toggleExpand(item.childrens, val);
}
});
} else {
data.expand = val
if (data.childrens) {
this.toggleExpand(data.childrens, val);
}
}
},
},
};
</script>