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/components/drawer/index.jsx

449 lines
15 KiB
React

import React from 'react';
2 years ago
import {
Drawer,
Space,
Button,
Dropdown,
Menu,
Table,
Spin,
Checkbox,
} from 'antd';
import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3';
import qs from 'qs';
import { message } from 'antd';
import jsPDF from 'jspdf';
2 years ago
import ExportJsonExcel from 'js-export-excel';
2 years ago
import './index.less';
import { getLabel } from '../../util/i18n.js';
let addNodeChildFunc = null;
let orgChart = null;
let active = 'top';
export default class DrawerComponents extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
data: [],
detailType: 'chart',
params: {},
2 years ago
dataSource: [],
columns: [],
spinning: true,
12 months ago
showJob: false,
};
}
2 years ago
componentDidMount() {}
// 点击节点
12 months ago
onNodeClick(node) {
if (node.ftype == '4') {
window.open(
`/spa/hrm/index_mobx.html#/main/hrm/card/cardInfo/${node.id}`,
'_blank',
);
}
}
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;
}
}
}
// 获取部门图片
2 years ago
getDepartmentImage(fisvitual) {
return fisvitual == '0'
? `./img/user-card/user-card.png`
: `./img/user-card/user-card-blue.png`;
}
//获取数据
getDeatilDatas(params, type = 'chart', showJob = '1') {
12 months ago
this.setState({ spinning: true, data: [], dataSource: [] });
d3.json(
2 years ago
'/api/bs/hrmorganization/orgchart/getDepartmentDetail?' +
qs.stringify({ detauleType: type, ...params, showJob }),
).then((data) => {
2 years ago
//
if (type == 'chart') {
this.setState({ data: data.data, spinning: false });
} else {
12 months ago
this.setState({
dataSource: data.dataSource,
columns: data.columns,
spinning: false,
});
2 years ago
}
});
}
// ButtonContent渲染
buttonContentRender = ({ node, state }) => {
return `
<div style="margin-left: 16px; margin-top: 10px;">
<img src="./img/button_content.png" />
</div>
`;
};
// 节点宽度渲染
nodeWidthRender = (d) => {
return 280;
};
nodeHeightRender = (d) => {
return 160;
};
// tool bar start
handleTopLayoutClick = (progressBtn) => {
progressBtn.current.style.top = 50 + 'px';
orgChart &&
orgChart
.setCentered(orgChart.getChartState().root.id)
.layout('top')
.render();
active = 'top';
};
handleLeftLayoutClick = (progressBtn) => {
progressBtn.current.style.top = 50 + 'px';
orgChart &&
orgChart
.layout('left')
.setCentered(orgChart.getChartState().root.id)
.render();
active = 'left';
};
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();
};
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();
};
2 years ago
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');
};
},
});
2 years ago
};
handleExport = (e) => {
const { labelData } = this.props;
2 years ago
let type = e.key == '1' ? 'png' : e.key == '1' ? 'pdf' : 'excel';
if (type == 'png') {
orgChart && orgChart.exportImg({ full: true });
2 years ago
} else if (type == 'pdf') {
orgChart && this.downloadPdf(orgChart);
} else {
2 years ago
let { dataSource } = this.state;
var option = {};
let dataTable = [];
if (dataSource) {
for (let i in dataSource) {
if (dataSource) {
let obj = {
序号: dataSource[i].id,
工号: dataSource[i].workCode,
姓名: dataSource[i].lastName,
性别: dataSource[i].sex,
2 years ago
部门: dataSource[i].departmentName,
分部: dataSource[i].subcompanyName,
2 years ago
岗位: dataSource[i].jobTitle,
手机号: dataSource[i].mobile,
};
dataTable.push(obj);
}
}
}
option.fileName = `${getLabel(547468, labelData)}`;
2 years ago
option.datas = [
{
sheetData: dataTable,
sheetName: 'sheet',
sheetFilter: [
`${getLabel(547327, labelData)}`,
`${getLabel(547328, labelData)}`,
`${getLabel(547329, labelData)}`,
`${getLabel(547330, labelData)}`,
`${getLabel(547331, labelData)}`,
`${getLabel(547332, labelData)}`,
`${getLabel(547333, labelData)}`,
`${getLabel(547334, labelData)}`,
2 years ago
],
sheetHeader: [
`${getLabel(547327, labelData)}`,
`${getLabel(547328, labelData)}`,
`${getLabel(547329, labelData)}`,
`${getLabel(547330, labelData)}`,
`${getLabel(547331, labelData)}`,
`${getLabel(547332, labelData)}`,
`${getLabel(547333, labelData)}`,
`${getLabel(547334, labelData)}`,
2 years ago
],
},
];
var toExcel = new ExportJsonExcel(option);
toExcel.saveExcel();
}
};
/**
* 节点渲染
*/
nodeContentRender = (d, i, arr, state) => {
const { labelData } = this.props;
if (d.data.ftype == 2) {
return `<div style="position: relative;">
<div style=" height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;position:relative;z-index:2">
<div style='position:absolute;z-index:-1;top:0'>
2 years ago
<img style='width: 295px;height: 163px;' src="${this.getDepartmentImage(
d.data.fisvitual,
)}">
</div>
<div style="display: inline-block; background-size: 100% 100%; width: 35%; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;">
<img src='./img/user-card/avatar-outer.png' style='position:absolute;width:90px;height:90px;left:11px'/>
<img src="./img/department.png" style="width: 58px; height: 58px;position:absolute;left:29px; border-radius: 50%; margin-top: 16px;position:absolute;left:29px;z-index:999"/>
</div>
<div style="display: inline-block; margin-left: 6px;width: 55%">
<div class="dept-box" style="font-size: 15px;font-family: Microsoft YaHei-Regular, Microsoft YaHei;font-weight: 900;color: #333333;height: 25px;line-height: 25px;width:110px,white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
2 years ago
${d.data.fname}
</div>
<div style="font-size: 13px;font-family: Microsoft YaHei-Bold, Microsoft YaHei;color: #333333;height: 25px;line-height: 25px;">
${getLabel(547322, labelData)}:${d.data.fleader}
</div>
2 years ago
<div style="display:flex" >
<div style="height: 25px; line-height: 25px; min-width: 80px;">
${getLabel(547323, labelData)}: ${
d.data.fonjob
} ${getLabel(547525, labelData)}
2 years ago
</div>
</div>
</div>
2 years ago
</div>
</div>`;
} else if (d.data.ftype == 3) {
return `<div style="position: relative;">
<div style=" height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 40px;">
2 years ago
<div style='position:absolute;z-index:-1;top:0'>
<img style='width: 295px;height: 163px;' src='./img/user-card/user-card-orange.png'>
</div>
2 years ago
<img src="./img/user-card/jobicon-orange.png" style="margin-left: 20px; vertical-align: top;"/>
<div style="display: inline-block; margin-left: 15px;">
<div style="font-size: 15px;height: 25px;line-height: 25px;font-family: Microsoft YaHei-Bold, Microsoft YaHei;font-weight: bold;color: #333333;">${
d.data.fname
}</div>
2 years ago
<div style="font-size: 13px;font-family: Microsoft YaHei-Regular, Microsoft YaHei;font-weight: 400;color: #333333;display: flex;height: 25px;line-height: 25px;">
<span>${getLabel(547323, labelData)}: ${
d.data.fonjob
} ${getLabel(547525, labelData)}</span>
</div>
</div>
</div>
</div>`;
} else if (d.data.ftype == 4) {
return `<div style="position: relative;" >
<div style="height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;">
2 years ago
<div style='position:absolute;z-index:-1;top:0px'>
<img style='width: 295px;height: 163px;' src='./img/user-card/user-card-green.png'>
</div>
2 years ago
<div style="display: inline-block; background-size: 100% 100%; width: 35%; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;">
<img src='./img/user-card/avatar-outer-green.png' style='position:absolute;width:90px;height:90px;left:11px;z-index:-1'/>
<img src="${
d.data.fleaderimg
? d.data.fleaderimg
: './img/default_avator.png'
}" style="width: 58px; height: 58px; border-radius: 50%; margin-top: 16px;margin-left: -6px;z-index:999" />
</div>
<div style="display: inline-block; margin-left: 6px;width: 55%;height:100%">
<div style='display:flex;align-items:center;height: 25px;line-height: 25px;margin-top:2px'>
2 years ago
<div style="font-weight: bold;font-size: 15px;ont-family: Microsoft YaHei-Bold, Microsoft YaHei;color: #333333;">${
d.data.fname
}</div>
</div>
2 years ago
<div style="font-size: 13px;font-family: Microsoft YaHei-Regular, Microsoft YaHei;font-weight: 400;color: #333333;display: flex;height: 25px;line-height: 25px;">
<span>${getLabel(547324, labelData)}: ${
d.data.companyWorkYear
} ${getLabel(547526, labelData)}</span>
</div>
</div>
2 years ago
</div>
</div>`;
}
};
showDrawer = (params) => {
12 months ago
this.getDeatilDatas(params, 'chart', '0');
this.setState({ open: true, params: params });
};
onClose = () => {
12 months ago
this.setState({ open: false, detailType: 'chart', showJob: false });
};
changeDetail = () => {
const { detailType, params } = this.state;
2 years ago
let type = detailType == 'chart' ? 'table' : 'chart';
const showJob = this.state.showJob ? '1' : '0';
this.setState({
2 years ago
detailType: type,
});
this.getDeatilDatas(params, type, showJob);
};
render() {
2 years ago
const {
params,
2 years ago
open,
data,
detailType,
dataSource,
columns,
spinning,
showJob,
} = this.state;
2 years ago
let arr = [];
const { labelData } = this.props;
2 years ago
if (detailType == 'chart') {
arr.push({ label: `${getLabel(547315, labelData)}`, key: '1' });
//arr.push({ label: '导出PDF', key: '2' });
2 years ago
} else {
arr.push({ label: '导出表格', key: '3' });
}
2 years ago
const menu = <Menu onClick={this.handleExport.bind(this)} items={arr} />;
return (
<Drawer
title={getLabel(547321, labelData)}
2 years ago
width={1100}
onClose={this.onClose}
open={open}
bodyStyle={{
paddingBottom: 80,
}}
extra={
<Space>
{detailType == 'chart' && params && params.fclass == '0' && (
<Checkbox
style={{ marginTop: '5px', marginLeft: 100 }}
checked={showJob}
onChange={(e) => {
this.setState({
showJob: e.target.checked,
});
2 years ago
this.getDeatilDatas(
params,
2 years ago
detailType,
e.target.checked ? '1' : '0',
);
}}
>
{getLabel(547447, labelData)}
</Checkbox>
)}
<Dropdown overlay={menu}>
<Button type="primary">{getLabel(547314, labelData)}</Button>
</Dropdown>
12 months ago
<Button type="primary" onClick={this.changeDetail}>
{getLabel(547326, labelData)}
12 months ago
</Button>
</Space>
}
>
{detailType == 'chart' ? (
12 months ago
<div className="svg-container">
<Spin
size="large"
spinning={spinning}
tip={getLabel(547320, labelData)}
12 months ago
className="loading-center"
/>
{data.length > 0 && (
2 years ago
<OrgChartComponent
setChart={(chart) => (orgChart = chart)}
setClick={(click) => (addNodeChildFunc = click)}
onNodeClick={this.onNodeClick}
onButtonClick={this.onButtonClick}
data={data}
buttonContent={this.buttonContentRender}
nodeWidth={this.nodeWidthRender}
nodeHeight={this.nodeHeightRender}
nodeContent={this.nodeContentRender}
/>
12 months ago
)}
</div>
) : (
2 years ago
<div style={{ padding: '0 20px' }}>
<Table
dataSource={dataSource}
columns={columns}
12 months ago
scroll={{ y: 600 }}
loading={spinning}
2 years ago
pagination={{
showSizeChanger: false,
showTotal: (total) =>
`${getLabel(547523, labelData)} ${
dataSource.length
} ${getLabel(547524, labelData)}`,
2 years ago
}}
/>
</div>
)}
</Drawer>
);
}
}