Compare commits
12 Commits
master
...
上海顺胜组织架构图v2
| Author | SHA1 | Date |
|---|---|---|
|
|
adcfd3c148 | |
|
|
08a969dc8c | |
|
|
58c339cdad | |
|
|
e7bfc7f831 | |
|
|
b708c6608d | |
|
|
d6af9ee836 | |
|
|
19134712f3 | |
|
|
6badf8edb3 | |
|
|
3d3b8a61da | |
|
|
2d658dd619 | |
|
|
a8820eeb94 | |
|
|
445aa1f00c |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -8,6 +8,8 @@ import {
|
|||
Table,
|
||||
Spin,
|
||||
Checkbox,
|
||||
Modal,
|
||||
Input,
|
||||
} from 'antd';
|
||||
import { OrgChartComponent } from '@/components/orgChart';
|
||||
import * as d3 from 'd3';
|
||||
|
|
@ -16,6 +18,7 @@ import { message } from 'antd';
|
|||
import jsPDF from 'jspdf';
|
||||
import ExportJsonExcel from 'js-export-excel';
|
||||
import './index.less';
|
||||
import { i18n } from '../../util/i18n.js';
|
||||
|
||||
let addNodeChildFunc = null;
|
||||
let orgChart = null;
|
||||
|
|
@ -32,13 +35,26 @@ export default class DrawerComponents extends React.Component {
|
|||
columns: [],
|
||||
spinning: true,
|
||||
showJob: true,
|
||||
isModalOpen: false,
|
||||
jobResponsibility: '',
|
||||
personId: '',
|
||||
jobTitle: '',
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {}
|
||||
|
||||
// 点击节点
|
||||
onNodeClick(node) {}
|
||||
onNodeClick = (node) => {
|
||||
if (node.ftype == '4') {
|
||||
this.setState({
|
||||
jobResponsibility: node.jobResponsibility,
|
||||
jobTitle: node.jobTitle,
|
||||
isModalOpen: true,
|
||||
personId: node.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onButtonClick(event, d) {
|
||||
if (d.children) {
|
||||
|
|
@ -63,7 +79,8 @@ export default class DrawerComponents extends React.Component {
|
|||
|
||||
//获取数据
|
||||
getDeatilDatas(params, type = 'chart', showJob = '1') {
|
||||
this.setState({ spinning: true });
|
||||
const { language } = this.props;
|
||||
this.setState({ spinning: true, data: [], dataSource: [] });
|
||||
d3.json(
|
||||
'/api/bs/hrmorganization/orgchart/getDepartmentDetail?' +
|
||||
qs.stringify({ detauleType: type, ...params, showJob }),
|
||||
|
|
@ -72,7 +89,53 @@ export default class DrawerComponents extends React.Component {
|
|||
if (type == 'chart') {
|
||||
this.setState({ data: data.data, spinning: false });
|
||||
} else {
|
||||
this.setState({ dataSource: data.dataSource, columns: data.columns });
|
||||
let columns = [
|
||||
{
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
title: `${i18n.table.no[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'workCode',
|
||||
key: 'workCode',
|
||||
title: `${i18n.table.workCode[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'lastName',
|
||||
key: 'lastName',
|
||||
title: `${i18n.table.lastName[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'sex',
|
||||
key: 'sex',
|
||||
title: `${i18n.table.gender[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'departmentName',
|
||||
key: 'departmentName',
|
||||
title: `${i18n.table.department[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'subcompanyName',
|
||||
key: 'subcompanyName',
|
||||
title: `${i18n.table.company[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'jobTitle',
|
||||
key: 'jobTitle',
|
||||
title: `${i18n.table.possition[language]}`,
|
||||
},
|
||||
{
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
title: `${i18n.table.mobile[language]}`,
|
||||
},
|
||||
];
|
||||
this.setState({
|
||||
dataSource: data.dataSource,
|
||||
columns: columns,
|
||||
spinning: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -164,6 +227,7 @@ export default class DrawerComponents extends React.Component {
|
|||
};
|
||||
|
||||
handleExport = (e) => {
|
||||
const { language } = this.props;
|
||||
let type = e.key == '1' ? 'png' : e.key == '1' ? 'pdf' : 'excel';
|
||||
if (type == 'png') {
|
||||
orgChart && orgChart.exportImg({ full: true });
|
||||
|
|
@ -190,7 +254,7 @@ export default class DrawerComponents extends React.Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
option.fileName = '组织信息';
|
||||
option.fileName = `${i18n.table.orgInfo[language]}`;
|
||||
option.datas = [
|
||||
{
|
||||
sheetData: dataTable,
|
||||
|
|
@ -206,14 +270,14 @@ export default class DrawerComponents extends React.Component {
|
|||
'手机号',
|
||||
],
|
||||
sheetHeader: [
|
||||
'序号',
|
||||
'工号',
|
||||
'姓名',
|
||||
'性别',
|
||||
'部门',
|
||||
'分部',
|
||||
'岗位',
|
||||
'手机号',
|
||||
i18n.table.no[language],
|
||||
i18n.table.workCode[language],
|
||||
i18n.table.lastName[language],
|
||||
i18n.table.gender[language],
|
||||
i18n.table.department[language],
|
||||
i18n.table.company[language],
|
||||
i18n.table.possition[language],
|
||||
i18n.table.mobile[language],
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
@ -226,6 +290,8 @@ export default class DrawerComponents extends React.Component {
|
|||
* 节点渲染
|
||||
*/
|
||||
nodeContentRender = (d, i, arr, state) => {
|
||||
const { language } = 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">
|
||||
|
|
@ -236,18 +302,24 @@ export default class DrawerComponents extends React.Component {
|
|||
</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"/>
|
||||
<img src="${
|
||||
d.data.fleaderimg
|
||||
? d.data.fleaderimg
|
||||
: './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;">
|
||||
${d.data.fname}
|
||||
</div>
|
||||
<div style="font-size: 13px;font-family: Microsoft YaHei-Bold, Microsoft YaHei;color: #333333;height: 25px;line-height: 25px;">
|
||||
负责人:${d.data.fleader}
|
||||
${i18n.head[language]}:${d.data.fleader}
|
||||
</div>
|
||||
<div style="display:flex" >
|
||||
<div style="height: 25px; line-height: 25px; min-width: 80px;">
|
||||
在岗: ${d.data.fonjob} 人
|
||||
${i18n.onJob[language]}: ${d.data.fonjob} ${
|
||||
i18n.onJob[language] == 'cn' ? '人' : ''
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -262,9 +334,13 @@ export default class DrawerComponents extends React.Component {
|
|||
</div>
|
||||
<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>
|
||||
<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>
|
||||
<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>在岗: ${d.data.fonjob} 人</span>
|
||||
<span>${i18n.onJob[language]}: ${d.data.fonjob} ${
|
||||
i18n.onJob[language] == 'cn' ? '人' : ''
|
||||
}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -283,14 +359,18 @@ export default class DrawerComponents extends React.Component {
|
|||
: './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: inline-block; margin-left: -6px;width: 58%;height:100%;margin-top:-20px;">
|
||||
<div style='display:flex;align-items:center;height: 25px;line-height: 25px;margin-top:15px'>
|
||||
<div style="font-weight: bold;font-size: 15px;ont-family: Microsoft YaHei-Bold, Microsoft YaHei;color: #333333;">${
|
||||
d.data.fname
|
||||
}</div>
|
||||
</div>
|
||||
<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>司龄: ${d.data.companyWorkYear} 年</span>
|
||||
<div style="font-size: 13px;font-family: Microsoft YaHei-Regular, Microsoft YaHei;font-weight: 400;color: #333333;height: 25px;line-height: 25px;">
|
||||
<span>${i18n.serveAge[language]}: ${
|
||||
d.data.companyWorkYear
|
||||
} ${i18n.year[language]}</span>
|
||||
<div>${i18n.postion[language]}: ${d.data.jobTitle}</div>
|
||||
<div>${i18n.level[language]}: ${d.data.level}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -305,13 +385,23 @@ export default class DrawerComponents extends React.Component {
|
|||
};
|
||||
|
||||
onClose = () => {
|
||||
this.setState({ open: false, detailType: 'chart', showJob: true });
|
||||
const { params } = this.state;
|
||||
this.setState({
|
||||
open: false,
|
||||
detailType: 'chart',
|
||||
showJob: params.fclass == '0' ? 'true' : 'false',
|
||||
});
|
||||
};
|
||||
|
||||
changeDetail = () => {
|
||||
const { detailType, params } = this.state;
|
||||
let type = detailType == 'chart' ? 'table' : 'chart';
|
||||
const showJob = this.state.showJob ? '1' : '0';
|
||||
var showJob = '1';
|
||||
if (params.fclass == '0') {
|
||||
showJob = this.state.showJob ? '1' : '0';
|
||||
} else {
|
||||
showJob = '0';
|
||||
}
|
||||
this.setState({
|
||||
detailType: type,
|
||||
});
|
||||
|
|
@ -319,6 +409,8 @@ export default class DrawerComponents extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { language } = this.props;
|
||||
|
||||
const {
|
||||
params,
|
||||
open,
|
||||
|
|
@ -328,20 +420,24 @@ export default class DrawerComponents extends React.Component {
|
|||
columns,
|
||||
spinning,
|
||||
showJob,
|
||||
jobResponsibility,
|
||||
jobTitle,
|
||||
isModalOpen,
|
||||
personId,
|
||||
} = this.state;
|
||||
let arr = [];
|
||||
if (detailType == 'chart') {
|
||||
arr.push({ label: '导出图片', key: '1' });
|
||||
arr.push({ label: `${i18n.exportImage[language]}`, key: '1' });
|
||||
//arr.push({ label: '导出PDF', key: '2' });
|
||||
} else {
|
||||
arr.push({ label: '导出表格', key: '3' });
|
||||
arr.push({ label: `${i18n.exportTable[language]}`, key: '3' });
|
||||
}
|
||||
|
||||
const menu = <Menu onClick={this.handleExport.bind(this)} items={arr} />;
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
title="详细信息"
|
||||
title={i18n.detailInfo[language]}
|
||||
width={1100}
|
||||
onClose={this.onClose}
|
||||
open={open}
|
||||
|
|
@ -366,11 +462,11 @@ export default class DrawerComponents extends React.Component {
|
|||
);
|
||||
}}
|
||||
>
|
||||
是否显示岗位
|
||||
{i18n.showJob[language]}
|
||||
</Checkbox>
|
||||
)}
|
||||
<Dropdown overlay={menu}>
|
||||
<Button type="primary">导出</Button>
|
||||
<Button type="primary">{i18n.export[language]}</Button>
|
||||
</Dropdown>
|
||||
<img
|
||||
style={{ width: 36, height: 36, cursor: 'pointer' }}
|
||||
|
|
@ -381,8 +477,14 @@ export default class DrawerComponents extends React.Component {
|
|||
}
|
||||
>
|
||||
{detailType == 'chart' ? (
|
||||
data.length > 0 && (
|
||||
<Spin size="large" spinning={spinning}>
|
||||
<div className="svg-container">
|
||||
<Spin
|
||||
size="large"
|
||||
spinning={spinning}
|
||||
tip="正在读取数据...."
|
||||
className="loading-center"
|
||||
/>
|
||||
{data.length > 0 && (
|
||||
<OrgChartComponent
|
||||
setChart={(chart) => (orgChart = chart)}
|
||||
setClick={(click) => (addNodeChildFunc = click)}
|
||||
|
|
@ -394,14 +496,15 @@ export default class DrawerComponents extends React.Component {
|
|||
nodeHeight={this.nodeHeightRender}
|
||||
nodeContent={this.nodeContentRender}
|
||||
/>
|
||||
</Spin>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ padding: '0 20px' }}>
|
||||
<Table
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
scroll={{ y: 500 }}
|
||||
loading={spinning}
|
||||
pagination={{
|
||||
locale: {
|
||||
// 翻页文本替换
|
||||
|
|
@ -409,11 +512,29 @@ export default class DrawerComponents extends React.Component {
|
|||
jump_to: '跳至',
|
||||
page: '页',
|
||||
},
|
||||
showTotal: (total) => `共 ${dataSource.length} 条`,
|
||||
showTotal: (total) =>
|
||||
language == 'cn'
|
||||
? `共 ${dataSource.length} 条`
|
||||
: `${dataSource.length} ${i18n.table.records[language]} ${i18n.table.total[language]}`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Modal
|
||||
title={`${i18n.postionInfo[language]}-${jobTitle}`}
|
||||
open={isModalOpen}
|
||||
onCancel={() => this.setState({ isModalOpen: false })}
|
||||
footer={[
|
||||
<Button
|
||||
key="back"
|
||||
onClick={() => this.setState({ isModalOpen: false })}
|
||||
>
|
||||
{i18n.close[language]}
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<div style={{ whiteSpace: 'pre-line' }}>{jobResponsibility}</div>
|
||||
</Modal>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,3 +2,11 @@
|
|||
width: 500px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.loading-center {
|
||||
position: absolute;
|
||||
top: 50vh;
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
margin-top: -8px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@ const { TextArea } = Input;
|
|||
import moment from 'moment';
|
||||
import 'moment/locale/zh-cn';
|
||||
import locale from 'antd/lib/date-picker/locale/zh_CN';
|
||||
import { HomeOutlined } from '@ant-design/icons';
|
||||
import { HomeOutlined, FolderOpenOutlined } from '@ant-design/icons';
|
||||
moment.locale('zh-cn');
|
||||
|
||||
import { i18n } from '../../util/i18n.js';
|
||||
|
||||
export class TopBar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -32,16 +34,20 @@ export class TopBar extends React.Component {
|
|||
rootTreeData: [], //根节点异步树
|
||||
treeLoadedKeys: [],
|
||||
treeExpandedKeys: [],
|
||||
deptTreeData: [],
|
||||
requestData: {
|
||||
fclass: '0',
|
||||
fclass: '',
|
||||
root: undefined,
|
||||
level: '2',
|
||||
department: undefined,
|
||||
level: '1',
|
||||
fisvitual: '0',
|
||||
hidedept: '0',
|
||||
},
|
||||
open: false,
|
||||
confirmLoading: false,
|
||||
description: '',
|
||||
defaultLevelOpt: [],
|
||||
levelOpt: [],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -142,8 +148,63 @@ export class TopBar extends React.Component {
|
|||
});
|
||||
|
||||
onRootChange = (value) => {
|
||||
let requestData = { ...this.state.requestData, root: value };
|
||||
this.setState({ requestData });
|
||||
const { fclass } = this.state.requestData;
|
||||
if (fclass != '0') {
|
||||
//顺胜项目二开 增加部门节点树
|
||||
this.getDeptTreeData(
|
||||
`/api/bs/hrmorganization/orgchart/getDepartmentTree?fclass=${fclass}&subcompany=${value}`,
|
||||
);
|
||||
}
|
||||
this.handleFormChange({ department: undefined, root: value });
|
||||
};
|
||||
|
||||
/**
|
||||
* 部门节点树
|
||||
*/
|
||||
getDeptTreeData = (url) => {
|
||||
fetch(url)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (data.api_status) {
|
||||
let arr = [...data.departmentTree];
|
||||
arr.map((item, index) => {
|
||||
item.icon = <FolderOpenOutlined />;
|
||||
});
|
||||
this.setState({
|
||||
deptTreeData: arr,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onDeptChange = (value, label, extra) => {
|
||||
const { deptTreeData } = this.state;
|
||||
var opt = this.buildLevelOpt(0);
|
||||
const foundItem = deptTreeData.find((item) => item.value === value);
|
||||
var level = foundItem ? foundItem.depth : '1';
|
||||
if (value != undefined) {
|
||||
opt = this.buildLevelOpt(level);
|
||||
}
|
||||
this.handleFormChange({
|
||||
department: value,
|
||||
level: level === '1' ? level : `${level + 1}`,
|
||||
});
|
||||
this.setState({ levelOpt: opt });
|
||||
};
|
||||
|
||||
/**
|
||||
* 虚拟维度部门层级构建
|
||||
*/
|
||||
buildLevelOpt = (level) => {
|
||||
const { language } = this.props;
|
||||
let opt = [{ value: '1', label: `${i18n.all[language]}` }];
|
||||
for (let index = 1; index <= level; index++) {
|
||||
opt.push({
|
||||
value: `${index + 1}`,
|
||||
label: language == 'cn' ? `${index}级` : `Level ${index}`,
|
||||
});
|
||||
}
|
||||
return opt;
|
||||
};
|
||||
|
||||
onTreeExpand = (expandedKeys) => {
|
||||
|
|
@ -153,6 +214,17 @@ export class TopBar extends React.Component {
|
|||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { language } = this.props;
|
||||
const defaultLevelOpt = [
|
||||
{ value: '1', label: `${i18n.all[language]}` },
|
||||
{ value: '2', label: language == 'cn' ? '一级' : 'Level 1' },
|
||||
{ value: '3', label: language == 'cn' ? '二级' : 'Level 2' },
|
||||
{ value: '4', label: language == 'cn' ? '三级' : 'Level 3' },
|
||||
];
|
||||
this.setState({
|
||||
levelOpt: defaultLevelOpt,
|
||||
defaultLevelOpt: defaultLevelOpt,
|
||||
});
|
||||
this.getSeatchCondition(this.props.url);
|
||||
}
|
||||
|
||||
|
|
@ -167,6 +239,10 @@ export class TopBar extends React.Component {
|
|||
fclasslist: data.fclasslist,
|
||||
rootTreeData: data.companyTree,
|
||||
});
|
||||
this.handleFormChange({ fclass: data.fclass, root: data.root });
|
||||
this.getDeptTreeData(
|
||||
`/api/bs/hrmorganization/orgchart/getDepartmentTree?fclass=${data.fclass}&subcompany=${data.root}`,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -175,7 +251,7 @@ export class TopBar extends React.Component {
|
|||
onClick={this.handleExportMenuClick.bind(this)}
|
||||
items={[
|
||||
{
|
||||
label: '导出图片',
|
||||
label: `${i18n.exportImage[this.props.language]}`,
|
||||
key: '1',
|
||||
},
|
||||
// {
|
||||
|
|
@ -187,29 +263,43 @@ export class TopBar extends React.Component {
|
|||
);
|
||||
|
||||
render() {
|
||||
const { disabled, type } = this.props;
|
||||
const { rootTreeData, open, confirmLoading, treeExpandedKeys } = this.state;
|
||||
const { disabled, type, language } = this.props;
|
||||
const {
|
||||
rootTreeData,
|
||||
open,
|
||||
confirmLoading,
|
||||
treeExpandedKeys,
|
||||
requestData,
|
||||
deptTreeData,
|
||||
levelOpt,
|
||||
defaultLevelOpt,
|
||||
} = this.state;
|
||||
const { fclass, department } = requestData;
|
||||
|
||||
return (
|
||||
<div className={style.topbarWrapper}>
|
||||
<Row>
|
||||
<Col span={6}>
|
||||
维度:
|
||||
{i18n.fclass[language]}:
|
||||
<Select
|
||||
defaultValue="0"
|
||||
style={{ width: 140 }}
|
||||
value={this.state.requestData.fclass}
|
||||
value={fclass}
|
||||
onChange={(value) => {
|
||||
const requestData = {
|
||||
fclass: value,
|
||||
root: undefined,
|
||||
level: '2',
|
||||
department: undefined,
|
||||
level: value == '0' ? '2' : '1',
|
||||
fisvitual: '0',
|
||||
hidedept: '0',
|
||||
};
|
||||
this.handleFormChange(requestData);
|
||||
this.setState({
|
||||
rootTreeData: [],
|
||||
deptTreeData: [],
|
||||
levelOpt:
|
||||
value == '0' ? defaultLevelOpt : this.buildLevelOpt(0),
|
||||
});
|
||||
this.getNodeTreeNode(
|
||||
`/api/bs/hrmorganization/orgchart/getSubCompanyTree?fclass=${value}`,
|
||||
|
|
@ -225,21 +315,22 @@ export class TopBar extends React.Component {
|
|||
))}
|
||||
</Select>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
根节点:
|
||||
<Col span={fclass == '0' ? 6 : 8}>
|
||||
{i18n.companyRoot[language]}:
|
||||
<TreeSelect
|
||||
treeDataSimpleMode
|
||||
allowClear
|
||||
style={{ width: '75%' }}
|
||||
style={{ width: '65%' }}
|
||||
value={this.state.requestData.root}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder="请选择根节点"
|
||||
placeholder={i18n.placeholder[language]}
|
||||
onChange={this.onRootChange}
|
||||
loadData={this.onRootLoadData}
|
||||
treeData={rootTreeData}
|
||||
treeIcon
|
||||
/>
|
||||
</Col>
|
||||
{fclass == '0' ? (
|
||||
<Col span={6}>
|
||||
<Checkbox
|
||||
style={{ marginTop: '5px', marginLeft: 100 }}
|
||||
|
|
@ -250,10 +341,11 @@ export class TopBar extends React.Component {
|
|||
})
|
||||
}
|
||||
>
|
||||
隐藏部门
|
||||
{i18n.hideDept[language]}
|
||||
</Checkbox>
|
||||
|
||||
<Tooltip
|
||||
title="提示:开启后将只显示分部组织架构!!!"
|
||||
title={i18n.tipsDept[language]}
|
||||
color="#0082fb"
|
||||
placement="rightTop"
|
||||
>
|
||||
|
|
@ -262,22 +354,26 @@ export class TopBar extends React.Component {
|
|||
/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<Col span={6}>
|
||||
部门层级:
|
||||
{i18n.deptLevel[language]}:
|
||||
<Select
|
||||
defaultValue="3"
|
||||
style={{ width: 140 }}
|
||||
value={this.state.requestData.level}
|
||||
onChange={(value) => this.handleFormChange({ level: value })}
|
||||
>
|
||||
<Option value="1">全部</Option>
|
||||
<Option value="2">一级</Option>
|
||||
<Option value="3">二级</Option>
|
||||
<Option value="4">三级</Option>
|
||||
{levelOpt.map((item) => (
|
||||
<Option key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginTop: '15px' }}>
|
||||
{fclass == '0' ? (
|
||||
<Col span={6}>
|
||||
<Checkbox
|
||||
style={{ marginTop: '5px' }}
|
||||
|
|
@ -288,10 +384,10 @@ export class TopBar extends React.Component {
|
|||
})
|
||||
}
|
||||
>
|
||||
显示虚拟组织
|
||||
{i18n.virtual[language]}
|
||||
</Checkbox>
|
||||
<Tooltip
|
||||
title="提示:若启用虚拟组织,需要在分部自定义表增加字段(名称 fblx) 字段类型 下拉框(0实体 1虚拟) 部门自定义表同上(字段名称 bmlx)。"
|
||||
title={i18n.tipsVirtual[language]}
|
||||
color="#0082fb"
|
||||
placement="rightTop"
|
||||
>
|
||||
|
|
@ -300,71 +396,45 @@ export class TopBar extends React.Component {
|
|||
/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: '10px' }}
|
||||
disabled={disabled}
|
||||
onClick={() => {
|
||||
this.setState({ open: true });
|
||||
}}
|
||||
>
|
||||
版本记录
|
||||
</Button>
|
||||
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{fclass != '0' ? (
|
||||
<Col span={8}>
|
||||
{i18n.deptRoot[language]}:
|
||||
<TreeSelect
|
||||
treeDataSimpleMode
|
||||
allowClear
|
||||
style={{ width: '75%' }}
|
||||
value={department}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder={i18n.placeholder[language]}
|
||||
onChange={this.onDeptChange}
|
||||
treeData={deptTreeData}
|
||||
treeIcon
|
||||
/>
|
||||
</Col>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<Col span={10}>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: '10px' }}
|
||||
onClick={() => {
|
||||
if (fclass != '0' && department == undefined) {
|
||||
return message.warning(`${i18n.searchRemind[language]}`);
|
||||
}
|
||||
this.props.onSearch(this.state.requestData);
|
||||
}}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: '10px' }}
|
||||
onClick={() => {
|
||||
window.open('#/dragtree', 'blank');
|
||||
}}
|
||||
>
|
||||
组织调整
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: '10px' }}
|
||||
onClick={() => {
|
||||
window.open('#/statistics', 'blank');
|
||||
}}
|
||||
>
|
||||
人数统计
|
||||
{i18n.search[language]}
|
||||
</Button>
|
||||
<Dropdown overlay={this.menu}>
|
||||
<Button type="primary">导出</Button>
|
||||
<Button type="primary">{i18n.export[language]}</Button>
|
||||
</Dropdown>
|
||||
</Col>
|
||||
</Row>
|
||||
<Modal
|
||||
title="版本记录"
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
open={open}
|
||||
onOk={this.handleOk}
|
||||
confirmLoading={confirmLoading}
|
||||
onCancel={() => this.setState({ open: false })}
|
||||
>
|
||||
<p style={{ color: 'red' }}>
|
||||
提示:版本记录耗时较长,请谨慎操作(仅记录当前维度的数据版本)
|
||||
</p>
|
||||
<p>主题:</p>
|
||||
<TextArea
|
||||
showCount
|
||||
maxLength={10}
|
||||
style={{ height: 120, resize: 'none' }}
|
||||
onChange={this.onChange}
|
||||
placeholder="please enter"
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -964,6 +964,9 @@ export class OrgChart {
|
|||
})
|
||||
.remove();
|
||||
|
||||
//实线设置
|
||||
//linkUpdate.style('stroke-dasharray', 'none');
|
||||
|
||||
// -------------------------- CONNECTIONS ----------------------
|
||||
|
||||
const connectionsSel = attrs.connectionsWrapper
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import moment from 'moment';
|
|||
import qs from 'qs';
|
||||
import { message, Spin, notification } from 'antd';
|
||||
import { SmileOutlined } from '@ant-design/icons';
|
||||
import { i18n } from '../util/i18n.js';
|
||||
|
||||
let active = 'top';
|
||||
let drawerCom = null;
|
||||
|
|
@ -27,22 +28,28 @@ export default function companyPage() {
|
|||
|
||||
const [sliderProgress, setSliderProgress] = useState(50);
|
||||
let addNodeChildFunc = null;
|
||||
let topBarSearchRequest = null;
|
||||
const [hasRight, setHasRight] = useState('');
|
||||
const [timelineId, setTimelineId] = useState(0);
|
||||
const [language, setLanguage] = useState('cn');
|
||||
const infoRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
infoRef.current = timelineId;
|
||||
let { hash } = window.location;
|
||||
let languageValue = hash.match(/language=([^&]+)/i);
|
||||
let language = 'cn';
|
||||
if (languageValue && languageValue.length > 1) {
|
||||
language = languageValue[1];
|
||||
setLanguage(language);
|
||||
}
|
||||
|
||||
notification.open({
|
||||
message: '提示',
|
||||
description:
|
||||
'组织架构图中编制数和在编数显示初始化需参考文档配置定时任务并执行!!!(编制数默认取本年度最新编制信息,人数统计展示仅限于行政维度)',
|
||||
message: i18n.tips[language],
|
||||
description: i18n.tipsContent[language],
|
||||
icon: <SmileOutlined style={{ color: '#108ee9' }} />,
|
||||
});
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
infoRef.current = timelineId;
|
||||
}, [timelineId]);
|
||||
|
||||
const [spinning, setSpinning] = useState(false);
|
||||
|
||||
// 点击节点
|
||||
|
|
@ -72,17 +79,10 @@ export default function companyPage() {
|
|||
}
|
||||
|
||||
let idsStr = idsList.join(',');
|
||||
let api = '';
|
||||
if (topBarSearchRequest) {
|
||||
let request = { ...topBarSearchRequest, ids: idsStr };
|
||||
api =
|
||||
let request = { ...topbar.state.requestData, ids: idsStr };
|
||||
let api =
|
||||
'/api/bs/hrmorganization/orgchart/asyncCompanyData' +
|
||||
qs.stringify(request, { addQueryPrefix: true });
|
||||
} else {
|
||||
api =
|
||||
'/api/bs/hrmorganization/orgchart/asyncCompanyData?fclass=0&fisvitual=0&id=0&root=0&ids=' +
|
||||
idsStr;
|
||||
}
|
||||
fetch(api)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
|
|
@ -97,8 +97,15 @@ export default function companyPage() {
|
|||
};
|
||||
|
||||
// 获取部门图片
|
||||
function getDepartmentImage(fisvitual) {
|
||||
return fisvitual == '0' ? `./img/back/level4.png` : `./img/back/level8.png`;
|
||||
function getDepartmentImage(fisvitual, colorCheck) {
|
||||
const fclass = topbar.state.requestData.fclass;
|
||||
if (fclass == '0') {
|
||||
return fisvitual == '0'
|
||||
? `./img/back/level4.png`
|
||||
: `./img/back/level8.png`;
|
||||
} else {
|
||||
return `./img/sship/dept${colorCheck}.png`;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分部图片
|
||||
|
|
@ -109,7 +116,7 @@ export default function companyPage() {
|
|||
//获取数据
|
||||
useEffect(() => {
|
||||
d3.json(
|
||||
'/api/bs/hrmorganization/orgchart/companyData?fclass=0&fisvitual=0&hidedept=0&root=0&level=2&id=0',
|
||||
'/api/bs/hrmorganization/orgchart/companyData?id=0&fisvitual=0&hidedept=0&level=1',
|
||||
).then((data) => {
|
||||
setData(data.data);
|
||||
setHasRight(data?.hasRight);
|
||||
|
|
@ -149,11 +156,13 @@ export default function companyPage() {
|
|||
};
|
||||
|
||||
const nodeContentRender = (d, i, arr, state) => {
|
||||
let fclass = topbar.state.requestData.fclass;
|
||||
let a = topbar.state.requestData.fclass;
|
||||
let fclass = a == '' ? undefined : a;
|
||||
let statisticsStyle = fclass == 0 ? 'block' : 'none';
|
||||
let headStyle = fclass == 0 ? 'none' : 'block';
|
||||
if (d.data.ftype == 0) {
|
||||
return `<div>
|
||||
<div style="display: inline-block; text-align: center; margin-left: 5px;">
|
||||
return `<div style = "text-align: center">
|
||||
<div style="display: inline-block; margin-left: 5px;">
|
||||
<div style="
|
||||
font-size: 24px;
|
||||
font-family: Microsoft YaHei-Bold, Microsoft YaHei;
|
||||
|
|
@ -190,6 +199,7 @@ export default function companyPage() {
|
|||
<div style='position:absolute;height:100%'>
|
||||
<img style='width:144px;height:106px' src="${getDepartmentImage(
|
||||
d.data.fisvitual,
|
||||
d.data.colorCheck,
|
||||
)}"/>
|
||||
</div>
|
||||
<div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 14px;
|
||||
|
|
@ -200,6 +210,12 @@ export default function companyPage() {
|
|||
<span style="color:red">${d.data.staffNum}</span> /
|
||||
<span style="color:green">${d.data.onJobNum}</span>
|
||||
</div>
|
||||
<div style="display: ${headStyle}">
|
||||
<span>${d.data.fleader}</span>
|
||||
</div>
|
||||
<div style="display: ${headStyle}">
|
||||
<span>${d.data.jobType}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -371,7 +387,6 @@ export default function companyPage() {
|
|||
if (cache) {
|
||||
requestData = { ...requestData, id: infoRef.current };
|
||||
}
|
||||
topBarSearchRequest = requestData;
|
||||
let api =
|
||||
'/api/bs/hrmorganization/orgchart/companyData' +
|
||||
qs.stringify(requestData, { addQueryPrefix: true });
|
||||
|
|
@ -381,7 +396,7 @@ export default function companyPage() {
|
|||
if (data.data) {
|
||||
if (!data.data.length) {
|
||||
setData([{}]);
|
||||
message.warning('暂无数据');
|
||||
message.warning(`${i18n.httpRemind[language]}`);
|
||||
} else {
|
||||
setData(data?.data);
|
||||
}
|
||||
|
|
@ -397,10 +412,11 @@ export default function companyPage() {
|
|||
* @param {*} requestData
|
||||
*/
|
||||
const handleChange = (requestData) => {
|
||||
setTimelineId(0);
|
||||
timeLine.searchTimeLines(
|
||||
`/api/bs/hrmorganization/orgchart/timeLines?fclass=${requestData.fclass}`,
|
||||
);
|
||||
//上海顺胜项目二开去除版本时间轴
|
||||
// setTimelineId(0);
|
||||
// timeLine.searchTimeLines(
|
||||
// `/api/bs/hrmorganization/orgchart/timeLines?fclass=${requestData.fclass}`,
|
||||
// );
|
||||
requestData = { ...requestData, id: 0 };
|
||||
handleSearch(requestData, false);
|
||||
};
|
||||
|
|
@ -428,7 +444,7 @@ export default function companyPage() {
|
|||
style={{ display: 'block', margin: '0 auto' }}
|
||||
src="./img/permission.png"
|
||||
/>
|
||||
<p style={{ textAlign: 'center' }}>对不起,您暂时没有权限!</p>
|
||||
<p style={{ textAlign: 'center' }}>{i18n.noAuth[language]}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -449,6 +465,7 @@ export default function companyPage() {
|
|||
}}
|
||||
type="company"
|
||||
url="/api/bs/hrmorganization/orgchart/getCondition?fclass=0&type=company&id=0"
|
||||
language={language}
|
||||
/>
|
||||
<ToolBar
|
||||
onTopLayoutClick={(progressBtn) => handleTopLayoutClick(progressBtn)}
|
||||
|
|
@ -465,13 +482,6 @@ export default function companyPage() {
|
|||
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
|
||||
onZoomBehavior={(value) => handleZoomBehavior(value)}
|
||||
/>
|
||||
<TimeLine
|
||||
ref={(r) => (timeLine = r)}
|
||||
onClick={(timeline) => {
|
||||
timeLineSearch(timeline);
|
||||
}}
|
||||
url={'/api/bs/hrmorganization/orgchart/timeLines?fclass=0'}
|
||||
/>
|
||||
<Spin size="large" spinning={spinning}>
|
||||
<OrgChartComponent
|
||||
setChart={(chart) => (orgChart = chart)}
|
||||
|
|
@ -485,7 +495,7 @@ export default function companyPage() {
|
|||
nodeContent={nodeContentRender}
|
||||
/>
|
||||
</Spin>
|
||||
<DrawerComponents ref={(r) => (drawerCom = r)} />
|
||||
<DrawerComponents ref={(r) => (drawerCom = r)} language={language} />
|
||||
<OperateDialog
|
||||
ref={(r) => (operateCom = r)}
|
||||
addFolderNode={addFolderNode}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ export default function userPage() {
|
|||
// 获取数据
|
||||
useEffect(() => {
|
||||
document.cookie =
|
||||
'ecology_JSessionid=aaahTt6JHXEIM-HoSW-Xy; JSESSIONID=aaahTt6JHXEIM-HoSW-Xy; Systemlanguid=7; languageidweaver=7; loginuuids=2773; __randcode__=a8294fa0-56d7-430f-a35b-139d73474682; loginidweaver=zhangxy16';
|
||||
'ecology_JSessionid=aaaIEE6qGEj4i9Tg8sO_y; JSESSIONID=aaaIEE6qGEj4i9Tg8sO_y; loginuuids=1; languageidweaver=7; Systemlanguid=7; loginidweaver=sysadmin;';
|
||||
d3.json(
|
||||
'/api/bs/hrmorganization/orgchart/userData?fclass=0&fisvitual=0&root=0&level=3&id=0',
|
||||
).then((data) => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
export const i18n = {
|
||||
fclass: { cn: '维度', en: 'Organizational type' },
|
||||
companyRoot: { cn: '分部根节点', en: 'Company' },
|
||||
deptRoot: { cn: '部门根节点', en: 'Department' },
|
||||
deptLevel: { cn: '部门层级', en: 'Hierarchy' },
|
||||
search: { cn: '查询', en: 'Search' },
|
||||
export: { cn: '导出', en: 'Export' },
|
||||
exportImage: { cn: '导出图片', en: ' Export Image' },
|
||||
exportTable: { cn: '导出表格', en: ' Export Table' },
|
||||
hideDept: { cn: '隐藏部门', en: 'Hide Department' },
|
||||
virtual: { cn: '显示虚拟组织', en: 'View Virtual Organization' },
|
||||
detailInfo: { cn: '详细信息', en: 'Detailed Information' },
|
||||
head: { cn: '负责人', en: 'Head' },
|
||||
onJob: { cn: '在岗', en: 'HeadCount' },
|
||||
serveAge: { cn: '司龄', en: 'Serving Age' },
|
||||
year: { cn: '年', en: 'Year' },
|
||||
postion: { cn: '岗位', en: 'Position' },
|
||||
level: { cn: '职等', en: 'Level' },
|
||||
postionInfo: { cn: '岗位职责', en: 'Job Responsibilities' },
|
||||
close: { cn: '关闭', en: 'Close' },
|
||||
employeeInfo: { cn: '人员详情', en: 'Employee Information' },
|
||||
placeholder: { cn: '请选择', en: 'Please Select' },
|
||||
all: { cn: '全部', en: 'All' },
|
||||
showJob: { cn: '是否显示岗位', en: 'Is Show Job' },
|
||||
searchRemind: {
|
||||
cn: '请选择部门根节点再进行查询!',
|
||||
en: 'Please select the department root node to query again!',
|
||||
},
|
||||
httpRemind: { cn: '暂无数据!', en: 'No data available' },
|
||||
noAuth: {
|
||||
cn: '对不起,您暂时没有权限!',
|
||||
en: 'Sorry, you do not have permission for the time being!',
|
||||
},
|
||||
|
||||
tips: { cn: '提示', en: 'Tips' },
|
||||
tipsContent: {
|
||||
cn: '组织架构图中编制数和在编数显示初始化需参考文档配置定时任务并执行!!!(编制数默认取本年度最新编制信息,人数统计展示仅限于行政维度)',
|
||||
en: 'The number of entries and the number of entries displayed in the organizational diagram Initialize the scheduled task and execute it. (The compilation number is the latest compilation information of this year by default, and the display of the number of people is limited to the administrative dimension)',
|
||||
},
|
||||
tipsDept: {
|
||||
cn: '提示:开启后将只显示分部组织架构!!!',
|
||||
en: 'Tip: Only the branch organization structure will be displayed after it is turned on!!!',
|
||||
},
|
||||
tipsVirtual: {
|
||||
cn: '提示:若启用虚拟组织,需要在分部自定义表增加字段(名称 fblx) 字段类型 下拉框(0实体 1虚拟) 部门自定义表同上(字段名称 bmlx)。',
|
||||
en: 'Tip: If virtual organization is enabled, you need to add a field (name fblx) Field type drop-down box (0 entity 1 Virtual) to the department custom table as above (field name bmlx).',
|
||||
},
|
||||
|
||||
/** 表头 */
|
||||
table: {
|
||||
no: { cn: '序号', en: 'No' },
|
||||
workCode: { cn: '工号', en: 'WorkCode' },
|
||||
lastName: { cn: '姓名', en: 'LastName' },
|
||||
gender: { cn: '性别', en: 'Gender' },
|
||||
department: { cn: '部门', en: 'Department' },
|
||||
company: { cn: '分部', en: 'Company' },
|
||||
possition: { cn: '岗位', en: 'Possition ' },
|
||||
mobile: { cn: '手机号', en: 'Mobile Phone Number ' },
|
||||
|
||||
orgInfo: { cn: '组织信息', en: 'Organization Information' },
|
||||
total: { cn: '共', en: 'in total' },
|
||||
records: { cn: '条', en: 'records' },
|
||||
},
|
||||
};
|
||||