根节点组件修改
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: Chengliang 1546584672@qq.com
|
||||
* @Date: 2023-06-25 16:33:21
|
||||
* @LastEditors: Chengliang 1546584672@qq.com
|
||||
* @LastEditTime: 2023-06-25 18:15:45
|
||||
* @LastEditTime: 2023-06-27 10:51:02
|
||||
* @FilePath: /org-chart-frant/src/components/timeline/index.jsx
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
|
|
@ -18,8 +18,18 @@ export default class TimeLine extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
handleLineClick(item) {
|
||||
debugger;
|
||||
handleLineClick(data) {
|
||||
let newList = this.state.timelineList.map((item) => {
|
||||
item.color = 'grey';
|
||||
if (item.key == data.key) {
|
||||
item.color = 'blue';
|
||||
}
|
||||
return item;
|
||||
});
|
||||
this.setState({
|
||||
timelineList: newList,
|
||||
});
|
||||
this.props.onClick(data);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
@ -31,17 +41,17 @@ export default class TimeLine extends React.Component {
|
|||
// });
|
||||
// });
|
||||
const datas = [
|
||||
{ key: '0', title: '当前版本', color: 'blue', time: '2022-01-09' },
|
||||
{ key: '1', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '2', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '3', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '4', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '5', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '6', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '7', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '8', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '9', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: '10', title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 0, title: '当前版本', color: 'blue', time: '2022-01-09' },
|
||||
{ key: 1, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 2, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 3, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 4, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 5, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 6, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 7, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 8, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 9, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
{ key: 10, title: '测试', color: 'grey', time: '2022-01-09' },
|
||||
];
|
||||
this.setState({
|
||||
timelineList: datas,
|
||||
|
|
@ -55,11 +65,13 @@ export default class TimeLine extends React.Component {
|
|||
{this.state.timelineList.map((item) => {
|
||||
return (
|
||||
<Timeline.Item
|
||||
key={item.key}
|
||||
onClick={this.handleLineClick.bind(this, item)}
|
||||
className={styles.timeline}
|
||||
color={item.color}
|
||||
style={{ color: item.color == 'blue' ? '#1890ff' : 'dimgray' }}
|
||||
>
|
||||
<div>{item.title}</div>{' '}
|
||||
<div>{item.title}</div>
|
||||
<div className={styles.time}>{item.time}</div>
|
||||
</Timeline.Item>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
.lineWrapper {
|
||||
width: 208px;
|
||||
height: 480px;
|
||||
height: calc(~'100% - 200px');
|
||||
overflow-y: scroll;
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
padding-left: 20px;
|
||||
|
||||
.timeline {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -21,3 +23,33 @@
|
|||
color: dimgray;
|
||||
}
|
||||
}
|
||||
|
||||
.lineWrapper::-webkit-scrollbar {
|
||||
/*滚动条整体样式*/
|
||||
width: 10px;
|
||||
/*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.lineWrapper::-webkit-scrollbar-thumb {
|
||||
/*滚动条里面小方块*/
|
||||
border-radius: 10px;
|
||||
background-color: skyblue;
|
||||
background-image: -webkit-linear-gradient(
|
||||
45deg,
|
||||
rgba(255, 255, 255, 0.2) 25%,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
rgba(255, 255, 255, 0.2) 50%,
|
||||
rgba(255, 255, 255, 0.2) 75%,
|
||||
transparent 75%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
.lineWrapper::-webkit-scrollbar-track {
|
||||
/*滚动条里面轨道*/
|
||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
background: #ededed;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
Col,
|
||||
Dropdown,
|
||||
Menu,
|
||||
TreeSelect,
|
||||
} from 'antd';
|
||||
const { Option } = Select;
|
||||
import moment from 'moment';
|
||||
|
|
@ -21,26 +22,33 @@ export class TopBar extends React.Component {
|
|||
super(props);
|
||||
this.state = {
|
||||
fclasslist: [],
|
||||
companylist: [],
|
||||
rootTreeData: [], //根节点异步树
|
||||
treeExpandedKeys: [],
|
||||
requestData: {
|
||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
fclass: '0',
|
||||
root: '0',
|
||||
root: undefined,
|
||||
level: '3',
|
||||
fisvitual: '0',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单值改变
|
||||
* @param {*} payload
|
||||
*/
|
||||
handleFormChange(payload) {
|
||||
let requestData = { ...this.state.requestData, ...payload };
|
||||
this.setState({ requestData });
|
||||
}
|
||||
//日期可选择未来
|
||||
// disabledDate (current) {
|
||||
// // return current && current >moment().subtract(1, "days");
|
||||
// return current && current > moment().endOf("day");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 组织维度改变
|
||||
*/
|
||||
changeFclass() {
|
||||
debugger;
|
||||
this.getSeatchCondition(this.props.url);
|
||||
}
|
||||
|
||||
handleExportMenuClick(e) {
|
||||
this.props.onExport(e.key == '1' ? 'png' : 'pdf');
|
||||
|
|
@ -50,16 +58,70 @@ export class TopBar extends React.Component {
|
|||
this.props.onExport('png');
|
||||
}
|
||||
|
||||
/**
|
||||
* 根节点树数据
|
||||
* @param {} parentId
|
||||
* @returns
|
||||
*/
|
||||
getNodeTreeNode = (parentId) => {
|
||||
const { fclass } = this.state.requestData;
|
||||
let api =
|
||||
'/api/bs/hrmorganization/orgchart/getSubCompanyTree?subcompany=' +
|
||||
parentId +
|
||||
'&fclass=' +
|
||||
fclass;
|
||||
fetch(api)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (data.api_status) {
|
||||
let arr = [...this.state.rootTreeData, ...data.companyTree];
|
||||
this.setState({
|
||||
rootTreeData: arr,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根节点树异步加载
|
||||
* @param {} parentId
|
||||
* @returns
|
||||
*/
|
||||
onRootLoadData = (treeNode) =>
|
||||
new Promise((resolve) => {
|
||||
const { id } = treeNode.props;
|
||||
setTimeout(() => {
|
||||
this.getNodeTreeNode(id);
|
||||
resolve(undefined);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onRootChange = (value) => {
|
||||
debugger;
|
||||
let requestData = { ...this.state.requestData, root: value };
|
||||
this.setState({ requestData });
|
||||
};
|
||||
|
||||
onTreeExpand = (expandedKeys) => {
|
||||
this.setState({
|
||||
treeExpandedKeys: expandedKeys,
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
fetch(this.props.url)
|
||||
this.getSeatchCondition(this.props.url);
|
||||
}
|
||||
|
||||
getSeatchCondition = (url) => {
|
||||
fetch(url)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
this.setState({
|
||||
fclasslist: data.fclasslist,
|
||||
companylist: data.companylist,
|
||||
rootTreeData: data.companyTree,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
menu = (
|
||||
<Menu
|
||||
|
|
@ -79,82 +141,47 @@ export class TopBar extends React.Component {
|
|||
|
||||
render() {
|
||||
const { disabled } = this.props;
|
||||
debugger;
|
||||
const { rootTreeData } = this.state;
|
||||
|
||||
return (
|
||||
<div className={style.topbarWrapper}>
|
||||
<Row>
|
||||
<Col span={6}>
|
||||
数据日期:
|
||||
<DatePicker
|
||||
placeholder="请选择日期"
|
||||
style={{ width: 130 }}
|
||||
locale={locale}
|
||||
allowClear={false}
|
||||
// disabledDate={this.disabledDate}
|
||||
defaultValue={moment(new Date())}
|
||||
value={
|
||||
this.state.requestData.date && this.state.requestData.date != ''
|
||||
? moment(this.state.requestData.date)
|
||||
: ''
|
||||
}
|
||||
onChange={(value) =>
|
||||
this.handleFormChange({
|
||||
date: value && value != '' ? value.format('YYYY-MM-DD') : '',
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={6}>
|
||||
维度:
|
||||
<Select
|
||||
defaultValue="0"
|
||||
style={{ width: 120 }}
|
||||
style={{ width: 140 }}
|
||||
value={this.state.requestData.fclass}
|
||||
onChange={(value) => this.handleFormChange({ fclass: value })}
|
||||
onChange={(value) => {
|
||||
this.handleFormChange({ fclass: value });
|
||||
this.props.onSearch(this.state.requestData);
|
||||
}}
|
||||
>
|
||||
{this.state.fclasslist.map((item) => (
|
||||
<Option value={item.id}>{item.companyname}</Option>
|
||||
<Option key={item.key} value={item.id}>
|
||||
{item.companyname}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Col>
|
||||
|
||||
<Col span={6}>
|
||||
根节点:
|
||||
<Select
|
||||
showSearch
|
||||
filterOption={(input, option) =>
|
||||
(option?.children).includes(input)
|
||||
}
|
||||
defaultValue="0"
|
||||
style={{ width: 120 }}
|
||||
<TreeSelect
|
||||
treeDataSimpleMode
|
||||
allowClear
|
||||
style={{ width: '80%' }}
|
||||
value={this.state.requestData.root}
|
||||
onChange={(value) => this.handleFormChange({ root: value })}
|
||||
>
|
||||
{this.state.companylist.map((item) => (
|
||||
<Option value={item.id}>{item.fname}</Option>
|
||||
))}
|
||||
</Select>
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder="请选择根节点"
|
||||
onChange={this.onRootChange}
|
||||
loadData={this.onRootLoadData}
|
||||
treeData={rootTreeData}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={6}>
|
||||
显示层级:
|
||||
<Select
|
||||
defaultValue="3"
|
||||
style={{ width: 120 }}
|
||||
value={this.state.requestData.level}
|
||||
onChange={(value) => this.handleFormChange({ level: value })}
|
||||
>
|
||||
<Option value="1">一级</Option>
|
||||
<Option value="2">二级</Option>
|
||||
<Option value="3">三级</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginTop: '15px' }}>
|
||||
<Col span={6}>
|
||||
<Checkbox
|
||||
style={{ marginTop: '5px' }}
|
||||
style={{ marginTop: '5px', marginLeft: 100 }}
|
||||
onChange={(e) =>
|
||||
this.handleFormChange({
|
||||
fisvitual: e.target.checked ? '1' : '0',
|
||||
|
|
@ -165,6 +192,21 @@ export class TopBar extends React.Component {
|
|||
</Checkbox>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
显示层级:
|
||||
<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>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{ marginTop: '15px' }}>
|
||||
<Col span={8}>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: '10px' }}
|
||||
|
|
@ -173,7 +215,7 @@ export class TopBar extends React.Component {
|
|||
this.props.onSynchronous(this.state.requestData);
|
||||
}}
|
||||
>
|
||||
同步数据
|
||||
版本记录
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
|
|
@ -184,7 +226,7 @@ export class TopBar extends React.Component {
|
|||
>
|
||||
查询
|
||||
</Button>
|
||||
<Dropdown menu={this.menu}>
|
||||
<Dropdown overlay={this.menu}>
|
||||
<Button>导出</Button>
|
||||
</Dropdown>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -70,14 +70,12 @@ export default function companyPage() {
|
|||
// 获取部门图片
|
||||
function getDepartmentImage() {
|
||||
let index = Math.floor(Math.random() * 8) + 1;
|
||||
// return `./img/department/${index}.png`;
|
||||
return `./img/department/1.png`;
|
||||
return `./img/back/level4.png`;
|
||||
}
|
||||
|
||||
// 获取部门图片
|
||||
// 获取分部图片
|
||||
function getSubcompanyImage() {
|
||||
let index = Math.floor(Math.random() * 3) + 1;
|
||||
// return `./img/subcompany/${index}.png`;
|
||||
return `./img/subcompany/2.png`;
|
||||
}
|
||||
|
||||
|
|
@ -118,9 +116,9 @@ export default function companyPage() {
|
|||
if (d.data.ftype == 0) {
|
||||
return 100;
|
||||
} else if (d.data.ftype == 1) {
|
||||
return 160;
|
||||
return 80;
|
||||
} else if (d.data.ftype == 2) {
|
||||
return 56;
|
||||
return 106;
|
||||
}
|
||||
return 120;
|
||||
};
|
||||
|
|
@ -152,18 +150,13 @@ export default function companyPage() {
|
|||
</div>
|
||||
</div>`;
|
||||
} else if (d.data.ftype == 1) {
|
||||
return `<div onclick="if(${
|
||||
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;
|
||||
return `<div onclick="if(${d.data.fisvitual}==1) return;window.open('${subcompanyUrl}', '_blank')">
|
||||
<div style="width: 144px; border: 1px solid #66BAF5; margin: 10px auto 0px; border-radius: 10px; text-align: center;
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 18px;
|
||||
height: 56px;
|
||||
padding: 15px 10px;
|
||||
">
|
||||
${d.data.fname}
|
||||
|
|
@ -174,17 +167,15 @@ export default function companyPage() {
|
|||
<div style="width: 100%; height: 100%; background-size: 100% 100%;" onclick="if(${
|
||||
d.data.fisvitual
|
||||
}==1) return;window.open('${departmentUrl}')">
|
||||
<div style='position:absolute'>
|
||||
<img src='./img/company_job_label.png'/></div>
|
||||
<div style="padding-left: 8px; padding-top: 23px;display:flex;align-items:center">
|
||||
<img src="${getDepartmentImage()}"/>
|
||||
<span style="
|
||||
margin-left: 3px;
|
||||
font-size: 12px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
">${d.data.fname}</span>
|
||||
<div style='position:absolute;height:100%'>
|
||||
<img style='width:144px;height:106px' src="${getDepartmentImage()}"/>
|
||||
</div>
|
||||
<div style="width: 144px;height: 80px;top: 35px;position: relative;font-weight: 400;font-size: 14px;
|
||||
font-family: Microsoft YaHei-Regular, Microsoft YaHei;color: #333333;text-align: center;">
|
||||
<div title=${
|
||||
d.data.fname
|
||||
} style="width: 110px;margin: 0 auto;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;-o-text-overflow:ellipsis;
|
||||
line-height: 18px;word-break: break-all;">${d.data.fname}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -268,6 +259,10 @@ export default function companyPage() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @param {*} type
|
||||
*/
|
||||
const handleExport = (type) => {
|
||||
if (type == 'png') {
|
||||
orgChart && orgChart.exportImg({ full: true });
|
||||
|
|
@ -276,6 +271,16 @@ export default function companyPage() {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 时间轴点击
|
||||
* @param {*} timeline
|
||||
*/
|
||||
const timeLineSearch = (timeline) => {};
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param {*} requestData
|
||||
*/
|
||||
const handleSearch = (requestData) => {
|
||||
topBarSearchRequest = requestData;
|
||||
let api =
|
||||
|
|
@ -295,6 +300,10 @@ export default function companyPage() {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 同步数据
|
||||
* @param {*} requestData
|
||||
*/
|
||||
const handleSynchronous = (requestData) => {
|
||||
setDisabled(true);
|
||||
let api = '/api/bs/hrmorganization/orgchart/synchronousData';
|
||||
|
|
@ -326,9 +335,8 @@ export default function companyPage() {
|
|||
.render();
|
||||
}
|
||||
}, [data]);
|
||||
// top bar end
|
||||
|
||||
if (hasRight === false) {
|
||||
//return message.error("对不起,您暂时没有权限", 2);
|
||||
return (
|
||||
<div style={{ width: '100%', top: '40%', position: 'absolute' }}>
|
||||
<img
|
||||
|
|
@ -366,7 +374,12 @@ export default function companyPage() {
|
|||
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
|
||||
onZoomBehavior={(value) => handleZoomBehavior(value)}
|
||||
/>
|
||||
<TimeLine url="/api/bs/hrmorganization/orgchart/timelines?type=company" />
|
||||
<TimeLine
|
||||
onClick={(timeline) => {
|
||||
timeLineSearch(timeline);
|
||||
}}
|
||||
url="/api/bs/hrmorganization/orgchart/timelines?type=company"
|
||||
/>
|
||||
<OrgChartComponent
|
||||
setChart={(chart) => (orgChart = chart)}
|
||||
setClick={(click) => (addNodeChildFunc = click)}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export default function userPage() {
|
|||
// 获取数据
|
||||
useEffect(() => {
|
||||
document.cookie =
|
||||
'ecology_JSessionid=aaabAoBxcpmhQ5GSTpXJy; JSESSIONID=aaabAoBxcpmhQ5GSTpXJy; Systemlanguid=7; languageidweaver=7; loginuuids=1; loginidweaver=sysadmin; __randcode__=137b6014-3b43-44f3-b921-3a7fddbbe91e';
|
||||
'ecology_JSessionid=aaabAoBxcpmhQ5GSTpXJy; JSESSIONID=aaabAoBxcpmhQ5GSTpXJy; Systemlanguid=7; languageidweaver=7; loginuuids=1; __randcode__=1e1d21ef-3a75-4eaa-b3b3-277fa0ca0ef3; loginidweaver=sysadmin';
|
||||
d3.json(
|
||||
// "/user/data"
|
||||
'/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=' +
|
||||
|
|
|
|||