383 lines
11 KiB
JavaScript
383 lines
11 KiB
JavaScript
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="if(${d.data.fisvitual}==1) return;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="if(${
|
||
d.data.fisvitual
|
||
}==1) return;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="if(${
|
||
d.data.fisvitual
|
||
}==1) return;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);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const handleSynchronous = (requestData) => {
|
||
let api = '/api/bs/hrmorganization/orgchart/synchronousData';
|
||
fetch(api)
|
||
.then((res) => res.json())
|
||
.then((data) => {
|
||
if (data.code == 200) {
|
||
message.success('同步成功,请重新查询');
|
||
} else {
|
||
message.error('数据同步失败');
|
||
}
|
||
//this.handleSearch(requestData);
|
||
});
|
||
};
|
||
|
||
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);
|
||
}}
|
||
onSynchronous={(requestData) => {
|
||
handleSynchronous(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>
|
||
)
|
||
);
|
||
}
|