组织透视修复导出图片

feature/fj
Chengliang 3 years ago
parent d0472f7a1d
commit 57cc610174

@ -1,9 +1,17 @@
/*
* @Author: Chengliang 1546584672@qq.com
* @Date: 2022-08-04 10:22:55
* @LastEditors: Chengliang 1546584672@qq.com
* @LastEditTime: 2022-08-08 16:31:31
* @FilePath: /org-chart-frant/.umirc.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { defineConfig } from 'umi'; import { defineConfig } from 'umi';
export default defineConfig({ export default defineConfig({
hash: true, hash: true,
history: { type: 'hash'}, history: { type: 'hash' },
base: "/spa/orgChart/", base: '/spa/orgChart/',
// exportStatic: {}, // exportStatic: {},
publicPath: './', publicPath: './',
nodeModulesTransform: { nodeModulesTransform: {
@ -11,15 +19,16 @@ export default defineConfig({
}, },
routes: [ routes: [
{ path: '/user', component: '@/pages/user' }, { path: '/user', component: '@/pages/user' },
{ path: '/company', component: '@/pages/company' } { path: '/company', component: '@/pages/company' },
], ],
fastRefresh: {}, fastRefresh: {},
antd: {}, antd: {},
proxy: { proxy: {
"/api": { // 标识需要进行转换的请求的url '/api': {
"target": "http://localhost:18089/api", // 服务端域名 // 标识需要进行转换的请求的url
"changeOrigin": true, // 允许域名进行转换 target: 'http://localhost:8686/api', // 服务端域名
"pathRewrite": { "^/api": ''} // 将请求url里的ci去掉 changeOrigin: true, // 允许域名进行转换
} pathRewrite: { '^/api': '' }, // 将请求url里的ci去掉
} },
},
}); });

@ -1,206 +1,217 @@
import styles from './index.less'; import styles from './index.less';
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from 'react';
import {OrgChartComponent} from '@/components/orgChart' import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3'; import * as d3 from 'd3';
import { TopBar } from '../components/topBar'; import { TopBar } from '../components/topBar';
import ToolBar from '../components/toolBar'; import ToolBar from '../components/toolBar';
import moment from "moment"; import moment from 'moment';
import qs from 'qs'; import qs from 'qs';
import { message } from 'antd'; import { message } from 'antd';
export default function userPage() { export default function userPage() {
const [data, setData] = useState(null); const [data, setData] = useState(null);
const [progressTop, setProgressTop] = useState(50); const [progressTop, setProgressTop] = useState(50);
let addNodeChildFunc = null; let addNodeChildFunc = null;
let orgChart = null; let orgChart = null;
let progressBtnRef = null; let progressBtnRef = null;
let topBarSearchRequest = null; let topBarSearchRequest = null;
//
// function onNodeClick(nodeId) {
function onNodeClick(nodeId) { // alert('clicked ' + nodeId);
// alert('clicked ' + nodeId); }
}
function onButtonClick(event, d) {
function onButtonClick(event, d) { if (d.children) {
let idsList = [];
if(d.children) { d.children.forEach((item) => {
let idsList = [] if (item.data.hasChildren && !item._children) {
d.children.forEach(item => { idsList.push(item.data.id);
if(item.data.hasChildren && !item._children) {
idsList.push(item.data.id);
}
})
if(idsList.length == 0) {
return
} }
});
let idsStr = idsList.join(",") if (idsList.length == 0) {
return;
}
console.log("idsStr", idsStr); let idsStr = idsList.join(',');
let api = ""; console.log('idsStr', idsStr);
if(topBarSearchRequest) {
let request = {...topBarSearchRequest, ids: idsStr}
api = "/api/bs/hrmorganization/orgchart/asyncUserData" + qs.stringify(request, {addQueryPrefix: true})
} else { let api = '';
api = "/api/bs/hrmorganization/orgchart/asyncUserData?fclass=0&root=0&date=" + moment(new Date()).format("YYYY-MM-DD") + "&ids="+idsStr if (topBarSearchRequest) {
} let request = { ...topBarSearchRequest, ids: idsStr };
api =
fetch(api).then(res => res.json()).then(data => { '/api/bs/hrmorganization/orgchart/asyncUserData' +
if(data.data) { qs.stringify(request, { addQueryPrefix: true });
data.data.forEach(item => { } else {
window.chart.addNode(item) api =
}) '/api/bs/hrmorganization/orgchart/asyncUserData?fclass=0&root=0&date=' +
} moment(new Date()).format('YYYY-MM-DD') +
}) '&ids=' +
idsStr;
} }
}
//
function getDepartmentImage() {
let index = Math.floor(Math.random() * 8) + 1
return `./img/department/${index}.png`
}
// fetch(api)
function getSubcompanyImage() { .then((res) => res.json())
let index = Math.floor(Math.random() * 3) + 1 .then((data) => {
return `./img/subcompany/${index}.png` if (data.data) {
data.data.forEach((item) => {
window.chart.addNode(item);
});
}
});
} }
}
//
useEffect(() => { //
d3.json( function getDepartmentImage() {
// "/user/data" let index = Math.floor(Math.random() * 8) + 1;
"/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=" + moment(new Date()).format("YYYY-MM-DD") return `./img/department/${index}.png`;
).then(data => { }
setData(data.data);
}); //
}, [true]); function getSubcompanyImage() {
let index = Math.floor(Math.random() * 3) + 1;
// ButtonContent return `./img/subcompany/${index}.png`;
const buttonContentRender = ({ node, state }) => { }
return `
//
useEffect(() => {
d3.json(
// "/user/data"
'/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD'),
).then((data) => {
setData(data.data);
});
}, [true]);
// ButtonContent
const buttonContentRender = ({ node, state }) => {
return `
<div style="margin-left: 16px; margin-top: 10px;"> <div style="margin-left: 16px; margin-top: 10px;">
<img src="./img/button_content.png" /> <img src="./img/button_content.png" />
</div> </div>
` `;
} };
// //
const nodeWidthRender = d => const nodeWidthRender = (d) => {
{ return 280;
return 280; };
}
const nodeHeightRender = (d) => {
const nodeHeightRender = d => { return 160;
return 160; };
}
// tool bar start
// tool bar start const handleTopLayoutClick = (progressBtn) => {
const handleTopLayoutClick = (progressBtn) => { progressBtn.current.style.top = 50 + 'px';
progressBtn.current.style.top= 50 + "px"; orgChart && orgChart.layout('top').render();
orgChart && orgChart.layout('top').render() };
}
const handleLeftLayoutClick = (progressBtn) => {
const handleLeftLayoutClick = (progressBtn) => { progressBtn.current.style.top = 50 + 'px';
progressBtn.current.style.top= 50 + "px"; orgChart && orgChart.layout('left').render();
orgChart && orgChart.layout('left').render() };
}
const handleZoomIn = (progressBtn) => {
const handleZoomIn = (progressBtn) => { if (progressBtn) {
if(progressBtn) { let top = parseInt(progressBtn.current.style.top) - 10;
let top = (parseInt(progressBtn.current.style.top) - 10) if (top <= 0) {
if(top <= 0) { top = 30;
top = 30;
}
progressBtn.current.style.top = top + "px";
} }
orgChart && orgChart.zoomIn(); progressBtn.current.style.top = top + 'px';
} }
orgChart && orgChart.zoomIn();
const handleZoomOut = (progressBtn) => { };
if(progressBtn) {
let top = (parseInt(progressBtn.current.style.top) + 10) const handleZoomOut = (progressBtn) => {
if(top >= 100) { if (progressBtn) {
top = 70; let top = parseInt(progressBtn.current.style.top) + 10;
} if (top >= 100) {
progressBtn.current.style.top = top + "px"; top = 70;
} }
orgChart && orgChart.zoomOut(); progressBtn.current.style.top = top + 'px';
}
// tool bar end
// top bar start
function downloadPdf(chart) {
chart.exportImg({
save: false,
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');
};
},
});
} }
orgChart && orgChart.zoomOut();
const handleExport = (type) => { };
if(type == "png") {
orgChart && orgChart.exportImg({full:true}); // tool bar end
} else {
orgChart && downloadPdf(orgChart) // top bar start
}
function downloadPdf(chart) {
chart.exportImg({
save: false,
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 const handleSearch = (requestData) => {
let api = "/api/bs/hrmorganization/orgchart/userData" + qs.stringify(requestData, {addQueryPrefix: true}) topBarSearchRequest = requestData;
fetch(api).then(res => res.json()).then(data => { let api =
if(data.data && data.data.length > 0) { '/api/bs/hrmorganization/orgchart/userData' +
setData(data.data) qs.stringify(requestData, { addQueryPrefix: true });
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.data && data.data.length > 0) {
setData(data.data);
} else { } else {
message.warning("暂无数据"); message.warning('暂无数据');
} }
}) });
} };
// top bar end // top bar end
const nodeContentRender = (d, i, arr, state) => { const nodeContentRender = (d, i, arr, state) => {
// //
let companyUrl = "/spa/organization/static/index.html#/main/organization/group" let companyUrl =
// '/spa/organization/static/index.html#/main/organization/group';
let subcompanyUrl = "/spa/organization/static/index.html#/main/organization/companyExtend/" //
// let subcompanyUrl =
let departmentUrl = "/spa/organization/static/index.html#/main/organization/departmentExtend/" '/spa/organization/static/index.html#/main/organization/companyExtend/';
// //
let jobtitleUrl = "/spa/organization/static/index.html#/main/organization/jobExtend/"; let departmentUrl =
'/spa/organization/static/index.html#/main/organization/departmentExtend/';
// //
let userUrl = "/spa/hrm/index_mobx.html#/main/hrm/card/cardInfo/"; let jobtitleUrl =
'/spa/organization/static/index.html#/main/organization/jobExtend/';
//
let addressBookUrl = "/spa/hrm/index_mobx.html#/main/hrm/addressBook"; //
let userUrl = '/spa/hrm/index_mobx.html#/main/hrm/card/cardInfo/';
if(d.data.ftype == 0 || d.data.ftype == 1 || d.data.ftype == 2) {
return `<div> //
let addressBookUrl = '/spa/hrm/index_mobx.html#/main/hrm/addressBook';
if (d.data.ftype == 0 || d.data.ftype == 1 || d.data.ftype == 2) {
return `<div>
<div style="position: relative;"> <div style="position: relative;">
<img src="./img/user-card/card-label-start.png" /> <img src="./img/user-card/card-label-start.png" />
<span style="display: inline-block; <span style="display: inline-block;
@ -214,16 +225,30 @@ export default function userPage() {
font-family: Microsoft YaHei-Bold, Microsoft YaHei; font-family: Microsoft YaHei-Bold, Microsoft YaHei;
font-weight: bold; font-weight: bold;
color: #000000; color: #000000;
" onclick="window.open('${d.data.ftype == 0 ? companyUrl : " onclick="window.open('${
d.data.ftype == 1 ? subcompanyUrl + d.data.fnumber : d.data.ftype == 0
d.data.ftype == 2 ? departmentUrl + d.data.fnumber : ""}', '_blank')">${d.data.fname}</span> ? companyUrl
: d.data.ftype == 1
? subcompanyUrl + d.data.fnumber
: d.data.ftype == 2
? departmentUrl + d.data.fnumber
: ''
}', '_blank')">${d.data.fname}</span>
<span style="margin-left: 70px;"> <span style="margin-left: 70px;">
<img src="./img/user-card/line1.png" /> <img src="./img/user-card/line1.png" />
<img src="./img/user-card/line2.png" /> <img src="./img/user-card/line2.png" />
</span> </span>
<div style="background: url('./img/user-card/user-card.png'); height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;" onclick="window.open('${userUrl + d.data.fleader}', '_blank')"> <div style="background: url('./img/user-card/user-card.png'); height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;" onclick="window.open('${
<div onclick="window.open('${userUrl + d.data.fleader}', '_blank')" style="display: inline-block; background: url('./img/user-card/avatar-outer.png'); background-size: 100% 100%; width: 90px; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;"> userUrl + d.data.fleader
<img src="${d.data.fleaderimg ? d.data.fleaderimg : "./img/default_avator.png"}" style="width: 58px; height: 58px; border-radius: 50%; margin-top: 16px;"/> }', '_blank')">
<div onclick="window.open('${
userUrl + d.data.fleader
}', '_blank')" style="display: inline-block; background: url('./img/user-card/avatar-outer.png'); background-size: 100% 100%; width: 90px; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;">
<img src="${
d.data.fleaderimg
? d.data.fleaderimg
: './img/default_avator.png'
}" style="width: 58px; height: 58px; border-radius: 50%; margin-top: 16px;"/>
</div> </div>
<div style="display: inline-block; margin-left: 6px;"> <div style="display: inline-block; margin-left: 6px;">
<div style=" <div style="
@ -241,15 +266,19 @@ export default function userPage() {
margin-bottom: 19px; margin-bottom: 19px;
">${d.data.fname} / ${d.data.fleaderjob}</div> ">${d.data.fname} / ${d.data.fleaderjob}</div>
<div style="display: flex;" onclick="window.open('${addressBookUrl}', '_blank')"> <div style="display: flex;" onclick="window.open('${addressBookUrl}', '_blank')">
<div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 69px;">编制: ${d.data.fplan}</div> <div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 69px;">编制: ${
<div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 69px; margin-left: 10px;">在岗: ${d.data.fonjob}</div> d.data.fplan
}</div>
<div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 69px; margin-left: 10px;">在岗: ${
d.data.fonjob
}</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>` </div>`;
} else if(d.data.ftype == 3) { } else if (d.data.ftype == 3) {
return `<div> return `<div>
<div style="position: relative;"> <div style="position: relative;">
<img src="./img/user-card/card-label-start.png" /> <img src="./img/user-card/card-label-start.png" />
<span style="display: inline-block; <span style="display: inline-block;
@ -294,10 +323,12 @@ export default function userPage() {
</div> </div>
</div> </div>
</div> </div>
</div>` </div>`;
} else if(d.data.ftype == 4) { } else if (d.data.ftype == 4) {
return `<div> return `<div>
<div style="position: relative;" onclick="window.open('${userUrl + d.data.fnumber}', '_blank')"> <div style="position: relative;" onclick="window.open('${
userUrl + d.data.fnumber
}', '_blank')">
<img src="./img/user-card/card-label-start.png" /> <img src="./img/user-card/card-label-start.png" />
<span > <span >
<img src="./img/user-card/line1.png" /> <img src="./img/user-card/line1.png" />
@ -305,7 +336,11 @@ export default function userPage() {
</span> </span>
<div style="background: url('./img/user-card/user-card.png'); height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;"> <div style="background: url('./img/user-card/user-card.png'); height: 152px;background-size: 100% 100%;box-sizing: border-box;padding-top: 30px;">
<div style="display: inline-block; background: url('./img/user-card/avatar-outer.png'); background-size: 100% 100%; width: 90px; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;"> <div style="display: inline-block; background: url('./img/user-card/avatar-outer.png'); background-size: 100% 100%; width: 90px; height: 90px; text-align:center; vertical-align: top; margin-left: 11px;box-sizing: border;">
<img src="${d.data.fleaderimg ? d.data.fleaderimg : "./img/default_avator.png"}" style="width: 58px; height: 58px; border-radius: 50%; margin-top: 16px;"/> <img src="${
d.data.fleaderimg
? d.data.fleaderimg
: './img/default_avator.png'
}" style="width: 58px; height: 58px; border-radius: 50%; margin-top: 16px;"/>
</div> </div>
<div style="display: inline-block; margin-left: 6px;"> <div style="display: inline-block; margin-left: 6px;">
<div style=" <div style="
@ -319,53 +354,57 @@ export default function userPage() {
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
">${d.data.department ? d.data.department + " / " : ""}${d.data.fleaderjob}</div> ">${d.data.department ? d.data.department + ' / ' : ''}${
d.data.fleaderjob
}</div>
<div style=" <div style="
font-size: 10px; font-size: 10px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
margin-bottom: 10px; margin-bottom: 10px;
">${d.data.mobile ? d.data.mobile : ""}</div> ">${d.data.mobile ? d.data.mobile : ''}</div>
<div style=" <div style="
font-size: 10px; font-size: 10px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
">${d.data.address ? "地址" + d.data.address : ""}</div> ">${d.data.address ? '地址:' + d.data.address : ''}</div>
</div> </div>
</div> </div>
</div> </div>
</div>` </div>`;
}
} }
};
return (
<div className={styles.contentWrapper}> return (
<TopBar <div className={styles.contentWrapper}>
onExport={() => {handleExport()}} <TopBar
onSearch={(requestData) => {handleSearch(requestData)}} onExport={(type) => {
url="/api/bs/hrmorganization/orgchart/getCondition?type=user" handleExport(type);
/> }}
<ToolBar onSearch={(requestData) => {
onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)} handleSearch(requestData);
onLeftLayoutClick={(progressBtn) => handleLeftLayoutClick(progressBtn)} }}
onZoomOut={(progressBtn) => handleZoomOut(progressBtn)} url="/api/bs/hrmorganization/orgchart/getCondition?type=user"
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)} />
/> <ToolBar
<OrgChartComponent onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)}
setChart={(chart) => orgChart = chart} onLeftLayoutClick={(progressBtn) => handleLeftLayoutClick(progressBtn)}
setClick={click => (addNodeChildFunc = click)} onZoomOut={(progressBtn) => handleZoomOut(progressBtn)}
onNodeClick={onNodeClick} onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
onButtonClick={onButtonClick} />
data={data} <OrgChartComponent
buttonContent={ setChart={(chart) => (orgChart = chart)}
buttonContentRender setClick={(click) => (addNodeChildFunc = click)}
} onNodeClick={onNodeClick}
nodeWidth={nodeWidthRender} onButtonClick={onButtonClick}
nodeHeight={nodeHeightRender} data={data}
nodeContent={nodeContentRender} buttonContent={buttonContentRender}
/> nodeWidth={nodeWidthRender}
</div> nodeHeight={nodeHeightRender}
); nodeContent={nodeContentRender}
/>
</div>
);
} }

Loading…
Cancel
Save