Compare commits

...

19 Commits

@ -2,7 +2,7 @@
* @Author: Chengliang 1546584672@qq.com * @Author: Chengliang 1546584672@qq.com
* @Date: 2022-08-04 10:22:55 * @Date: 2022-08-04 10:22:55
* @LastEditors: Chengliang 1546584672@qq.com * @LastEditors: Chengliang 1546584672@qq.com
* @LastEditTime: 2022-09-06 16:46:56 * @LastEditTime: 2023-06-08 13:50:33
* @FilePath: /org-chart-frant/.umirc.ts * @FilePath: /org-chart-frant/.umirc.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
@ -11,7 +11,7 @@ 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/aischart/',
// exportStatic: {}, // exportStatic: {},
publicPath: './', publicPath: './',
nodeModulesTransform: { nodeModulesTransform: {
@ -20,13 +20,14 @@ 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' },
{ path: '/chart', component: '@/pages/chart' },
], ],
fastRefresh: {}, fastRefresh: {},
antd: {}, antd: {},
proxy: { proxy: {
'/api': { '/api': {
// 标识需要进行转换的请求的url // 标识需要进行转换的请求的url
target: 'http://221.226.25.34:8088/api', // 服务端域名 / http://localhost:8686 target: 'http://10.21.121.82:8080/api', // 服务端域名 / http://localhost:8686
changeOrigin: true, // 允许域名进行转换 changeOrigin: true, // 允许域名进行转换
pathRewrite: { '^/api': '' }, // 将请求url里的ci去掉 pathRewrite: { '^/api': '' }, // 将请求url里的ci去掉
}, },

@ -20,16 +20,20 @@
] ]
}, },
"dependencies": { "dependencies": {
"@ant-design/pro-layout": "^6.5.0", "@ant-design/pro-layout": "^7.14.3",
"@types/d3": "^7.4.0", "@types/d3": "^7.4.0",
"antd": "^4.5.2",
"d3": "7.4.4", "d3": "7.4.4",
"d3-org-chart": "2.6.0", "d3-org-chart": "2.6.0",
"es": "^0.8.0",
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"moment": "^2.29.3", "moment": "^2.29.3",
"qs": "^6.11.0", "qs": "^6.11.0",
"react": "17.x", "react": "17.x",
"react-dom": "17.x", "react-dom": "17.x",
"umi": "^3.5.26" "umi": "^3.5.26",
"watermark-component-for-react": "^1.0.0",
"watermark-dom": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^17.0.0", "@types/react": "^17.0.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -1,38 +1,38 @@
.toolbarWrapper { .toolbarWrapper {
width: 68px; width: 68px;
position: fixed; position: fixed;
right: 10px; right: 10px;
z-index: 100; z-index: 100;
background: #fff; background: #fff;
border-radius: 20px; border-radius: 20px;
padding-top: 20px; padding-top: 20px;
padding-bottom: 20px; padding-bottom: 20px;
text-align: center; text-align: center;
.progressWrapper { .progressWrapper {
position: relative; position: relative;
padding-top: 5px; padding-top: 5px;
padding-bottom: 5px; padding-bottom: 5px;
margin-left: 20px; margin-left: 20px;
.progressLine { .progressLine {
height: 100px; height: 100px;
width: 0px; width: 0px;
border-left: 2px solid #C9C9C9; border-left: 2px solid #c9c9c9;
margin-left: 12px; margin-left: 12px;
}
.progressBtn {
width: 16px;
height: 9px;
background-color: #C9C9C9;
position: absolute;
left: 5px;
top: 0px;
}
} }
.toolBarItem { .progressBtn {
display: block; width: 16px;
margin-top: 20px; height: 9px;
margin-bottom: 20px; background-color: #c9c9c9;
margin-left: 20px; position: absolute;
cursor: pointer; left: 5px;
top: 0px;
} }
} }
.toolBarItem {
display: block;
margin-top: 20px;
margin-bottom: 20px;
margin-left: 20px;
// cursor: pointer;
}
}

@ -4,11 +4,11 @@ import {
DatePicker, DatePicker,
Select, Select,
Button, Button,
Checkbox,
Row, Row,
Col, Col,
Dropdown, Dropdown,
Menu, Menu,
TreeSelect,
} from 'antd'; } from 'antd';
const { Option } = Select; const { Option } = Select;
import moment from 'moment'; import moment from 'moment';
@ -20,14 +20,14 @@ export class TopBar extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
fclasslist: [], deptartmentTreeData: [], //
companylist: [], treeExpandedKeys: [],
levelOptions: [], //hrm
butvisable: true,
requestData: { requestData: {
date: moment(new Date()).format('YYYY-MM-DD'), date: moment(new Date()).format('YYYY-MM-DD'), //
fclass: '0', department: undefined,
root: '0', level: '0', //
level: '3',
fisvitual: '0',
}, },
}; };
} }
@ -36,31 +36,78 @@ export class TopBar extends React.Component {
let requestData = { ...this.state.requestData, ...payload }; let requestData = { ...this.state.requestData, ...payload };
this.setState({ requestData }); this.setState({ requestData });
} }
//
// disabledDate (current) {
// // return current && current >moment().subtract(1, "days");
// return current && current > moment().endOf("day");
// }
handleExportMenuClick(e) { handleExportMenuClick(e) {
this.props.onExport(e.key == '1' ? 'png' : 'pdf'); this.props.onExport(e.key == '1' ? 'png' : 'pdf');
} }
handleExportButtonClick() { /**
this.props.onExport('png'); * 部门树数据
} * @param {} parentId
* @returns
*/
getDepartmentTreeNode = (parentId) => {
let api = '/api/ais/orgChart/getDepartmentTree?department=' + parentId;
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.status) {
let arr = [...this.state.deptartmentTreeData, ...data.data.deptTree];
this.setState({
deptartmentTreeData: arr,
});
}
});
};
/**
* 部门树异步加载
* @param {} parentId
* @returns
*/
onDepartmentLoadData = (treeNode) =>
new Promise((resolve) => {
const { id } = treeNode.props;
setTimeout(() => {
this.getDepartmentTreeNode(id);
resolve(undefined);
}, 1000);
});
onDepartmentChange = (value) => {
let requestData = { ...this.state.requestData, department: value };
this.setState({ requestData });
};
paramsUtil = (param) => {
let arr = param.map(function (obj, index) {
return obj.value;
});
return arr.join(',');
};
onTreeExpand = (expandedKeys) => {
this.setState({
treeExpandedKeys: expandedKeys,
});
};
componentDidMount() { componentDidMount() {
fetch(this.props.url) fetch(this.props.url)
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
this.setState({ if (data.status) {
fclasslist: data.fclasslist, this.setState({
companylist: data.companylist, levelOptions: data.data.deptLevel,
}); deptartmentTreeData: data.data.deptTree,
butvisable: data.data.hasRight,
});
}
}); });
} }
/**
* 导出多选 */
menu = ( menu = (
<Menu <Menu
onClick={this.handleExportMenuClick.bind(this)} onClick={this.handleExportMenuClick.bind(this)}
@ -78,17 +125,18 @@ export class TopBar extends React.Component {
); );
render() { render() {
const { deptartmentTreeData } = this.state;
return ( return (
<div className={style.topbarWrapper}> <div className={style.topbarWrapper}>
<Row> <Row gutter={[16, 16]}>
<Col span={5}> <Col span={6}>
数据日期 日期追溯
<DatePicker <DatePicker
placeholder="请选择日期" placeholder="日期选择"
style={{ width: 130 }} style={{ width: 150 }}
locale={locale} locale={locale}
allowClear={false} allowClear={false}
// disabledDate={this.disabledDate} //disabledDate={this.disabledDate}
defaultValue={moment(new Date())} defaultValue={moment(new Date())}
value={ value={
this.state.requestData.date && this.state.requestData.date != '' this.state.requestData.date && this.state.requestData.date != ''
@ -102,66 +150,30 @@ export class TopBar extends React.Component {
} }
/> />
</Col> </Col>
<Col span={6}>
<Col span={4}> 部门
维度 <TreeSelect
<Select treeDataSimpleMode
defaultValue="0" allowClear
style={{ width: 120 }} style={{ width: '80%' }}
value={this.state.requestData.fclass} value={this.state.requestData.department}
onChange={(value) => this.handleFormChange({ fclass: value })} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
> placeholder="请选择部门节点"
{this.state.fclasslist.map((item) => ( onChange={this.onDepartmentChange}
<Option value={item.id}>{item.companyname}</Option> loadData={this.onDepartmentLoadData}
))} treeData={deptartmentTreeData}
</Select> />
</Col> </Col>
{/* <Col span={6}>
<Col span={4}> 部门层级
根节点
<Select <Select
showSearch style={{ width: 130 }}
filterOption={(input, option) =>
(option?.children).includes(input)
}
defaultValue="0"
style={{ width: 120 }}
value={this.state.requestData.root}
onChange={(value) => this.handleFormChange({ root: value })}
>
{this.state.companylist.map((item) => (
<Option value={item.id}>{item.fname}</Option>
))}
</Select>
</Col>
<Col span={5}>
显示层级
<Select
defaultValue="3"
style={{ width: 120 }}
value={this.state.requestData.level} value={this.state.requestData.level}
onChange={(value) => this.handleFormChange({ level: value })} onChange={(value) => this.handleFormChange({ level: value })}
> options={this.state.levelOptions}
<Option value="1">一级</Option> />
<Option value="2">二级</Option> </Col> */}
<Option value="3">三级</Option> <Col span={6}>
</Select>
</Col>
<Col span={3}>
<Checkbox
style={{ marginTop: '5px' }}
onChange={(e) =>
this.handleFormChange({
fisvitual: e.target.checked ? '1' : '0',
})
}
>
显示虚拟组织
</Checkbox>
</Col>
<Col span={3}>
<Button <Button
type="primary" type="primary"
style={{ marginRight: '10px' }} style={{ marginRight: '10px' }}
@ -171,9 +183,20 @@ export class TopBar extends React.Component {
> >
查询 查询
</Button> </Button>
<Dropdown overlay={this.menu}> <Button
<Button>导出</Button> type="primary"
</Dropdown> style={{ marginRight: '10px' }}
onClick={() => {
window.open('#/chart', '_blank');
}}
>
任命架构图
</Button>
{this.state.butvisable && (
<Dropdown overlay={this.menu}>
<Button type="primary">导出</Button>
</Dropdown>
)}
</Col> </Col>
</Row> </Row>
</div> </div>

@ -480,7 +480,6 @@ export class OrgChart {
//InnerFunctions which will update visuals //InnerFunctions which will update visuals
const attrs = this.getChartState(); const attrs = this.getChartState();
if (!attrs.data || attrs.data.length == 0) { if (!attrs.data || attrs.data.length == 0) {
console.log('ORG CHART - Data is empty');
return this; return this;
} }
@ -637,19 +636,9 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj), ({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj),
)[0]; )[0];
if (nodeFound) { if (nodeFound) {
console.log(
`ORG CHART - ADD - Node with id "${attrs.nodeId(
obj,
)}" already exists in tree`,
);
return this; return this;
} }
if (!parentFound) { if (!parentFound) {
console.log(
`ORG CHART - ADD - Parent node with id "${attrs.parentNodeId(
obj,
)}" not found in the tree`,
);
return this; return this;
} }
if (obj._centered && !obj._expanded) obj._expanded = true; if (obj._centered && !obj._expanded) obj._expanded = true;
@ -670,19 +659,9 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj), ({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj),
)[0]; )[0];
if (nodeFound) { if (nodeFound) {
console.log(
`ORG CHART - ADD - Node with id "${attrs.nodeId(
obj,
)}" already exists in tree`,
);
return this; return this;
} }
if (!parentFound) { if (!parentFound) {
console.log(
`ORG CHART - ADD - Parent node with id "${attrs.parentNodeId(
obj,
)}" not found in the tree`,
);
return this; return this;
} }
obj._expanded = true; obj._expanded = true;
@ -701,9 +680,6 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) == nodeId, ({ data }) => attrs.nodeId(data) == nodeId,
)[0]; )[0];
if (!node) { if (!node) {
console.log(
`ORG CHART - REMOVE - Node with id "${nodeId}" not found in the tree`,
);
return this; return this;
} }
@ -866,8 +842,6 @@ export class OrgChart {
const nodes = treeData.descendants(); const nodes = treeData.descendants();
// console.table(nodes.map(d => ({ x: d.x, y: d.y, width: d.width, height: d.height, flexCompactDim: d.flexCompactDim + "" })))
// Get all links // Get all links
const links = treeData.descendants().slice(1); const links = treeData.descendants().slice(1);
nodes.forEach(attrs.layoutBindings[attrs.layout].swap); nodes.forEach(attrs.layoutBindings[attrs.layout].swap);
@ -1298,7 +1272,6 @@ export class OrgChart {
// } else { // } else {
// this.fit(); // this.fit();
// } // }
console.log(44444, centeredNodes);
this.fit({ this.fit({
animate: true, animate: true,
scale: false, scale: false,
@ -1622,7 +1595,6 @@ export class OrgChart {
const attrs = this.getChartState(); const attrs = this.getChartState();
const { root } = attrs; const { root } = attrs;
let descendants = nodes ? nodes : root.descendants(); let descendants = nodes ? nodes : root.descendants();
console.log(11111111111, nodes, descendants, scale);
const minX = d3.min( const minX = d3.min(
descendants, descendants,
(d) => d.x + attrs.layoutBindings[attrs.layout].nodeLeftX(d), (d) => d.x + attrs.layoutBindings[attrs.layout].nodeLeftX(d),
@ -1639,7 +1611,6 @@ export class OrgChart {
descendants, descendants,
(d) => d.y + attrs.layoutBindings[attrs.layout].nodeBottomY(d), (d) => d.y + attrs.layoutBindings[attrs.layout].nodeBottomY(d),
); );
console.log('333,minY', minX, maxX, minY, maxY);
this.zoomTreeBounds({ this.zoomTreeBounds({
params: { animate: animate, scale }, params: { animate: animate, scale },
x0: transform == 'export' ? minX - 700 : minX - 50, x0: transform == 'export' ? minX - 700 : minX - 50,
@ -1659,11 +1630,6 @@ export class OrgChart {
)[0]; )[0];
if (!node) { if (!node) {
console.log(
`ORG CHART - ${
expandedFlag ? 'EXPAND' : 'COLLAPSE'
} - Node with id (${id}) not found in the tree`,
);
return this; return this;
} }
node.data._expanded = expandedFlag; node.data._expanded = expandedFlag;
@ -1677,9 +1643,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId, (d) => attrs.nodeId(d.data) === nodeId,
)[0]; )[0];
if (!node) { if (!node) {
console.log(
`ORG CHART - CENTER - Node with id (${nodeId}) not found in the tree`,
);
return this; return this;
} }
node.data._centered = true; node.data._centered = true;
@ -1693,9 +1656,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId, (d) => attrs.nodeId(d.data) === nodeId,
)[0]; )[0];
if (!node) { if (!node) {
console.log(
`ORG CHART - HIGHLIGHT - Node with id (${nodeId}) not found in the tree`,
);
return this; return this;
} }
node.data._highlighted = true; node.data._highlighted = true;
@ -1710,9 +1670,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId, (d) => attrs.nodeId(d.data) === nodeId,
)[0]; )[0];
if (!node) { if (!node) {
console.log(
`ORG CHART - HIGHLIGHTROOT - Node with id (${nodeId}) not found in the tree`,
);
return this; return this;
} }
node.data._upToTheRootHighlighted = true; node.data._upToTheRootHighlighted = true;
@ -1786,7 +1743,7 @@ export class OrgChart {
xhr.send(); xhr.send();
} }
exportImg({ full = false, scale = 12, onLoad = (d) => d, save = true } = {}) { exportImg({ full = false, scale = 6, onLoad = (d) => d, save = true } = {}) {
const that = this; const that = this;
const attrs = this.getChartState(); const attrs = this.getChartState();
const { svg: svgImg, root } = attrs; const { svg: svgImg, root } = attrs;

@ -1,5 +0,0 @@
import React from 'react'
export default () => {
return <div>Hello</div>
}

@ -0,0 +1,38 @@
import React, { useEffect, useState } from 'react';
import * as d3 from 'd3';
import styles from './index.less';
import { Image } from 'antd';
import WaterMark from 'watermark-component-for-react';
export default function chartPage() {
const [url, setUrl] = useState();
const [hasRight, setHasRight] = useState('true');
const [watermark, setWatermark] = useState();
//
useEffect(() => {
d3.json('/api/ais/orgChart/chartData').then((res) => {
setWatermark(res.data.watermark);
setUrl(res.data.url);
setHasRight('true');
});
}, []);
return (
hasRight && (
<>
<WaterMark content={watermark} font="20px Microsoft Yahei">
<div className={styles.chartContainer}>
<Image
src={url}
preview={false}
//src={page}
height={'100vh'}
/>
</div>
</WaterMark>
</>
)
);
}

@ -1,5 +1,5 @@
import styles from './index.less'; import styles from './index.less';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef } 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';
@ -7,22 +7,23 @@ import ToolBar from '../components/toolBar';
import jsPDF from 'jspdf'; import jsPDF from 'jspdf';
import moment from 'moment'; import moment from 'moment';
import qs from 'qs'; import qs from 'qs';
import { message } from 'antd'; import { message, Spin } from 'antd';
import WaterMark from 'watermark-component-for-react';
let active = 'top'; let active = 'top';
let orgChart = null;
export default function companyPage() { export default function companyPage() {
const [data, setData] = useState(null); const [data, setData] = useState(null);
const [sliderProgress, setSliderProgress] = useState(50);
let addNodeChildFunc = null; let addNodeChildFunc = null;
let orgChart = null; let orgChart = null;
let topBarSearchRequest = useRef({});
let topBarSearchRequest = null;
const [hasRight, setHasRight] = useState(''); const [hasRight, setHasRight] = useState('');
const [watermark, setWatermark] = useState('');
const [loading, setLoading] = useState('');
// //
function onNodeClick(nodeId) { function onNodeClick(nodeId) {}
// alert('clicked ' + nodeId);
}
// //
function onButtonClick(event, d) { function onButtonClick(event, d) {
@ -33,34 +34,19 @@ export default function companyPage() {
idsList.push(item.data.id); idsList.push(item.data.id);
} }
}); });
if (idsList.length == 0) { if (idsList.length == 0) {
return; return;
} }
let idsStr = idsList.join(','); let idsStr = idsList.join(',');
let request = { ...topBarSearchRequest.current, ids: idsStr };
console.log('idsStr', idsStr); let api =
'/api/ais/orgChart/asyncCompanyData' +
let api = ''; qs.stringify(request, { addQueryPrefix: true });
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) fetch(api)
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((resp) => {
if (data.data) { if (resp.data.data) {
data.data.forEach((item) => { resp.data.data.forEach((item) => {
window.chart.addNode(item); window.chart.addNode(item);
}); });
} }
@ -68,36 +54,48 @@ export default function companyPage() {
} }
} }
// //
function getDepartmentImage() { function getLevelImage(deptLevel, isVirtual) {
let index = Math.floor(Math.random() * 8) + 1; switch (deptLevel) {
// return `./img/department/${index}.png`; case '0':
return `./img/department/1.png`; return isVirtual == 0
} ? `./img/company/level1.png`
: `./img/company/level5.png`;
// case '1':
function getSubcompanyImage() { return isVirtual == 0
let index = Math.floor(Math.random() * 3) + 1; ? `./img/company/level2.png`
// return `./img/subcompany/${index}.png`; : `./img/company/level6.png`;
return `./img/subcompany/2.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(() => { useEffect(() => {
d3.json( d3.json(
// "/company/data" '/api/ais/orgChart/companyData?level=0&date=' +
'/api/bs/hrmorganization/orgchart/companyData?fclass=0&isvitual=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD'), moment(new Date()).format('YYYY-MM-DD'),
).then((data) => { ).then((resp) => {
setData(data.data); setData(resp.data.data);
setHasRight(data?.hasRight); setWatermark(resp.data.watermark);
setHasRight('true');
}); });
}, [true]); }, []);
// ButtonContent // ButtonContent
const buttonContentRender = ({ node, state }) => { const buttonContentRender = ({ node, state }) => {
if (node.children) { 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>`; 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 { } 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>`; 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>`;
} }
@ -119,24 +117,16 @@ export default function companyPage() {
if (d.data.ftype == 0) { if (d.data.ftype == 0) {
return 100; return 100;
} else if (d.data.ftype == 1) { } else if (d.data.ftype == 1) {
return 160; return 80;
} else if (d.data.ftype == 2) { } else if (d.data.ftype == 2) {
return 56; return 106;
} }
return 120; return 120;
}; };
const nodeContentRender = (d, i, arr, state) => { 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) { if (d.data.ftype == 0) {
return `<div onclick="if(${d.data.fisvitual}==1) return;window.open('${companyUrl}', '_blank')" style="text-align:center"> return `<div style="text-align:center">
<div style="display: inline-block; vertical-align: top;"> <div style="display: inline-block; vertical-align: top;">
<img src="./img/company.png" /> <img src="./img/company.png" />
</div> </div>
@ -153,12 +143,7 @@ export default function companyPage() {
</div> </div>
</div>`; </div>`;
} else if (d.data.ftype == 1) { } else if (d.data.ftype == 1) {
return `<div onclick="if(${ return `<div onclick="window.open('${d.data.url}', '_blank')">
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; <div style="width: 136px; border: 1px solid #66BAF5; margin: 10px auto 0px; border-radius: 23px; text-align: center;
font-size: 14px; font-size: 14px;
font-family: Microsoft YaHei-Regular, Microsoft YaHei; font-family: Microsoft YaHei-Regular, Microsoft YaHei;
@ -171,22 +156,31 @@ export default function companyPage() {
</div> </div>
</div>`; </div>`;
} else if (d.data.ftype == 2) { } else if (d.data.ftype == 2) {
let one = d.data.leader == '' ? 'none' : 'inline';
let three = d.data.deputyLeader == '' ? 'none' : 'inline';
let two = d.data.header == '' ? 'none' : 'inline-block';
return ` return `
<div style="width: 100%; height: 100%; background-size: 100% 100%;" onclick="if(${ <div style="width: 100%; height: 100%; background-size: 100% 100%;" >
d.data.fisvitual <div style='position:absolute;height:100%'>
}==1) return;window.open('${departmentUrl}')"> <img style='width:144px;height:106px' src="${getLevelImage(
<div style='position:absolute'> d.data.deptLevel,
<img src='./img/company_job_label.png'/></div> d.data.isVirtual,
<div style="padding-left: 8px; padding-top: 23px;display:flex;align-items:center"> )}"/></div>
<img src="${getDepartmentImage()}"/> <div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 12px;
<span style=" font-family: Microsoft YaHei-Regular, Microsoft YaHei;color: #333333;text-align: center;">
margin-left: 3px;
font-size: 12px; <div title=${
font-family: Microsoft YaHei-Regular, Microsoft YaHei; d.data.fname
font-weight: 400; } style="width: 110px;margin: 0 auto;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:ellipsis;
color: #333333; line-height: 18px;word-break: break-all;">${d.data.fname}</div>
">${d.data.fname}</span> <div style="width: 130px;margin: 0 auto;line-height: 18px;display:${two}">分管领导${
</div> d.data.header
} </div>
<div style="width: 120px;margin: 0 auto;line-height: 18px;">
<p style="display:${one}">${d.data.leader}</p>
<p style="display:${three}"> &nbsp;|| ${d.data.deputyLeader}</p>
</div>
</div>
</div> </div>
`; `;
} }
@ -242,10 +236,6 @@ export default function companyPage() {
orgChart && orgChart.zoomBehavior(value - 50); orgChart && orgChart.zoomBehavior(value - 50);
}; };
// tool bar end
// top bar start
function downloadPdf(chart) { function downloadPdf(chart) {
chart.exportImg({ chart.exportImg({
save: false, save: false,
@ -271,32 +261,36 @@ export default function companyPage() {
const handleExport = (type) => { const handleExport = (type) => {
if (type == 'png') { if (type == 'png') {
orgChart && orgChart.exportImg({ full: true }); orgChart && orgChart.exportImg({ full: true, scale: 12 });
} else { } else {
orgChart && downloadPdf(orgChart); orgChart && downloadPdf(orgChart);
} }
}; };
const handleSearch = (requestData) => { const handleSearch = (requestData) => {
topBarSearchRequest = requestData; setLoading(true);
topBarSearchRequest.current = requestData;
let api = let api =
'/api/bs/hrmorganization/orgchart/companyData' + '/api/ais/orgChart/companyData' +
qs.stringify(requestData, { addQueryPrefix: true }); qs.stringify(requestData, { addQueryPrefix: true });
fetch(api) fetch(api)
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((resp) => {
if (data.data) { if (resp.status) {
if (!data.data.length) { if (!resp.data.data.length) {
setData([{}]); setData([{}]);
message.warning('暂无数据'); message.warning('暂无数据');
} else { } else {
setData(data?.data); setData(resp.data.data);
setTimeout(function () {
setLoading(false);
}, 1000);
} }
} }
}); });
}; };
useEffect(() => { useEffect(() => {
console.log('data', data);
if (active == 'left') { if (active == 'left') {
orgChart && orgChart &&
orgChart orgChart
@ -311,9 +305,8 @@ export default function companyPage() {
.render(); .render();
} }
}, [data]); }, [data]);
// top bar end
if (hasRight === false) { if (hasRight === false) {
//return message.error("", 2);
return ( return (
<div style={{ width: '100%', top: '40%', position: 'absolute' }}> <div style={{ width: '100%', top: '40%', position: 'absolute' }}>
<img <img
@ -327,38 +320,46 @@ export default function companyPage() {
return ( return (
hasRight && ( hasRight && (
<div className={styles.contentWrapper}> <>
<TopBar <div className={styles.contentWrapper}>
onExport={(type) => { <TopBar
handleExport(type); onExport={(type) => {
}} handleExport(type);
onSearch={(requestData) => { }}
handleSearch(requestData); onSearch={(requestData) => {
}} handleSearch(requestData);
type="company" }}
url="/api/bs/hrmorganization/orgchart/getCondition?type=company" type="company"
/> url="/api/ais/orgChart/getSearchCondition"
<ToolBar />
onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)} <WaterMark content={watermark} font="20px Microsoft Yahei">
onLeftLayoutClick={(progressBtn) => <ToolBar
handleLeftLayoutClick(progressBtn) onTopLayoutClick={(progressBtn) =>
} handleTopLayoutClick(progressBtn)
onZoomOut={(progressBtn) => handleZoomOut(progressBtn)} }
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)} onLeftLayoutClick={(progressBtn) =>
onZoomBehavior={(value) => handleZoomBehavior(value)} handleLeftLayoutClick(progressBtn)
/> }
<OrgChartComponent onZoomOut={(progressBtn) => handleZoomOut(progressBtn)}
setChart={(chart) => (orgChart = chart)} onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
setClick={(click) => (addNodeChildFunc = click)} onZoomBehavior={(value) => handleZoomBehavior(value)}
onNodeClick={onNodeClick} />
data={data} <Spin spinning={loading} tip="页面加载中 请稍候">
onButtonClick={onButtonClick} <OrgChartComponent
buttonContent={buttonContentRender} setChart={(chart) => (orgChart = chart)}
nodeWidth={nodeWidthRender} setClick={(click) => (addNodeChildFunc = click)}
nodeHeight={nodeHeightRender} onNodeClick={onNodeClick}
nodeContent={nodeContentRender} data={data}
/> onButtonClick={onButtonClick}
</div> buttonContent={buttonContentRender}
nodeWidth={nodeWidthRender}
nodeHeight={nodeHeightRender}
nodeContent={nodeContentRender}
/>
</Spin>
</WaterMark>
</div>
</>
) )
); );
} }

@ -1,11 +1,23 @@
/*
* @Author: Chengliang 1546584672@qq.com
* @Date: 2023-08-08 17:38:47
* @LastEditors: Chengliang 1546584672@qq.com
* @LastEditTime: 2023-08-09 14:38:52
* @FilePath: /org-chart-frant/src/pages/index.less
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AEmax
*/
.title { .title {
background: rgb(121, 242, 157); background: rgb(121, 242, 157);
} }
.wrapper { .wrapper {
background: #F7F9FD; background: #f7f9fd;
} }
.contentWrapper { .contentWrapper {
background-color: #F7F9FD; background-color: #f7f9fd;
} }
.chartContainer {
text-align: center;
}

@ -50,11 +50,11 @@ export default function userPage() {
if (topBarSearchRequest) { if (topBarSearchRequest) {
let request = { ...topBarSearchRequest, ids: idsStr }; let request = { ...topBarSearchRequest, ids: idsStr };
api = api =
'/api/bs/hrmorganization/orgchart/asyncUserData' + '/api/bs/hrmorganization/jclorgchart/asyncUserData' +
qs.stringify(request, { addQueryPrefix: true }); qs.stringify(request, { addQueryPrefix: true });
} else { } else {
api = api =
'/api/bs/hrmorganization/orgchart/asyncUserData?fclass=0&root=0&date=' + '/api/bs/hrmorganization/jclorgchart/asyncUserData?fclass=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD') + moment(new Date()).format('YYYY-MM-DD') +
'&ids=' + '&ids=' +
idsStr; idsStr;
@ -78,7 +78,7 @@ export default function userPage() {
return `./img/department/${index}.png`; return `./img/department/${index}.png`;
} }
// //
function getSubcompanyImage() { function getSubcompanyImage() {
let index = Math.floor(Math.random() * 3) + 1; let index = Math.floor(Math.random() * 3) + 1;
return `./img/subcompany/${index}.png`; return `./img/subcompany/${index}.png`;
@ -87,14 +87,14 @@ export default function userPage() {
// //
useEffect(() => { useEffect(() => {
document.cookie = document.cookie =
'loginidweaver=1; languageidweaver=7; loginuuids=1; JSESSIONID=aaa1QNMWge48Bh-3oq6oy; ecology_JSessionid=aaa1QNMWge48Bh-3oq6oy; __randcode__=5c4300d1-05d6-4ca6-adb4-f4e23a47acb5'; '33_ecology_JSessionid=aaaa-IcPBu61A7ZrtCyLy; JSESSIONID=aaaa-IcPBu61A7ZrtCyLy; ecology_JSessionid=aaaa-IcPBu61A7ZrtCyLy; Systemlanguid=7; languageidweaver=7; loginuuids=1; loginidweaver=sysadmin; CASTGC=TGT-1-H9KSLsgcxVxv1DacS9ONFSR2Ajb3nkZDho15XOOnoAtQN4ypIb-c01';
d3.json( d3.json(
// "/user/data" // "/user/data"
'/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=' + '/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=' +
moment(new Date()).format('YYYY-MM-DD'), moment(new Date()).format('YYYY-MM-DD'),
).then((data) => { ).then((data) => {
setData(data.data); setData(data.data);
setHasRight(data?.hasRight); setHasRight('true');
}); });
}, [true]); }, [true]);
@ -190,7 +190,7 @@ export default function userPage() {
const handleExport = (type) => { const handleExport = (type) => {
if (type == 'png') { if (type == 'png') {
orgChart && orgChart.exportImg({ full: true }); orgChart && orgChart.exportImg({ full: true, scale: 12 });
} else { } else {
orgChart && downloadPdf(orgChart); orgChart && downloadPdf(orgChart);
} }
@ -199,7 +199,7 @@ export default function userPage() {
const handleSearch = (requestData) => { const handleSearch = (requestData) => {
setTpBarSearchRequest(requestData); setTpBarSearchRequest(requestData);
let api = let api =
'/api/bs/hrmorganization/orgchart/userData' + '/api/bs/hrmorganization/jclorgchart/userData' +
qs.stringify(requestData, { addQueryPrefix: true }); qs.stringify(requestData, { addQueryPrefix: true });
fetch(api) fetch(api)
.then((res) => res.json()) .then((res) => res.json())
@ -236,15 +236,15 @@ export default function userPage() {
let companyUrl = let companyUrl =
'/spa/organization/static/index.html#/main/organization/group'; '/spa/organization/static/index.html#/main/organization/group';
// //
let subcompanyUrl = `/spa/organization/static/index.html#/main/organization/companyExtend/${d.data.fobjid}`; let subcompanyUrl = `/spa/hrm/engine.html#/hrmengine/organization?showTree=false&type=subcompany&id=${d.data.fobjid}`;
// //
let departmentUrl = `/spa/organization/static/index.html#/main/organization/departmentExtend/${d.data.fobjid}`; let departmentUrl = `/spa/hrm/engine.html#/hrmengine/organization?showTree=false&isView=1&type=department&id=${d.data.fobjid}`;
// //
let jobtitleUrl = `/spa/organization/static/index.html#/main/organization/jobExtend/${d.data.fobjid}`; let jobtitleUrl = `/spa/organization/static/index.html#/main/organization/jobExtend/${d.data.fobjid}`;
// //
let userUrl = `/spa/organization/static/index.html#/main/organization/resourceCard/${d.data.fleader}`; let userUrl = `/spa/hrm/index_mobx.html#/main/hrm/card/cardInfo/${d.data.fleader}`;
// //
let postUserUrl = `/spa/organization/static/index.html#/main/organization/resourceCard/${d.data.fobjid}`; let postUserUrl = `/spa/hrm/index_mobx.html#/main/hrm/card/cardInfo/${d.data.fobjid}`;
// //
let addressBookGroupUrl = `/spa/organization/static/index.html#/main/organization/resource/?virtualtype=0`; let addressBookGroupUrl = `/spa/organization/static/index.html#/main/organization/resource/?virtualtype=0`;
// //
@ -269,7 +269,9 @@ 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="if(${d.data.fisvitual}==1) return;window.open('${ " onclick="if(${d.data.fisvitual}==1||${
d.data.ftype
}==0) return;window.open('${
d.data.ftype == 0 d.data.ftype == 0
? companyUrl ? companyUrl
: d.data.ftype == 1 : d.data.ftype == 1
@ -327,17 +329,9 @@ export default function userPage() {
<div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 60px;">编制: ${ <div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 60px;">编制: ${
d.data.fplan d.data.fplan
}</div> }</div>
<div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 60px; margin-left: 10px;" onclick="if(${ <div style="height: 28px;border: 1px solid #00C2FF; border-radius: 10px; line-height: 24px; padding: 0px 5px; min-width: 60px; margin-left: 10px;">在岗: ${
d.data.fisvitual d.data.fonjob
}==1) return;event.stopPropagation();window.open('${ }</div>
d.data.ftype == 0
? addressBookGroupUrl
: d.data.ftype == 1
? addressBookUrl
: d.data.ftype == 2
? addressBookDepartmentUrl
: ''
}', '_blank')">在岗: ${d.data.fonjob}</div>
</div> </div>
</div> </div>
</div> </div>
@ -358,9 +352,7 @@ 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="if(${ " onclick="if(${d.data.fisvitual}==1) return;">${
d.data.fisvitual
}==1) return;window.open('${jobtitleUrl}', '_blank')">${
d.data.fname d.data.fname
}</span> }</span>
<span style="margin-left: 70px;"> <span style="margin-left: 70px;">
@ -379,9 +371,7 @@ export default function userPage() {
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
margin-bottom: 23px; margin-bottom: 23px;
" onclick="if(${ " onclick="if(${d.data.fisvitual}==1) return;">${
d.data.fisvitual
}==1) return;window.open('${jobtitleUrl}', '_blank')">${
d.data.fname d.data.fname
}</div> }</div>
<div style=" <div style="
@ -392,11 +382,7 @@ export default function userPage() {
display: ${d.data.fisvitual == 0 ? 'flex' : 'none'}; display: ${d.data.fisvitual == 0 ? 'flex' : 'none'};
"> ">
<span>编制${d.data.fplan}</span> <span>编制${d.data.fplan}</span>
<span style="margin-left: 10px;" onclick="if(${ <span style="margin-left: 10px;">在岗${d.data.fonjob}</span>
d.data.fisvitual
}==1) return;window.open('${addressBookPostUrl}', '_blank')">在岗${
d.data.fonjob
}</span>
</div> </div>
</div> </div>
</div> </div>
@ -497,7 +483,7 @@ export default function userPage() {
handleSearch(requestData); handleSearch(requestData);
}} }}
type="user" type="user"
url="/api/bs/hrmorganization/orgchart/getCondition?type=user" url="/api/bs/hrmorganization/jclorgchart/getCondition?type=user"
/> />
<ToolBar <ToolBar
onTopLayoutClick={handleTopLayoutClick} onTopLayoutClick={handleTopLayoutClick}

Loading…
Cancel
Save