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.
org-chart-frant/src/pages/company.jsx

360 lines
10 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import styles from './index.less';
import React, { useEffect, useState } from 'react';
import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3';
import { TopBar } from '../components/topBar';
import ToolBar from '../components/toolBar';
import jsPDF from 'jspdf';
import moment from 'moment';
import qs from 'qs';
import { message, Tooltip } from 'antd';
let active = 'top';
export default function companyPage() {
const [data, setData] = useState(null);
let addNodeChildFunc = null;
let orgChart = null;
let topBarSearchRequest = null;
const [hasRight, setHasRight] = useState('');
// 点击节点
function onNodeClick(nodeId) {}
// 扩展按钮点击
function onButtonClick(event, d) {
if (d.children) {
let idsList = [];
d.children.forEach((item) => {
if (item.data.hasChildren && !item._children) {
idsList.push(item.data.id);
}
});
if (idsList.length == 0) {
return;
}
let idsStr = idsList.join(',');
let api = '';
if (topBarSearchRequest) {
let request = { ...topBarSearchRequest, ids: idsStr };
api =
'/api/ais/orgChart/asyncCompanyData' +
qs.stringify(request, { addQueryPrefix: true });
} else {
api =
'/api/ais/orgChart/asyncCompanyData?level=0&date=' +
moment(new Date()).format('YYYY-MM-DD') +
'&ids=' +
idsStr;
}
fetch(api)
.then((res) => res.json())
.then((resp) => {
if (resp.data.data) {
resp.data.data.forEach((item) => {
window.chart.addNode(item);
});
}
});
}
}
// 获取层级图片
function getLevelImage(deptLevel, isVirtual) {
switch (deptLevel) {
case '0':
return isVirtual == 0
? `./img/company/level1.png`
: `./img/company/level5.png`;
case '1':
return isVirtual == 0
? `./img/company/level2.png`
: `./img/company/level6.png`;
case '2':
return isVirtual == 0
? `./img/company/level3.png`
: `./img/company/level7.png`;
case '3':
return isVirtual == 0
? `./img/company/level4.png`
: `./img/company/level8.png`;
default:
return isVirtual == 0
? `./img/company/level4.png`
: `./img/company/level8.png`;
}
}
//获取数据
useEffect(() => {
d3.json(
'/api/ais/orgChart/companyData?level=0&date=' +
moment(new Date()).format('YYYY-MM-DD'),
).then((resp) => {
setData(resp.data.data);
setHasRight('true');
});
}, [true]);
// ButtonContent渲染
const buttonContentRender = ({ node, state }) => {
if (node.children) {
return `<div style="border-radius:3px;padding:3px;font-size:10px;margin:auto auto;background-color:#66BAF5"> <div style="margin-top:0px;line-height:1.35;height:11px;font-size:25px; color: #fff;">ˆ</div> </div>`;
} else {
return `<div style="border-radius:3px;padding:3px;font-size:10px;margin:auto auto;background-color:#66BAF5"> <div style="margin-top:0px;line-height:1.35;height:11px;font-size:25px; color: #fff;transform:rotate(180deg)">ˆ</div> </div>`;
}
};
// 节点宽度渲染
const nodeWidthRender = (d) => {
if (d.data.ftype == 0) {
return 1000;
} else if (d.data.ftype == 1) {
return 160;
} else if (d.data.ftype == 2) {
return 144;
}
return 200;
};
const nodeHeightRender = (d) => {
if (d.data.ftype == 0) {
return 100;
} else if (d.data.ftype == 1) {
return 80;
} else if (d.data.ftype == 2) {
return 106;
}
return 120;
};
const nodeContentRender = (d, i, arr, state) => {
if (d.data.ftype == 0) {
return `<div style="text-align:center">
<div style="display: inline-block; vertical-align: top;">
<img src="./img/company.png" />
</div>
<div style="display: inline-block; text-align: center; margin-left: 5px;">
<div style="
font-size: 24px;
font-family: Microsoft YaHei-Bold, Microsoft YaHei;
font-weight: bold;
color: #000000;
line-height: 28px;
letter-spacing: 1px;
margin-top: 10px;
">${d.data.fname}</div>
</div>
</div>`;
} else if (d.data.ftype == 1) {
return `<div onclick="window.open('${d.data.url}', '_blank')">
<div style="width: 136px; border: 1px solid #66BAF5; margin: 10px auto 0px; border-radius: 23px; text-align: center;
font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #333333;
line-height: 18px;
padding: 15px 10px;
">
${d.data.fname}
</div>
</div>`;
} else if (d.data.ftype == 2) {
let one = d.data.leader == '' ? 'none' : 'inline-block';
let three = d.data.deputyLeader == '' ? 'none' : 'inline-block';
let two = d.data.header == '' ? 'none' : 'block';
return `
<div style="width: 100%; height: 100%; background-size: 100% 100%;" >
<div style='position:absolute;height:100%'>
<img style='width:144px;height:106px' src="${getLevelImage(
d.data.deptLevel,
d.data.isVirtual,
)}"/></div>
<div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 12px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;color: #333333;text-align: center;">
<div title=${
d.data.fname
} style="width: 110px;margin: 0 auto;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:ellipsis;
line-height: 18px;word-break: break-all;">${d.data.fname}</div>
<div style="width: 130px;margin: 0 auto;line-height: 18px;display:${two}">分管领导:${
d.data.header
} </div>
<div style="width: 120px;margin: 0 auto;line-height: 18px;display:${one}">
<span style="display:${one}">${
d.data.leader
}</span><span style="display:${three}"> &nbsp;|| ${
d.data.deputyLeader
}</span></div>
</div>
</div>
`;
}
return `<div>${d.data.fname}</div>`;
};
// tool bar start
const handleTopLayoutClick = (progressBtn) => {
progressBtn.current.style.top = 50 + 'px';
orgChart &&
orgChart
.layout('top')
.setCentered(orgChart.getChartState().root.id)
.render();
active = 'top';
};
const handleLeftLayoutClick = (progressBtn) => {
progressBtn.current.style.top = 50 + 'px';
orgChart &&
orgChart
.layout('left')
.setCentered(orgChart.getChartState().root.id)
.render();
active = 'left';
};
const handleZoomIn = (progressBtn) => {
if (progressBtn) {
let top = parseInt(progressBtn.current.style.top) - 10;
if (top >= 0) {
progressBtn.current.style.top = top + 'px';
} else {
return;
}
}
orgChart && orgChart.zoomIn();
};
const handleZoomOut = (progressBtn) => {
if (progressBtn) {
let top = parseInt(progressBtn.current.style.top) + 10;
if (top <= 100) {
progressBtn.current.style.top = top + 'px';
} else {
return;
}
}
orgChart && orgChart.zoomOut();
};
const handleZoomBehavior = (value) => {
orgChart && orgChart.zoomBehavior(value - 50);
};
function downloadPdf(chart) {
chart.exportImg({
save: false,
full: true,
onLoad: (base64) => {
var pdf = new jsPDF();
var img = new Image();
img.src = base64;
img.onload = function () {
pdf.addImage(
img,
'JPEG',
5,
5,
595 / 3,
((img.height / img.width) * 595) / 3,
);
pdf.save('chart.pdf');
};
},
});
}
const handleExport = (type) => {
if (type == 'png') {
orgChart && orgChart.exportImg({ full: true, scale: 12 });
} else {
orgChart && downloadPdf(orgChart);
}
};
const handleSearch = (requestData) => {
topBarSearchRequest = requestData;
let api =
'/api/ais/orgChart/companyData' +
qs.stringify(requestData, { addQueryPrefix: true });
fetch(api)
.then((res) => res.json())
.then((resp) => {
if (resp.status) {
if (!resp.data.data.length) {
setData([{}]);
message.warning('暂无数据');
} else {
setData(resp.data.data);
}
}
});
};
useEffect(() => {
if (active == 'left') {
orgChart &&
orgChart
.setCentered(orgChart.getChartState().root?.id)
.layout('left')
.render();
} else {
orgChart &&
orgChart
.setCentered(orgChart.getChartState().root?.id)
.layout('top')
.render();
}
}, [data]);
if (hasRight === false) {
return (
<div style={{ width: '100%', top: '40%', position: 'absolute' }}>
<img
style={{ display: 'block', margin: '0 auto' }}
src="./img/permission.png"
/>
<p style={{ textAlign: 'center' }}>对不起您暂时没有权限!</p>
</div>
);
}
return (
hasRight && (
<div className={styles.contentWrapper}>
<TopBar
onExport={(type) => {
handleExport(type);
}}
onSearch={(requestData) => {
handleSearch(requestData);
}}
type="company"
url="/api/ais/orgChart/getSearchCondition"
/>
<ToolBar
onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)}
onLeftLayoutClick={(progressBtn) =>
handleLeftLayoutClick(progressBtn)
}
onZoomOut={(progressBtn) => handleZoomOut(progressBtn)}
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
onZoomBehavior={(value) => handleZoomBehavior(value)}
/>
<OrgChartComponent
setChart={(chart) => (orgChart = chart)}
setClick={(click) => (addNodeChildFunc = click)}
onNodeClick={onNodeClick}
data={data}
onButtonClick={onButtonClick}
buttonContent={buttonContentRender}
nodeWidth={nodeWidthRender}
nodeHeight={nodeHeightRender}
nodeContent={nodeContentRender}
/>
</div>
)
);
}