org-chart-frant/src/pages/company.jsx

361 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 } from 'antd';
let active = 'top';
export default function companyPage() {
const [data, setData] = useState(null);
const [sliderProgress, setSliderProgress] = useState(50);
let addNodeChildFunc = null;
let orgChart = null;
let topBarSearchRequest = null;
const [hasRight, setHasRight] = useState('');
// 点击节点
function onNodeClick(nodeId) {
// alert('clicked ' + 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(',');
console.log('idsStr', idsStr);
let api = '';
if (topBarSearchRequest) {
let request = { ...topBarSearchRequest, ids: idsStr };
api =
'/api/bs/hrmorganization/orgchart/asyncCompanyData' +
qs.stringify(request, { addQueryPrefix: true });
} else {
api =
'/api/bs/hrmorganization/orgchart/asyncCompanyData?fclass=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD') +
'&ids=' +
idsStr;
}
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.data) {
data.data.forEach((item) => {
window.chart.addNode(item);
});
}
});
}
}
// 获取部门图片
function getDepartmentImage() {
let index = Math.floor(Math.random() * 8) + 1;
// return `./img/department/${index}.png`;
return `./img/department/1.png`;
}
// 获取部门图片
function getSubcompanyImage() {
let index = Math.floor(Math.random() * 3) + 1;
// return `./img/subcompany/${index}.png`;
return `./img/subcompany/2.png`;
}
// 获取数据
useEffect(() => {
d3.json(
// "/company/data"
'/api/bs/hrmorganization/orgchart/companyData?fclass=0&isvitual=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD'),
).then((data) => {
setData(data.data);
setHasRight(data?.hasRight);
});
}, [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 160;
} else if (d.data.ftype == 2) {
return 56;
}
return 120;
};
const nodeContentRender = (d, i, arr, state) => {
// 集团地址
let companyUrl =
'/spa/organization/static/index.html#/main/organization/group';
// 分部地址
let subcompanyUrl = `/spa/organization/static/index.html#/main/organization/companyExtend/${d.data.fobjid}`;
// 部门地址
let departmentUrl = `/spa/organization/static/index.html#/main/organization/departmentExtend/${d.data.fobjid}`;
if (d.data.ftype == 0) {
return `<div onclick="window.open('${companyUrl}', '_blank')" 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('${subcompanyUrl}', '_blank')">
<div style="width: 85px; height: 85px; border: 1px solid #66BAF5; border-radius: 50%;text-align: center; line-height: 85px; margin: 0 auto;display:flex;justify-content:center;align-items:center">
<img src="${getSubcompanyImage()}" />
</div>
<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) {
return `
<div style="width: 100%; height: 100%; background-size: 100% 100%;" onclick="window.open('${departmentUrl}')">
<div style='position:absolute'>
<img src='./img/company_job_label.png'/></div>
<div style="padding-left: 8px; padding-top: 23px;display:flex;align-items:center">
<img src="${getDepartmentImage()}"/>
<span style="
margin-left: 3px;
font-size: 12px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400;
color: #333333;
">${d.data.fname}</span>
</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);
};
// tool bar end
// top bar start
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 });
} else {
orgChart && downloadPdf(orgChart);
}
};
const handleSearch = (requestData) => {
topBarSearchRequest = requestData;
let api =
'/api/bs/hrmorganization/orgchart/companyData' +
qs.stringify(requestData, { addQueryPrefix: true });
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.data) {
if (!data.data.length) {
setData([{}]);
message.warning('暂无数据');
} else {
setData(data?.data);
}
}
});
};
useEffect(() => {
console.log('data', data);
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]);
// top bar end
if (hasRight === false) {
//return message.error("对不起,您暂时没有权限", 2);
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/bs/hrmorganization/orgchart/getCondition?type=company"
/>
<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>
)
);
}