Compare commits

...

12 Commits

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

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,146 +315,126 @@ 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 }}
checked={this.state.requestData.hidedept == '1'}
onChange={(e) =>
this.handleFormChange({
hidedept: e.target.checked ? '1' : '0',
})
}
>
{i18n.hideDept[language]}
</Checkbox>
<Tooltip
title={i18n.tipsDept[language]}
color="#0082fb"
placement="rightTop"
>
<QuestionCircleOutlined
style={{ color: '#0082fb', cursor: 'pointer', fontSize: 16 }}
/>
</Tooltip>
</Col>
) : (
''
)}
<Col span={6}>
<Checkbox
style={{ marginTop: '5px', marginLeft: 100 }}
checked={this.state.requestData.hidedept == '1'}
onChange={(e) =>
this.handleFormChange({
hidedept: e.target.checked ? '1' : '0',
})
}
>
隐藏部门
</Checkbox>
<Tooltip
title="提示:开启后将只显示分部组织架构!!!"
color="#0082fb"
placement="rightTop"
>
<QuestionCircleOutlined
style={{ color: '#0082fb', cursor: 'pointer', fontSize: 16 }}
/>
</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' }}>
<Col span={6}>
<Checkbox
style={{ marginTop: '5px' }}
checked={this.state.requestData.fisvitual == '1'}
onChange={(e) =>
this.handleFormChange({
fisvitual: e.target.checked ? '1' : '0',
})
}
>
显示虚拟组织
</Checkbox>
<Tooltip
title="提示:若启用虚拟组织,需要在分部自定义表增加字段(名称 fblx) 字段类型 下拉框(0实体 1虚拟) 部门自定义表同上(字段名称 bmlx)。"
color="#0082fb"
placement="rightTop"
>
<QuestionCircleOutlined
style={{ color: '#0082fb', cursor: 'pointer', fontSize: 16 }}
{fclass == '0' ? (
<Col span={6}>
<Checkbox
style={{ marginTop: '5px' }}
checked={this.state.requestData.fisvitual == '1'}
onChange={(e) =>
this.handleFormChange({
fisvitual: e.target.checked ? '1' : '0',
})
}
>
{i18n.virtual[language]}
</Checkbox>
<Tooltip
title={i18n.tipsVirtual[language]}
color="#0082fb"
placement="rightTop"
>
<QuestionCircleOutlined
style={{ color: '#0082fb', cursor: 'pointer', fontSize: 16 }}
/>
</Tooltip>
</Col>
) : (
''
)}
{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
/>
</Tooltip>
</Col>
<Col span={16}>
<Button
type="primary"
style={{ marginRight: '10px' }}
disabled={disabled}
onClick={() => {
this.setState({ open: true });
}}
>
版本记录
</Button>
</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 =
'/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;
}
let request = { ...topbar.state.requestData, ids: idsStr };
let api =
'/api/bs/hrmorganization/orgchart/asyncCompanyData' +
qs.stringify(request, { addQueryPrefix: true });
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`;
}
}
//
@ -106,10 +113,10 @@ export default function companyPage() {
return fisvitual == '0' ? `./img/back/level1.png` : `./img/back/level5.png`;
}
//
//
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' },
},
};
Loading…
Cancel
Save