Compare commits

..

14 Commits

Author SHA1 Message Date
liang.cheng 170dfe720a Merge pull request 'feature/cl' (#17) from feature/cl into master
Reviewed-on: #17
5 months ago
Chengliang 8e8569110e 多语言遗留问题修复 6 months ago
Chengliang dce9480ee9 组织架构图更新根节点 8 months ago
liang.cheng 2b8751d7dd Merge pull request '组织架构图增加版本删除功能' (#16) from feature/cl into master
Reviewed-on: #16
9 months ago
Chengliang c9005b9a08 组织架构图增加版本删除功能 9 months ago
liang.cheng 0bc78d717f Merge pull request 'feature/cl' (#15) from feature/cl into master
Reviewed-on: #15
10 months ago
liang.cheng 0513ad1345 Merge pull request 'feature/cl' (#14) from feature/cl into master
Reviewed-on: #14
10 months ago
liang.cheng f825a33bb8 Merge pull request '多语言设置' (#11) from feature/cl into master
Reviewed-on: #11
10 months ago
liang.cheng 68402ffb6e Merge pull request '组织架构图多语言设置' (#10) from feature/cl into master
Reviewed-on: #10
11 months ago
liang.cheng 67cfb21f72 Merge pull request '修复已知问题' (#9) from feature/cl into master
Reviewed-on: #9
12 months ago
liang.cheng 2a5628765e Merge pull request 'feature/cl' (#8) from feature/cl into master
Reviewed-on: #8
1 year ago
liang.cheng 32e1b51632 Merge pull request 'feature/cl' (#7) from feature/cl into master
Reviewed-on: #7
2 years ago
liang.cheng 747a625c1c Merge pull request 'feature/cl' (#6) from feature/cl into master
Reviewed-on: #6
2 years ago
liang.cheng 038c6fef3c Merge pull request '组织快捷调整页面' (#5) from feature/cl into master
Reviewed-on: #5
2 years ago

Binary file not shown.

@ -367,6 +367,7 @@ export default class DrawerComponents extends React.Component {
};
onStatusChange = (checkedValues) => {
const { labelData } = this.props;
if (checkedValues.length === 0) {
return message.error(`${getLabel(547728, labelData)}`, 2);
}
@ -384,6 +385,7 @@ export default class DrawerComponents extends React.Component {
};
onTypeChange = (checkedValues) => {
const { labelData } = this.props;
if (this.state.showJob) {
return message.error(`${getLabel(547729, labelData)}`, 2);
}

@ -7,10 +7,12 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React from 'react';
import { Timeline, Drawer } from 'antd';
import { Timeline, Drawer, Popconfirm, message } from 'antd';
import styles from './index.less';
import leftTreeShow from './img/leftTree-show.png';
import leftHide from './img/leftTree-hide.png';
import { CloseCircleOutlined } from '@ant-design/icons';
import { getLabel } from '../../util/i18n.js';
export default class TimeLine extends React.Component {
constructor(props) {
@ -35,6 +37,21 @@ export default class TimeLine extends React.Component {
this.props.onClick(data);
}
handleDelete(key) {
const { labelData } = this.props;
let api = `/api/bs/hrmorganization/orgchart/versionDelete?versionId=${key}`;
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.api_status) {
message.success(`${getLabel(547484, labelData)}`, 2, 3);
window.location.reload(true);
} else {
message.error(`${getLabel(547483, labelData)}`, 2, 3);
}
});
}
componentDidMount() {
this.searchTimeLines(this.props.url);
}
@ -56,6 +73,8 @@ export default class TimeLine extends React.Component {
};
render() {
const { labelData } = this.props;
let showStyle = {};
let positionStyle = {};
if (this.state.open) {
@ -89,14 +108,30 @@ export default class TimeLine extends React.Component {
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
className={styles.title}
style={{
color: item.color == 'blue' ? '#1890ff' : 'dimgray',
}}
onClick={this.handleLineClick.bind(this, item)}
>
{item.title}
</div>
{item.key != 0 && (
<Popconfirm
title={`${getLabel(547491, labelData)}[${item.title}]?`}
onConfirm={this.handleDelete.bind(this, item.key)}
okText={getLabel(547319, labelData)}
cancelText={getLabel(547318, labelData)}
>
<div className={styles.delete}>
<CloseCircleOutlined />
</div>
</Popconfirm>
)}
<div className={styles.time}>{item.time}</div>
</Timeline.Item>
);

@ -15,21 +15,25 @@
cursor: pointer;
}
.timeline :hover {
color: #1890ff;
}
// .timeline .title:hover {
// color: #1890ff;
// }
.time {
color: dimgray;
}
.delete :hover {
color: red;
}
}
.leftRightLayoutBtn {
width: 18px;
height: 60px;
position: absolute;
position: fixed;
top: 50%;
margin-top: -30px;
// margin-top: -30px;
z-index: 101;
cursor: pointer;
}

@ -22,7 +22,7 @@ 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, FolderOutlined } from '@ant-design/icons';
moment.locale('zh-cn');
import { getLabel } from '../../util/i18n.js';
import { SmileOutlined } from '@ant-design/icons';
@ -45,6 +45,8 @@ export class TopBar extends React.Component {
open: false,
confirmLoading: false,
description: '',
timelineId: '0',
treeKey: 1,
};
}
@ -57,10 +59,29 @@ export class TopBar extends React.Component {
this.setState({ requestData });
}
handleTreeData(treeData = [], timelineId) {
this.setState({
rootTreeData: treeData,
timelineId: timelineId,
treeKey: this.state.treeKey + 1,
});
}
onChange = (e) => {
this.setState({ description: e.target.value });
};
generateKey = (
length = 5,
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
) => {
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
};
/**
* 弹窗确认
*/
@ -117,6 +138,9 @@ export class TopBar extends React.Component {
}
arr.map((item, index) => {
item.icon = <HomeOutlined />;
if (item.type == 2) {
item.icon = <FolderOutlined />;
}
});
this.setState({
rootTreeData: arr,
@ -135,11 +159,14 @@ export class TopBar extends React.Component {
const { id } = treeNode;
setTimeout(() => {
const { fclass } = this.state.requestData;
const { timelineId } = this.state;
let api =
'/api/bs/hrmorganization/orgchart/getSubCompanyTree?subcompany=' +
id +
'&fclass=' +
fclass;
fclass +
'&id=' +
timelineId;
this.getNodeTreeNode(api);
resolve(undefined);
}, 500);
@ -192,7 +219,8 @@ export class TopBar extends React.Component {
render() {
const { disabled, type, labelData } = this.props;
const { rootTreeData, open, confirmLoading, treeExpandedKeys } = this.state;
const { rootTreeData, open, confirmLoading, treeExpandedKeys, treeKey } =
this.state;
return (
<div className={style.topbarWrapper}>
@ -229,9 +257,11 @@ export class TopBar extends React.Component {
))}
</Select>
</Col>
<Col span={6}>
<Col span={8}>
{getLabel(547294, labelData)}
<TreeSelect
key={treeKey}
treeDataSimpleMode
allowClear
style={{ width: '65%' }}
@ -244,7 +274,7 @@ export class TopBar extends React.Component {
treeIcon
/>
</Col>
<Col span={6}>
<Col span={5}>
<Checkbox
style={{ marginTop: '5px', marginLeft: 100 }}
checked={this.state.requestData.hidedept == '1'}
@ -266,7 +296,7 @@ export class TopBar extends React.Component {
/>
</Tooltip>
</Col>
<Col span={6}>
<Col span={5}>
{getLabel(547299, labelData)}
<Select
defaultValue="3"
@ -304,7 +334,8 @@ export class TopBar extends React.Component {
/>
</Tooltip>
</Col>
<Col span={16}>
<Col span={10}>
{this.state.requestData.fclass == '0' && (
<span>
<Button
@ -334,7 +365,7 @@ export class TopBar extends React.Component {
}}
>
{getLabel(547313, labelData)}
</Button>{' '}
</Button>
</span>
)}

@ -351,6 +351,10 @@ export default function companyPage() {
*/
const handleExport = (type) => {
if (type == 'png') {
const hiddenElements = document.querySelectorAll('.tooltitle');
const hiddenElementsArray = Array.from(hiddenElements);
// DOM
hiddenElementsArray.forEach((el) => (el.style.display = 'none'));
orgChart && orgChart.exportImg({ full: true });
} else {
orgChart && downloadPdf(orgChart);
@ -371,6 +375,8 @@ export default function companyPage() {
hidedept: '0',
};
topbar.handleFormChange({ ...resetParams });
//
topbar.handleTreeData([], timeline.id);
topbar.getNodeTreeNode(
`/api/bs/hrmorganization/orgchart/getSubCompanyTree?fclass=${fclass}&id=${timeline.id}`,
false,
@ -490,6 +496,7 @@ export default function companyPage() {
timeLineSearch(timeline);
}}
url={'/api/bs/hrmorganization/orgchart/timeLines?fclass=0'}
labelData={labelData}
/>
<Spin size="large" spinning={spinning}>
<OrgChartComponent

@ -5,6 +5,7 @@ import qs from 'qs';
import MergeDialog from '../components/dialog/mergeDialog';
import CopyDialog from '../components/dialog/copyDialog';
import inset from '../../public/img/back/inset.png';
import { getLabel } from '../util/i18n.js';
import {
HomeOutlined,
@ -21,7 +22,7 @@ const DragTree = () => {
const [expandedKeys, setExpandedKeys] = useState([undefined]);
const childRef = useRef(null);
const copyChildRef = useRef(null);
const [tip, setTip] = useState('正在加载,请稍候...');
const [tip, setTip] = useState('');
const [loading, setLoading] = useState(false);
const [showCanceled, setShowCanceled] = useState(0);
const [drawerOpen, setDrawerOpen] = useState(false);
@ -36,6 +37,7 @@ const DragTree = () => {
useEffect(() => {
d3.json('/api/bs/hrmorganization/orgchart/i18n').then((res) => {
setLabelData(res.data);
setTip(`${getLabel(547473, res.data)}`);
});
getMoveTree(0);
}, [true]);
@ -75,40 +77,26 @@ const DragTree = () => {
const dropPosition =
info.dropPosition - Number(dropPos[dropPos.length - 1]);
if (dropPosition == -1 || dropPosition == 1) {
return message.error('不支持该操作!!!', 2);
if (dropPosition == -1) {
return message.error(`${getLabel(547475, labelData)}`, 2);
}
let pos =
dropPosition == 0
? `${getLabel(547476, labelData)}`
: `${getLabel(547477, labelData)}`;
let pos = dropPosition == 0 ? '内部' : '下方';
let title = `确定将【${info.dragNode.title}】移到 【${info.node.title}${pos}`;
let title = `${getLabel(547478, labelData)}${
info.dragNode.title
} ${getLabel(547479, labelData)} ${info.node.title}${pos}`;
Modal.confirm({
title: '转移操作(仅转移到内部时工作流提醒生效)',
title: `${getLabel(547480, labelData)}`,
content: title,
okText: '确认',
cancelText: '取消',
async onOk() {
okText: `${getLabel(547319, labelData)}`,
cancelText: `${getLabel(547318, labelData)}`,
onOk() {
setLoading(true);
setTip('正在转移,请稍候...');
if (dropPosition == 0) {
let extend = 'dept';
let tranfeserType = 1;
if (dragKey.slice(0, 1).toLowerCase() === 's') {
extend = 'comp';
tranfeserType = 2;
}
if (dropKey.slice(0, 1).toLowerCase() === 's') {
tranfeserType = 2;
}
await messageRemind(
extend,
'MOVE',
dragKey.slice(1),
false,
dropKey.slice(1),
'',
tranfeserType,
);
}
setTip(`${getLabel(547481, labelData)}`);
fetch('/api/bs/hrmorganization/dept/dragDepartment', {
method: 'POST',
headers: {
@ -165,14 +153,14 @@ const DragTree = () => {
}
}
setGData(data);
message.success('转移成功', 2);
message.success(`${getLabel(547482, labelData)}`, 2);
} else {
message.warning(res.msg, 2);
}
setLoading(false);
})
.catch((error) => {
message.error('接口异常,请联系管理员');
message.error(`${getLabel(547483, labelData)}`);
});
},
onCancel() {},
@ -185,14 +173,12 @@ const DragTree = () => {
*/
const onDelete = (nodeData) => {
const extend = nodeData.type == '1' ? 'comp' : 'dept';
let id = nodeData.id.substring(1);
let title = nodeData.title;
fetch(`/api/bs/hrmorganization/${extend}/deleteByIds`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ ids: id }),
body: JSON.stringify({ ids: nodeData.id.substring(1) }),
})
.then((response) => response.json())
.then((res) => {
@ -203,81 +189,17 @@ const DragTree = () => {
arr.splice(index, 1);
});
setGData(data);
message.success('删除成功', 2);
messageRemind(extend, 'DELETE', title);
message.success(`${getLabel(547484, labelData)}`, 2);
} else {
message.warning(res.data.message, 2);
}
}
})
.catch((error) => {
message.error('接口异常,请联系管理员');
message.error(`${getLabel(547483, labelData)}`);
});
};
/**
* 工作流提醒
*/
const messageRemind = (
type,
operateType,
fromId,
canceled,
toId = '',
mergeName = '',
tranfeserType = null,
) => {
debugger;
return new Promise((reslove, reject) => {
let params = {
workflowId: 1,
operateType: operateType,
mergeName: mergeName,
type: type,
canceled: canceled,
tranfeserType: tranfeserType,
};
if (type == 'dept') {
params = {
...params,
departmentIdFrom: fromId,
};
if (tranfeserType == 2) {
params = {
...params,
subCompanyIdTo: toId,
};
} else {
params = {
...params,
departmentIdTo: toId,
};
}
} else {
params = {
...params,
subCompanyIdFrom: fromId,
subCompanyIdTo: toId,
};
}
fetch('/api/bs/hrmorganization/remind/quickly/workflow/message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
})
.then((response) => response.json())
.then((res) => {
reslove();
})
.catch((error) => {
message.error('系统默认工作流提醒失败');
});
});
};
/**
* 封存
* @param {*} nodeData
@ -285,16 +207,14 @@ const DragTree = () => {
const onCancel = (nodeData) => {
setShowCanceled(0);
const extend = nodeData.type == '1' ? 'comp' : 'dept';
let id = nodeData.id.substring(1);
let canceled = nodeData.canceled != '0';
fetch(`/api/bs/hrmorganization/${extend}/updateForbiddenTagById`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: id,
canceled: canceled,
id: nodeData.id.substring(1),
canceled: nodeData.canceled != '0',
}),
})
.then((response) => response.json())
@ -302,7 +222,7 @@ const DragTree = () => {
if (res.code == 200) {
const data = [...gData];
if (nodeData.canceled != '0') {
message.success('恢复成功', 2);
message.success(`${getLabel(547485, labelData)}`, 2);
loop(data, nodeData.key, (item, index, arr) => {
arr[index].canceled = '0';
});
@ -310,16 +230,15 @@ const DragTree = () => {
loop(data, nodeData.key, (item, index, arr) => {
arr.splice(index, 1);
});
message.success('封存成功', 2);
message.success(`${getLabel(547486, labelData)}`, 2);
}
setGData(data);
messageRemind(extend, 'CANCELED', id, canceled);
} else {
message.warning(res.msg, 2);
}
})
.catch((error) => {
message.error('接口异常,请联系管理员');
message.error(`${getLabel(547483, labelData)}`);
});
};
@ -336,13 +255,10 @@ const DragTree = () => {
};
const onMergeCreate = (values) => {
let fromId = mergeId.substring(1);
let toId = values.department.substring(1);
let mergeName = values.mergeName;
let params = {
department: toId,
mergeName: mergeName,
id: fromId,
department: values.department.substring(1),
mergeName: values.mergeName,
id: mergeId.substring(1),
};
fetch('/api/bs/hrmorganization/dept/mergeDepartment', {
method: 'POST',
@ -355,15 +271,14 @@ const DragTree = () => {
.then((res) => {
if (res.code == 200) {
getMoveTree(0, values.department);
message.success('合并成功', 2);
messageRemind('dept', 'MERGE', fromId, false, toId, mergeName);
message.success(`${getLabel(547487, labelData)}`, 2);
} else {
message.warning(res.msg, 2);
}
setOpen(false);
})
.catch((error) => {
message.error('接口异常,请联系管理员');
message.error(`${getLabel(547483, labelData)}`);
});
};
@ -397,13 +312,13 @@ const DragTree = () => {
if (res.code == 200) {
setCopyOpen(false);
getMoveTree(0, values.company);
message.success('复制成功', 2);
message.success(`${getLabel(547488, labelData)}`, 2);
} else {
message.warning(res.msg, 2);
}
})
.catch((error) => {
message.error('接口异常,请联系管理员');
message.error(`${getLabel(547483, labelData)}`);
});
};
@ -429,7 +344,7 @@ const DragTree = () => {
{nodeData.title}
{nodeData.canceled == '1' ? (
<span style={{ color: 'red', marginLeft: '5px' }}>
(已封存)
({getLabel(547489, labelData)})
</span>
) : (
''
@ -448,25 +363,28 @@ const DragTree = () => {
);
}}
>
查看
{getLabel(547490, labelData)}
</span>
{/**<Popconfirm
title={`确认要删除[${nodeData.title}]?`}
<Popconfirm
title={`${getLabel(547491, labelData)}[${nodeData.title}]?`}
onConfirm={() => onDelete(nodeData)}
okText="确认"
cancelText="取消"
okText={getLabel(547319, labelData)}
cancelText={getLabel(547318, labelData)}
>
<span className="drag-button">删除</span>
<span className="drag-button">
{getLabel(547492, labelData)}
</span>
</Popconfirm>
**/}
<Popconfirm
title={`确认要封存或恢复 [${nodeData.title}]?`}
title={`${getLabel(547493, labelData)} [${nodeData.title}]?`}
onConfirm={() => onCancel(nodeData)}
okText="确认"
cancelText="取消"
okText={getLabel(547319, labelData)}
cancelText={getLabel(547318, labelData)}
>
<span className="drag-button">
{nodeData.canceled == '0' ? '封存' : '恢复'}
{nodeData.canceled == '0'
? `${getLabel(547494, labelData)}`
: `${getLabel(547495, labelData)}`}
</span>
</Popconfirm>
<span
@ -474,14 +392,14 @@ const DragTree = () => {
className="drag-button"
onClick={() => onMerge(nodeData)}
>
合并
{getLabel(547194, labelData)}
</span>
<span
style={{ display: attr }}
className="drag-button"
onClick={() => onCopy(nodeData)}
>
复制
{getLabel(547196, labelData)}
</span>
</div>
</>
@ -495,84 +413,84 @@ const DragTree = () => {
};
return (
<div className="drag-wrapper">
<Spin tip={tip} spinning={loading}>
<div className="drag-layout">
<div className="drag-header">
<img src={inset} />
<div>组织快速调整</div>
</div>
<div className="drag-content">
<ApartmentOutlined
className="drag-showcanceled"
style={{ color: showCanceled == 0 ? '#000' : '#1890ff' }}
onClick={() => {
const value = showCanceled == 0 ? 1 : 0;
setTip('正在加载,请稍候...');
setShowCanceled(value);
getMoveTree(value);
}}
/>
<Tree
className="draggable-tree"
//defaultExpandedKeys={expandedKeys}
expandedKeys={expandedKeys}
onExpand={onExpand}
draggable
icon={false}
blockNode
onDragEnter={onDragEnter}
onDrop={onDrop}
treeData={gData}
titleRender={onTitleRender}
/>
</div>
<Drawer
width="60%"
placement="right"
closable={false}
onClose={() => setDrawerOpen(false)}
open={drawerOpen}
>
<iframe src={iframe} width="100%" height="100%" />
</Drawer>
Object.keys(labelData).length != 0 && (
<div className="drag-wrapper">
<Spin tip={tip} spinning={loading}>
<div className="drag-layout">
<div className="drag-header">
<img src={inset} />
<div>{getLabel(547282, labelData)}</div>
</div>
<div className="drag-content">
<ApartmentOutlined
className="drag-showcanceled"
style={{ color: showCanceled == 0 ? '#000' : '#1890ff' }}
onClick={() => {
const value = showCanceled == 0 ? 1 : 0;
setTip(`${getLabel(547473, labelData)}`);
setShowCanceled(value);
getMoveTree(value);
}}
/>
<Tree
className="draggable-tree"
//defaultExpandedKeys={expandedKeys}
expandedKeys={expandedKeys}
onExpand={onExpand}
draggable
icon={false}
blockNode
onDragEnter={onDragEnter}
onDrop={onDrop}
treeData={gData}
titleRender={onTitleRender}
/>
</div>
<Drawer
width="60%"
placement="right"
closable={false}
onClose={() => setDrawerOpen(false)}
open={drawerOpen}
>
<iframe src={iframe} width="100%" height="100%" />
</Drawer>
<div className="drag-footer">
<p>
<QuestionCircleOutlined />
小提示
</p>
<div className="tips">
<div>1.鼠标拖拽Tree节点到任一分部部门下可快速完成组织转移;</div>
<div>2.点击查看侧滑打开组织详细信息,可快速编辑;</div>
<div>
3.鼠标悬停树节点 一键开启删除封存合并复制等功能;
<div className="drag-footer">
<p>
<QuestionCircleOutlined />
{getLabel(547283, labelData)}
</p>
<div className="tips">
<div>1.{getLabel(547284, labelData)}</div>
<div>2.{getLabel(547285, labelData)}</div>
<div>3.{getLabel(547286, labelData)}</div>
<div>4.{getLabel(547287, labelData)}</div>
</div>
<div>4.顶部小图标点击可显示已封存的组织架构</div>
</div>
</div>
</div>
</Spin>
</Spin>
<MergeDialog
ref={childRef}
open={open}
onCreate={onMergeCreate}
onCancel={() => {
setOpen(false);
}}
labelData={labelData}
/>
<CopyDialog
ref={copyChildRef}
open={copyopen}
onCreate={onCopyCreate}
onCancel={() => {
setCopyOpen(false);
}}
labelData={labelData}
/>
</div>
<MergeDialog
ref={childRef}
open={open}
onCreate={onMergeCreate}
onCancel={() => {
setOpen(false);
}}
labelData={labelData}
/>
<CopyDialog
ref={copyChildRef}
open={copyopen}
onCreate={onCopyCreate}
onCancel={() => {
setCopyOpen(false);
}}
labelData={labelData}
/>
</div>
)
);
};
export default DragTree;

@ -99,7 +99,7 @@ export default function userPage() {
//
useEffect(() => {
document.cookie =
'ecology_JSessionid=aaayMjvxCzkVJaNpQnW7y; JSESSIONID=aaayMjvxCzkVJaNpQnW7y; __randcode__=d1d05beb-637c-4417-bee5-e7ee0061eb7e; Systemlanguid=7; languageidweaver=7; loginidweaver=sysadmin;';
'ecology_JSessionid=aaaLiDqzA0rZHgPBdxGez; JSESSIONID=aaaLiDqzA0rZHgPBdxGez; Systemlanguid=7; languageidweaver=7; loginuuids=1; loginidweaver=sysadmin; __randcode__=7b9b3b9b-a780-4d6a-b8d5-22d0f8aaf11a';
d3.json(
'/api/bs/hrmorganization/orgchart/userData?fclass=0&fisvitual=0&root=0&level=3&id=0',
).then((data) => {

Loading…
Cancel
Save