diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..ce358e4
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..6560a98
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..cf64fc2
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..e674d91
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/org-chart-frant.iml b/.idea/org-chart-frant.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/org-chart-frant.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..198aa37
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ DEFINITION_ORDER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ActionScript specificJavaScript
+
+
+ Android
+
+
+ Ant
+
+
+ Batch Applications
+
+
+ CFML
+
+
+ CSS
+
+
+ Class structureJava
+
+
+ Code quality toolsCSS
+
+
+ Code quality toolsJavaScript
+
+
+ Code style issuesJava
+
+
+ CoffeeScript
+
+
+ CorrectnessLintAndroid
+
+
+ Cucumber
+
+
+ Error handlingJava
+
+
+ Faces Model
+
+
+ Flow type checkerJavaScript
+
+
+ FreeMarker
+
+
+ General
+
+
+ GeneralCoffeeScript
+
+
+ GeneralJavaScript
+
+
+ Google Web Toolkit
+
+
+ GrailsGroovy
+
+
+ Groovy
+
+
+ HTML
+
+
+ Hibernate
+
+
+ IconsUsabilityLintAndroid
+
+
+ ImportsJava
+
+
+ Inheritance issuesJava
+
+
+ Internationalization
+
+
+ InternationalizationJava
+
+
+ InternationalizationLintAndroid
+
+
+ Invalid elementsCSS
+
+
+ J2ME issuesJava
+
+
+ JSON and JSON5
+
+
+ JSP
+
+
+ Java
+
+
+ Java 8Java language level migration aidsJava
+
+
+ Java interop issuesKotlin
+
+
+ Java language level migration aidsJava
+
+
+ JavaFX
+
+
+ JavaScript
+
+
+ JavadocJava
+
+
+ Kotlin
+
+
+ LintAndroid
+
+
+ LintLintAndroid
+
+
+ Manifest
+
+
+ Markdown
+
+
+ MessagesCorrectnessLintAndroid
+
+
+ Node.jsJavaScript
+
+
+ OSGi
+
+
+ OtherGroovy
+
+
+ Pages Navigation Model
+
+
+ Plugin DevKit
+
+
+ PortabilityJava
+
+
+ Potentially confusing code constructsGroovy
+
+
+ Probable bugsJava
+
+
+ Properties Files
+
+
+ Properties FilesJava
+
+
+ RELAX NG
+
+
+ RESTful Web Service
+
+
+ Resource managementJava
+
+
+ SQL
+
+
+ Sass/SCSS
+
+
+ SecurityLintAndroid
+
+
+ SetupSpring CoreSpring
+
+
+ Spring
+
+
+ Spring BootSpring
+
+
+ Spring CoreSpring
+
+
+ Struts
+
+
+ Struts 1Struts
+
+
+ Struts 2Struts
+
+
+ Style issuesKotlin
+
+
+ TestNGJava
+
+
+ Threading issuesJava
+
+
+ TypeScript
+
+
+ UI Form
+
+
+ UsabilityLintAndroid
+
+
+ Validity issuesGroovy
+
+
+ Velocity
+
+
+ Verbose or redundant code constructsJava
+
+
+ VisibilityJava
+
+
+ Vue
+
+
+ Web Services
+
+
+ XML
+
+
+ XMLSpring CoreSpring
+
+
+ XPath
+
+
+ YAML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1689842546961
+
+
+ 1689842546961
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ fastdfs-client-java-1.27-RELEASE
+
+
+
+
+
+
+
+
+
+
+
+ 10
+
+
+
+
+
+
+
+
+
+
+
+ 1.8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.umirc.ts b/.umirc.ts
index e64d073..633ddc8 100644
--- a/.umirc.ts
+++ b/.umirc.ts
@@ -2,7 +2,7 @@
* @Author: Chengliang 1546584672@qq.com
* @Date: 2022-08-04 10:22:55
* @LastEditors: Chengliang 1546584672@qq.com
- * @LastEditTime: 2022-12-16 11:24:29
+ * @LastEditTime: 2023-07-24 09:57:14
* @FilePath: /org-chart-frant/.umirc.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -26,7 +26,8 @@ export default defineConfig({
proxy: {
'/api': {
// 标识需要进行转换的请求的url
- target: 'http://127.0.0.1:8686/api', // 服务端域名 / http://localhost:8686
+ //target: 'http://127.0.0.1:8686/api', // 服务端域名 / http://localhost:8686
+ target: 'http://221.226.25.34:11080/api',
changeOrigin: true, // 允许域名进行转换
pathRewrite: { '^/api': '' }, // 将请求url里的ci去掉
},
diff --git a/dist.zip b/dist.zip
new file mode 100644
index 0000000..6b4a674
Binary files /dev/null and b/dist.zip differ
diff --git a/package.json b/package.json
index 7f0d301..abd3425 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"@types/d3": "^7.4.0",
"d3": "7.4.4",
"d3-org-chart": "2.6.0",
+ "js-export-excel": "^1.1.4",
"jspdf": "^2.5.1",
"moment": "^2.29.3",
"qs": "^6.11.0",
diff --git a/public/img/back/level1.png b/public/img/back/level1.png
new file mode 100644
index 0000000..4d2a63d
Binary files /dev/null and b/public/img/back/level1.png differ
diff --git a/public/img/back/level2.png b/public/img/back/level2.png
new file mode 100644
index 0000000..2ab4d3c
Binary files /dev/null and b/public/img/back/level2.png differ
diff --git a/public/img/back/level3.png b/public/img/back/level3.png
new file mode 100644
index 0000000..e655097
Binary files /dev/null and b/public/img/back/level3.png differ
diff --git a/public/img/back/level4.png b/public/img/back/level4.png
new file mode 100644
index 0000000..06947e4
Binary files /dev/null and b/public/img/back/level4.png differ
diff --git a/public/img/back/level5.png b/public/img/back/level5.png
new file mode 100644
index 0000000..e77017a
Binary files /dev/null and b/public/img/back/level5.png differ
diff --git a/public/img/back/level6.png b/public/img/back/level6.png
new file mode 100644
index 0000000..6be044f
Binary files /dev/null and b/public/img/back/level6.png differ
diff --git a/public/img/back/level7.png b/public/img/back/level7.png
new file mode 100644
index 0000000..0d164b5
Binary files /dev/null and b/public/img/back/level7.png differ
diff --git a/public/img/back/level8.png b/public/img/back/level8.png
new file mode 100644
index 0000000..e2041c7
Binary files /dev/null and b/public/img/back/level8.png differ
diff --git a/public/img/change.png b/public/img/change.png
new file mode 100644
index 0000000..b08b481
Binary files /dev/null and b/public/img/change.png differ
diff --git a/public/img/department.png b/public/img/department.png
new file mode 100644
index 0000000..eb3c3d5
Binary files /dev/null and b/public/img/department.png differ
diff --git a/public/img/user-card/avatar-outer-green.png b/public/img/user-card/avatar-outer-green.png
new file mode 100644
index 0000000..aee791f
Binary files /dev/null and b/public/img/user-card/avatar-outer-green.png differ
diff --git a/public/img/user-card/jobicon-orange.png b/public/img/user-card/jobicon-orange.png
new file mode 100644
index 0000000..3c5da8e
Binary files /dev/null and b/public/img/user-card/jobicon-orange.png differ
diff --git a/public/img/user-card/user-card-blue.png b/public/img/user-card/user-card-blue.png
new file mode 100644
index 0000000..5a67581
Binary files /dev/null and b/public/img/user-card/user-card-blue.png differ
diff --git a/public/img/user-card/user-card-green.png b/public/img/user-card/user-card-green.png
new file mode 100644
index 0000000..13bae55
Binary files /dev/null and b/public/img/user-card/user-card-green.png differ
diff --git a/public/img/user-card/user-card-orange.png b/public/img/user-card/user-card-orange.png
new file mode 100644
index 0000000..d11807c
Binary files /dev/null and b/public/img/user-card/user-card-orange.png differ
diff --git a/public/img/user-card/绿色-虚线.png b/public/img/user-card/绿色-虚线.png
new file mode 100644
index 0000000..a8a0f01
Binary files /dev/null and b/public/img/user-card/绿色-虚线.png differ
diff --git a/src/components/dialog/index.jsx b/src/components/dialog/index.jsx
new file mode 100644
index 0000000..0199402
--- /dev/null
+++ b/src/components/dialog/index.jsx
@@ -0,0 +1,134 @@
+import React from 'react';
+import { TreeSelect, Modal, message } from 'antd';
+
+export default class OperateDialog extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ treeData: [],
+ open: false,
+ confirmLoading: false,
+ title: '',
+ operateType: '',
+ root: '',
+ type: 1,
+ };
+ }
+
+ componentDidMount() {}
+
+ handleOk = () => {
+ const { type } = this.state;
+ if (type === 1) {
+ this.props.addFolderNode();
+ } else {
+ this.props.deleteNode();
+ }
+ setTimeout(() => {
+ this.setState({ open: false });
+ message.success('操作成功');
+ }, 200);
+ // if (description.length == 0) {
+ // return message.error('请填写描述信息');
+ // }
+ // this.setState({ confirmLoading: true });
+ // let api =
+ // '/api/bs/hrmorganization/orgchart/versionRecord?fclass=' +
+ // requestData.fclass +
+ // '&description=' +
+ // description;
+ // fetch(api)
+ // .then((res) => res.json())
+ // .then((data) => {
+ // if (data.api_status) {
+ // this.setState({
+ // open: false,
+ // confirmLoading: false,
+ // description: '',
+ // });
+ // message.success('版本记录成功,请重新刷新页面', 2, 3);
+ // } else {
+ // message.error('版本记录失败,请联系相关人员处理数据', 2, 3);
+ // }
+ // });
+ };
+
+ /**
+ * 根节点树数据
+ * @param {} parentId
+ * @returns
+ */
+ getNodeTreeNode = (parentId) => {
+ this.setState({ confirmLoading: true });
+ fetch(`/api/bs/hrmorganization/orgchart/getSubCompanyTree`)
+ .then((res) => res.json())
+ .then((data) => {
+ if (data.api_status) {
+ let arr = [];
+ arr = [...this.state.treeData, ...data.companyTree];
+ this.setState({
+ treeData: arr,
+ confirmLoading: false,
+ });
+ }
+ });
+ };
+
+ /**
+ * 根节点树异步加载
+ * @param {} parentId
+ * @returns
+ */
+ onRootLoadData = (treeNode) =>
+ new Promise((resolve) => {
+ const { id } = treeNode.props;
+ setTimeout(() => {
+ let api = `/api/bs/hrmorganization/orgchart/getSubCompanyTree?subcompany=${id}`;
+ this.getNodeTreeNode(api);
+ resolve(undefined);
+ }, 500);
+ });
+
+ showOperate = (id, title, type) => {
+ this.setState({
+ open: true,
+ confirmLoading: true,
+ title: title,
+ type: type,
+ });
+ this.getNodeTreeNode(id);
+ };
+
+ onRootChange = (value) => {
+ this.setState({ root: value });
+ };
+
+ render() {
+ const { treeData, open, confirmLoading, title } = this.state;
+ return (
+ <>
+ this.setState({ open: false })}
+ >
+
+
+ >
+ );
+ }
+}
diff --git a/src/components/drawer/index.jsx b/src/components/drawer/index.jsx
new file mode 100644
index 0000000..789c545
--- /dev/null
+++ b/src/components/drawer/index.jsx
@@ -0,0 +1,405 @@
+import React from 'react';
+import {
+ Drawer,
+ Space,
+ Button,
+ Dropdown,
+ Menu,
+ Table,
+ Spin,
+ Checkbox,
+} from 'antd';
+import { OrgChartComponent } from '@/components/orgChart';
+import * as d3 from 'd3';
+import qs from 'qs';
+import { message } from 'antd';
+import jsPDF from 'jspdf';
+import ExportJsonExcel from 'js-export-excel';
+import './index.less';
+
+let addNodeChildFunc = null;
+let orgChart = null;
+let active = 'top';
+export default class DrawerComponents extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ open: false,
+ data: [],
+ detailType: 'chart',
+ params: {},
+ dataSource: [],
+ columns: [],
+ spinning: true,
+ showJob: true,
+ };
+ }
+
+ componentDidMount() {}
+
+ // 点击节点
+ onNodeClick(node) {}
+
+ onButtonClick(event, d) {
+ if (d.children) {
+ let idsList = [];
+ d.children.forEach((item) => {
+ if (item.data.hasChildren && !item._children) {
+ idsList.push(item.data.id);
+ }
+ });
+ if (idsList.length == 0) {
+ return;
+ }
+ }
+ }
+
+ // 获取部门图片
+ getDepartmentImage(fisvitual) {
+ return fisvitual == '0'
+ ? `./img/user-card/user-card.png`
+ : `./img/user-card/user-card-blue.png`;
+ }
+
+ //获取数据
+ getDeatilDatas(params, type = 'chart', showJob = '1') {
+ this.setState({ spinning: true });
+ d3.json(
+ '/api/bs/hrmorganization/orgchart/getDepartmentDetail?' +
+ qs.stringify({ detauleType: type, ...params, showJob }),
+ ).then((data) => {
+ //
+ if (type == 'chart') {
+ this.setState({ data: data.data, spinning: false });
+ } else {
+ this.setState({ dataSource: data.dataSource, columns: data.columns });
+ }
+ });
+ }
+
+ // ButtonContent渲染
+ buttonContentRender = ({ node, state }) => {
+ return `
+
+

+
+ `;
+ };
+
+ // 节点宽度渲染
+ nodeWidthRender = (d) => {
+ return 280;
+ };
+
+ nodeHeightRender = (d) => {
+ return 160;
+ };
+
+ // tool bar start
+ handleTopLayoutClick = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart &&
+ orgChart
+ .setCentered(orgChart.getChartState().root.id)
+ .layout('top')
+ .render();
+ active = 'top';
+ };
+
+ handleLeftLayoutClick = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart &&
+ orgChart
+ .layout('left')
+ .setCentered(orgChart.getChartState().root.id)
+ .render();
+ active = 'left';
+ };
+
+ handleZoomIn = (progressBtn) => {
+ if (progressBtn) {
+ let top = parseInt(progressBtn.current.style.top) - 10;
+ if (top >= 0) {
+ progressBtn.current.style.top = top + 'px';
+ } else {
+ return;
+ }
+ }
+ orgChart && orgChart.zoomIn();
+ };
+
+ handleZoomOut = (progressBtn) => {
+ if (progressBtn) {
+ let top = parseInt(progressBtn.current.style.top) + 10;
+ if (top <= 100) {
+ progressBtn.current.style.top = top + 'px';
+ } else {
+ return;
+ }
+ }
+ orgChart && orgChart.zoomOut();
+ };
+
+ downloadPdf = (chart) => {
+ chart.exportImg({
+ save: false,
+ full: true,
+ onLoad: (base64) => {
+ var pdf = new jsPDF();
+ var img = new Image();
+ img.src = base64;
+ img.onload = function () {
+ pdf.addImage(
+ img,
+ 'JPEG',
+ 5,
+ 5,
+ 595 / 3,
+ ((img.height / img.width) * 595) / 3,
+ );
+ pdf.save('chart.pdf');
+ };
+ },
+ });
+ };
+
+ handleExport = (e) => {
+ let type = e.key == '1' ? 'png' : e.key == '1' ? 'pdf' : 'excel';
+ if (type == 'png') {
+ orgChart && orgChart.exportImg({ full: true });
+ } else if (type == 'pdf') {
+ orgChart && this.downloadPdf(orgChart);
+ } else {
+ let { dataSource } = this.state;
+ var option = {};
+ let dataTable = [];
+ if (dataSource) {
+ for (let i in dataSource) {
+ if (dataSource) {
+ let obj = {
+ 序号: dataSource[i].id,
+ 工号: dataSource[i].workCode,
+ 姓名: dataSource[i].lastName,
+ 性别: dataSource[i].sex,
+ 部门: dataSource[i].departmentId,
+ 分部: dataSource[i].subcompanyid1,
+ 岗位: dataSource[i].jobTitle,
+ 手机号: dataSource[i].mobile,
+ };
+ dataTable.push(obj);
+ }
+ }
+ }
+ option.fileName = '组织信息';
+ option.datas = [
+ {
+ sheetData: dataTable,
+ sheetName: 'sheet',
+ sheetFilter: [
+ '序号',
+ '工号',
+ '姓名',
+ '性别',
+ '部门',
+ '分部',
+ '岗位',
+ '手机号',
+ ],
+ sheetHeader: [
+ '序号',
+ '工号',
+ '姓名',
+ '性别',
+ '部门',
+ '分部',
+ '岗位',
+ '手机号',
+ ],
+ },
+ ];
+ var toExcel = new ExportJsonExcel(option);
+ toExcel.saveExcel();
+ }
+ };
+
+ /**
+ * 节点渲染
+ */
+ nodeContentRender = (d, i, arr, state) => {
+ if (d.data.ftype == 2) {
+ return `
+
+
+
})
+
+
+

+

+
+
+
+ ${d.data.fname}
+
+
+ 负责人:${d.data.fleader}
+
+
+
+ 在岗: ${d.data.fonjob} 人
+
+
+
+
+
+
`;
+ } else if (d.data.ftype == 3) {
+ return `
+
+
+

+
+

+
+
${d.data.fname}
+
+ 在岗: ${d.data.fonjob} 人
+
+
+
+
`;
+ } else if (d.data.ftype == 4) {
+ return `
+
+
+

+
+
+

+

+
+
+
+
${
+ d.data.fname
+ }
+
+
+ 司龄: ${d.data.companyWorkYear} 年
+
+
+
+
`;
+ }
+ };
+
+ showDrawer = (params) => {
+ const showJob = params.fclass == '0' ? '1' : '0';
+ this.getDeatilDatas(params, 'chart', showJob);
+ this.setState({ open: true, params: params });
+ };
+
+ onClose = () => {
+ this.setState({ open: false, detailType: 'chart', showJob: true });
+ };
+
+ changeDetail = () => {
+ const { detailType, params } = this.state;
+ let type = detailType == 'chart' ? 'table' : 'chart';
+ const showJob = params.fclass == '0' ? '1' : '0';
+ this.setState({
+ detailType: type,
+ });
+ this.getDeatilDatas(params, type, showJob);
+ };
+
+ render() {
+ const {
+ params,
+ open,
+ data,
+ detailType,
+ dataSource,
+ columns,
+ spinning,
+ showJob,
+ } = this.state;
+ let arr = [];
+ if (detailType == 'chart') {
+ arr.push({ label: '导出图片', key: '1' });
+ //arr.push({ label: '导出PDF', key: '2' });
+ } else {
+ arr.push({ label: '导出表格', key: '3' });
+ }
+
+ const menu = ;
+
+ return (
+
+ {detailType == 'chart' && params && params.fclass == '0' && (
+ {
+ this.setState({
+ showJob: e.target.checked,
+ });
+
+ this.getDeatilDatas(
+ params,
+ detailType,
+ e.target.checked ? '1' : '0',
+ );
+ }}
+ >
+ 是否显示岗位
+
+ )}
+
+
+
+
+
+ }
+ >
+ {detailType == 'chart' ? (
+ data.length > 0 && (
+
+ (orgChart = chart)}
+ setClick={(click) => (addNodeChildFunc = click)}
+ onNodeClick={this.onNodeClick}
+ onButtonClick={this.onButtonClick}
+ data={data}
+ buttonContent={this.buttonContentRender}
+ nodeWidth={this.nodeWidthRender}
+ nodeHeight={this.nodeHeightRender}
+ nodeContent={this.nodeContentRender}
+ />
+
+ )
+ ) : (
+
+ )}
+
+ );
+ }
+}
diff --git a/src/components/drawer/index.less b/src/components/drawer/index.less
new file mode 100644
index 0000000..e2403ec
--- /dev/null
+++ b/src/components/drawer/index.less
@@ -0,0 +1,4 @@
+.dept-box:hover {
+ width: 500px;
+ text-align: left;
+}
diff --git a/src/components/timeline/index.jsx b/src/components/timeline/index.jsx
new file mode 100644
index 0000000..49f34e8
--- /dev/null
+++ b/src/components/timeline/index.jsx
@@ -0,0 +1,71 @@
+/*
+ * @Author: Chengliang 1546584672@qq.com
+ * @Date: 2023-06-25 16:33:21
+ * @LastEditors: Chengliang 1546584672@qq.com
+ * @LastEditTime: 2023-06-29 14:24:04
+ * @FilePath: /org-chart-frant/src/components/timeline/index.jsx
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+import React from 'react';
+import { Timeline } from 'antd';
+import styles from './index.less';
+
+export default class TimeLine extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ timelineList: [],
+ };
+ }
+
+ 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() {
+ this.searchTimeLines(this.props.url);
+ }
+
+ searchTimeLines(url) {
+ fetch(url)
+ .then((res) => res.json())
+ .then((data) => {
+ this.setState({
+ timelineList: data.timelineList,
+ });
+ });
+ }
+
+ render() {
+ return (
+
+
+ {this.state.timelineList.map((item) => {
+ return (
+
+ {item.title}
+ {item.time}
+
+ );
+ })}
+
+
+ );
+ }
+}
diff --git a/src/components/timeline/index.less b/src/components/timeline/index.less
new file mode 100644
index 0000000..55d216d
--- /dev/null
+++ b/src/components/timeline/index.less
@@ -0,0 +1,55 @@
+.lineWrapper {
+ width: 208px;
+ height: calc(~'100% - 200px');
+ overflow-y: scroll;
+ position: fixed;
+ left: 10px;
+ z-index: 100;
+ background: #fff;
+ border-radius: 20px;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ padding-left: 20px;
+
+ .timeline {
+ cursor: pointer;
+ }
+
+ .timeline :hover {
+ color: #1890ff;
+ }
+
+ .time {
+ 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;
+}
diff --git a/src/components/toolBar/img/compact.png b/src/components/toolBar/img/compact.png
new file mode 100644
index 0000000..5233876
Binary files /dev/null and b/src/components/toolBar/img/compact.png differ
diff --git a/src/components/toolBar/img/expandAll.png b/src/components/toolBar/img/expandAll.png
new file mode 100644
index 0000000..38eaea2
Binary files /dev/null and b/src/components/toolBar/img/expandAll.png differ
diff --git a/src/components/toolBar/img/fit.png b/src/components/toolBar/img/fit.png
new file mode 100644
index 0000000..cd8ee5b
Binary files /dev/null and b/src/components/toolBar/img/fit.png differ
diff --git a/src/components/toolBar/img/folder-add.png b/src/components/toolBar/img/folder-add.png
new file mode 100644
index 0000000..324aeb7
Binary files /dev/null and b/src/components/toolBar/img/folder-add.png differ
diff --git a/src/components/toolBar/img/folder-remove.png b/src/components/toolBar/img/folder-remove.png
new file mode 100644
index 0000000..ed16637
Binary files /dev/null and b/src/components/toolBar/img/folder-remove.png differ
diff --git a/src/components/toolBar/img/fullscreen.png b/src/components/toolBar/img/fullscreen.png
new file mode 100644
index 0000000..ee9d692
Binary files /dev/null and b/src/components/toolBar/img/fullscreen.png differ
diff --git a/src/components/toolBar/index.jsx b/src/components/toolBar/index.jsx
index 1cbe424..e540c7f 100644
--- a/src/components/toolBar/index.jsx
+++ b/src/components/toolBar/index.jsx
@@ -6,6 +6,12 @@ import top from './img/top.png';
import left from './img/left.png';
import topActive from './img/top_active.png';
import leftActive from './img/left_active.png';
+import fullscreen from './img/fullscreen.png';
+import fit from './img/fit.png';
+import compact from './img/compact.png';
+import expandAll from './img/expandAll.png';
+import deleteNode from './img/folder-remove.png';
+import folderAdd from './img/folder-add.png';
export default class ToolBar extends React.Component {
progressBtn = React.createRef();
@@ -97,6 +103,48 @@ export default class ToolBar extends React.Component {
this.props.onLeftLayoutClick(this.progressBtn);
}}
/>
+ {/*
{
+ this.props.onFolderAddNode(this.progressBtn);
+ }}
+ />
+
{
+ this.props.onDeleteNode(this.progressBtn);
+ }}
+ /> */}
+
{
+ this.props.onFullscreen(this.progressBtn);
+ }}
+ />
+
{
+ this.props.onFit(this.progressBtn);
+ }}
+ />
+
{
+ this.props.onCompact(this.progressBtn);
+ }}
+ />
+
{
+ this.props.onExpandAll(this.progressBtn);
+ }}
+ />
);
}
diff --git a/src/components/toolBar/index.less b/src/components/toolBar/index.less
index ffe10d8..305d10f 100644
--- a/src/components/toolBar/index.less
+++ b/src/components/toolBar/index.less
@@ -1,38 +1,39 @@
.toolbarWrapper {
- width: 68px;
- position: fixed;
- right: 10px;
- z-index: 100;
- background: #fff;
- border-radius: 20px;
- padding-top: 20px;
- padding-bottom: 20px;
- text-align: center;
- .progressWrapper {
- position: relative;
- padding-top: 5px;
- padding-bottom: 5px;
- margin-left: 20px;
- .progressLine {
- height: 100px;
- width: 0px;
- border-left: 2px solid #C9C9C9;
- margin-left: 12px;
- }
- .progressBtn {
- width: 16px;
- height: 9px;
- background-color: #C9C9C9;
- position: absolute;
- left: 5px;
- top: 0px;
- }
+ width: 68px;
+ position: fixed;
+ right: 10px;
+ z-index: 100;
+ background: #fff;
+ border-radius: 20px;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ text-align: center;
+ .progressWrapper {
+ position: relative;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ margin-left: 20px;
+ .progressLine {
+ height: 100px;
+ width: 0px;
+ border-left: 2px solid #c9c9c9;
+ margin-left: 12px;
}
- .toolBarItem {
- display: block;
- margin-top: 20px;
- margin-bottom: 20px;
- margin-left: 20px;
- cursor: pointer;
+ .progressBtn {
+ width: 16px;
+ height: 9px;
+ background-color: #c9c9c9;
+ position: absolute;
+ left: 5px;
+ top: 0px;
}
-}
\ No newline at end of file
+ }
+ .toolBarItem {
+ display: block;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ margin-left: 26px;
+ cursor: pointer;
+ width: 20px;
+ }
+}
diff --git a/src/components/topBar/index.jsx b/src/components/topBar/index.jsx
index 2bb1fe2..3ee4c2e 100644
--- a/src/components/topBar/index.jsx
+++ b/src/components/topBar/index.jsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { QuestionCircleOutlined } from '@ant-design/icons';
import style from './index.less';
import {
DatePicker,
@@ -9,8 +10,14 @@ import {
Col,
Dropdown,
Menu,
+ TreeSelect,
+ Tooltip,
+ Modal,
+ Input,
+ message,
} from 'antd';
const { Option } = Select;
+const { TextArea } = Input;
import moment from 'moment';
import 'moment/locale/zh-cn';
import locale from 'antd/lib/date-picker/locale/zh_CN';
@@ -21,26 +28,66 @@ 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',
- level: '3',
+ root: undefined,
+ level: '2',
fisvitual: '0',
},
+ open: false,
+ confirmLoading: false,
+ description: '',
};
}
+ /**
+ * 表单值改变
+ * @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");
- // }
+
+ onChange = (e) => {
+ this.setState({ description: e.target.value });
+ };
+
+ /**
+ * 弹窗确认
+ */
+ handleOk = () => {
+ const { description, requestData } = this.state;
+ if (description.length == 0) {
+ return message.error('请填写描述信息');
+ }
+ this.setState({ confirmLoading: true });
+ // setTimeout(() => {
+ // this.setState({ open: false, confirmLoading: false, description: '' });
+ // message.success('版本记录成功,请重新刷新页面');
+ // }, 2000);
+ let api =
+ '/api/bs/hrmorganization/orgchart/versionRecord?fclass=' +
+ requestData.fclass +
+ '&description=' +
+ description;
+ fetch(api)
+ .then((res) => res.json())
+ .then((data) => {
+ if (data.api_status) {
+ this.setState({
+ open: false,
+ confirmLoading: false,
+ description: '',
+ });
+ message.success('版本记录成功,请重新刷新页面', 2, 3);
+ } else {
+ message.error('版本记录失败,请联系相关人员处理数据', 2, 3);
+ }
+ });
+ };
handleExportMenuClick(e) {
this.props.onExport(e.key == '1' ? 'png' : 'pdf');
@@ -50,16 +97,74 @@ export class TopBar extends React.Component {
this.props.onExport('png');
}
+ /**
+ * 根节点树数据
+ * @param {} parentId
+ * @returns
+ */
+ getNodeTreeNode = (url, merge = true) => {
+ fetch(url)
+ .then((res) => res.json())
+ .then((data) => {
+ if (data.api_status) {
+ let arr = [];
+ if (merge) {
+ arr = [...this.state.rootTreeData, ...data.companyTree];
+ } else {
+ arr = [...data.companyTree];
+ }
+ this.setState({
+ rootTreeData: arr,
+ });
+ }
+ });
+ };
+
+ /**
+ * 根节点树异步加载
+ * @param {} parentId
+ * @returns
+ */
+ onRootLoadData = (treeNode) =>
+ new Promise((resolve) => {
+ const { id } = treeNode.props;
+ setTimeout(() => {
+ const { fclass } = this.state.requestData;
+ let api =
+ '/api/bs/hrmorganization/orgchart/getSubCompanyTree?subcompany=' +
+ id +
+ '&fclass=' +
+ fclass;
+ this.getNodeTreeNode(api);
+ resolve(undefined);
+ }, 500);
+ });
+
+ onRootChange = (value) => {
+ 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 = (
);
render() {
- const { disabled } = this.props;
+ const { disabled, type } = this.props;
+ const { rootTreeData, open, confirmLoading } = this.state;
return (
-
- 数据日期:
-
- this.handleFormChange({
- date: value && value != '' ? value.format('YYYY-MM-DD') : '',
- })
- }
- />
-
-
维度:
-
根节点:
-
-
-
-
- 显示层级:
-
+ dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+ placeholder="请选择根节点"
+ onChange={this.onRootChange}
+ loadData={this.onRootLoadData}
+ treeData={rootTreeData}
+ />
-
-
this.handleFormChange({
fisvitual: e.target.checked ? '1' : '0',
@@ -163,18 +243,44 @@ export class TopBar extends React.Component {
>
显示虚拟组织
+
+
+
+ 部门层级:
+
+
+
+
+
+
+
this.setState({ open: false })}
+ >
+
+ 提示:版本记录耗时较长,请谨慎操作(仅记录当前维度的数据版本)
+
+ 主题:
+
+
);
}
diff --git a/src/d3-org-chart.js b/src/d3-org-chart.js
index ba08742..13ddc87 100644
--- a/src/d3-org-chart.js
+++ b/src/d3-org-chart.js
@@ -480,7 +480,6 @@ export class OrgChart {
//InnerFunctions which will update visuals
const attrs = this.getChartState();
if (!attrs.data || attrs.data.length == 0) {
- console.log('ORG CHART - Data is empty');
return this;
}
@@ -637,19 +636,9 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj),
)[0];
if (nodeFound) {
- console.log(
- `ORG CHART - ADD - Node with id "${attrs.nodeId(
- obj,
- )}" already exists in tree`,
- );
return this;
}
if (!parentFound) {
- console.log(
- `ORG CHART - ADD - Parent node with id "${attrs.parentNodeId(
- obj,
- )}" not found in the tree`,
- );
return this;
}
if (obj._centered && !obj._expanded) obj._expanded = true;
@@ -670,19 +659,9 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) === attrs.parentNodeId(obj),
)[0];
if (nodeFound) {
- console.log(
- `ORG CHART - ADD - Node with id "${attrs.nodeId(
- obj,
- )}" already exists in tree`,
- );
return this;
}
if (!parentFound) {
- console.log(
- `ORG CHART - ADD - Parent node with id "${attrs.parentNodeId(
- obj,
- )}" not found in the tree`,
- );
return this;
}
obj._expanded = true;
@@ -701,9 +680,6 @@ export class OrgChart {
({ data }) => attrs.nodeId(data) == nodeId,
)[0];
if (!node) {
- console.log(
- `ORG CHART - REMOVE - Node with id "${nodeId}" not found in the tree`,
- );
return this;
}
@@ -1100,7 +1076,8 @@ export class OrgChart {
) {
return;
}
- attrs.onNodeClick(attrs.nodeId(data));
+ //attrs.onNodeClick(attrs.nodeId(data));
+ attrs.onNodeClick(data);
});
// Add background rectangle for the nodes
@@ -1298,7 +1275,6 @@ export class OrgChart {
// } else {
// this.fit();
// }
- console.log(44444, centeredNodes);
this.fit({
animate: true,
scale: false,
@@ -1622,7 +1598,6 @@ export class OrgChart {
const attrs = this.getChartState();
const { root } = attrs;
let descendants = nodes ? nodes : root.descendants();
- console.log(11111111111, nodes, descendants, scale);
const minX = d3.min(
descendants,
(d) => d.x + attrs.layoutBindings[attrs.layout].nodeLeftX(d),
@@ -1639,7 +1614,6 @@ export class OrgChart {
descendants,
(d) => d.y + attrs.layoutBindings[attrs.layout].nodeBottomY(d),
);
- console.log('333,minY', minX, maxX, minY, maxY);
this.zoomTreeBounds({
params: { animate: animate, scale },
x0: transform == 'export' ? minX - 700 : minX - 50,
@@ -1659,11 +1633,6 @@ export class OrgChart {
)[0];
if (!node) {
- console.log(
- `ORG CHART - ${
- expandedFlag ? 'EXPAND' : 'COLLAPSE'
- } - Node with id (${id}) not found in the tree`,
- );
return this;
}
node.data._expanded = expandedFlag;
@@ -1677,9 +1646,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId,
)[0];
if (!node) {
- console.log(
- `ORG CHART - CENTER - Node with id (${nodeId}) not found in the tree`,
- );
return this;
}
node.data._centered = true;
@@ -1693,9 +1659,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId,
)[0];
if (!node) {
- console.log(
- `ORG CHART - HIGHLIGHT - Node with id (${nodeId}) not found in the tree`,
- );
return this;
}
node.data._highlighted = true;
@@ -1710,9 +1673,6 @@ export class OrgChart {
(d) => attrs.nodeId(d.data) === nodeId,
)[0];
if (!node) {
- console.log(
- `ORG CHART - HIGHLIGHTROOT - Node with id (${nodeId}) not found in the tree`,
- );
return this;
}
node.data._upToTheRootHighlighted = true;
diff --git a/src/pages/company.jsx b/src/pages/company.jsx
index df2f2b0..c3778f4 100644
--- a/src/pages/company.jsx
+++ b/src/pages/company.jsx
@@ -1,32 +1,55 @@
import styles from './index.less';
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useRef } from 'react';
import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3';
import { TopBar } from '../components/topBar';
import ToolBar from '../components/toolBar';
+import TimeLine from '../components/timeline';
+import DrawerComponents from '../components/drawer';
+import OperateDialog from '../components/dialog';
import jsPDF from 'jspdf';
import moment from 'moment';
import qs from 'qs';
-import { message } from 'antd';
+import { message, Spin } from 'antd';
let active = 'top';
+let drawerCom = null;
+let operateCom = null;
+let timeLine = null;
+let orgChart = null;
+let topbar = null;
+
export default function companyPage() {
const [data, setData] = useState(null);
+ let compact = 0;
+ let expandAll = 0;
+
const [sliderProgress, setSliderProgress] = useState(50);
let addNodeChildFunc = null;
- let orgChart = null;
-
let topBarSearchRequest = null;
const [hasRight, setHasRight] = useState('');
- const [disabled, setDisabled] = useState(false);
+ const [timelineId, setTimelineId] = useState(0);
+ const infoRef = useRef();
+
+ useEffect(() => {
+ infoRef.current = timelineId;
+ }, [timelineId]);
+ const [spinning, setSpinning] = useState(false);
// 点击节点
- function onNodeClick(nodeId) {
- // alert('clicked ' + nodeId);
- }
+ const onNodeClick = (node) => {
+ if (node.ftype == '2') {
+ const params = {
+ rootId: node.id,
+ fclass: topbar.state.requestData.fclass,
+ id: infoRef.current,
+ };
+ drawerCom.showDrawer(params);
+ }
+ };
// 扩展按钮点击
- function onButtonClick(event, d) {
+ const onButtonClick = (event, d) => {
if (d.children) {
let idsList = [];
d.children.forEach((item) => {
@@ -40,9 +63,6 @@ export default function companyPage() {
}
let idsStr = idsList.join(',');
-
- console.log('idsStr', idsStr);
-
let api = '';
if (topBarSearchRequest) {
let request = { ...topBarSearchRequest, ids: idsStr };
@@ -51,44 +71,36 @@ export default function companyPage() {
qs.stringify(request, { addQueryPrefix: true });
} else {
api =
- '/api/bs/hrmorganization/orgchart/asyncCompanyData?fclass=0&root=0&date=' +
- moment(new Date()).format('YYYY-MM-DD') +
- '&ids=' +
+ '/api/bs/hrmorganization/orgchart/asyncCompanyData?fclass=0&fisvitual=0&id=0&root=0&ids=' +
idsStr;
}
-
fetch(api)
.then((res) => res.json())
.then((data) => {
if (data.data) {
data.data.forEach((item) => {
- window.chart.addNode(item);
+ // window.chart.addNode(item);
+ orgChart.addNode(item);
});
}
});
}
- }
+ };
// 获取部门图片
- function getDepartmentImage() {
- let index = Math.floor(Math.random() * 8) + 1;
- // return `./img/department/${index}.png`;
- return `./img/department/1.png`;
+ function getDepartmentImage(fisvitual) {
+ return fisvitual == '0' ? `./img/back/level4.png` : `./img/back/level8.png`;
}
- // 获取部门图片
- function getSubcompanyImage() {
- let index = Math.floor(Math.random() * 3) + 1;
- // return `./img/subcompany/${index}.png`;
- return `./img/subcompany/2.png`;
+ // 获取分部图片
+ function getSubcompanyImage(fisvitual) {
+ return fisvitual == '0' ? `./img/back/level1.png` : `./img/back/level5.png`;
}
// 获取数据
useEffect(() => {
d3.json(
- // "/company/data"
- '/api/bs/hrmorganization/orgchart/companyData?fclass=0&isvitual=0&root=0&date=' +
- moment(new Date()).format('YYYY-MM-DD'),
+ '/api/bs/hrmorganization/orgchart/companyData?fclass=0&fisvitual=0&root=0&level=2&id=0',
).then((data) => {
setData(data.data);
setHasRight(data?.hasRight);
@@ -120,24 +132,16 @@ export default function companyPage() {
if (d.data.ftype == 0) {
return 100;
} else if (d.data.ftype == 1) {
- return 160;
+ return 106;
} else if (d.data.ftype == 2) {
- return 56;
+ return 106;
}
return 120;
};
const nodeContentRender = (d, i, arr, state) => {
- // 集团地址
- let companyUrl =
- '/spa/organization/static/index.html#/main/organization/group';
- // 分部地址
- let subcompanyUrl = `/spa/organization/static/index.html#/main/organization/companyExtend/${d.data.fobjid}`;
- // 部门地址
- let departmentUrl = `/spa/organization/static/index.html#/main/organization/departmentExtend/${d.data.fobjid}`;
-
if (d.data.ftype == 0) {
- return `
+ return `
@@ -154,39 +158,30 @@ export default function companyPage() {
`;
} else if (d.data.ftype == 1) {
- return `
-
-
})
-
-
- ${d.data.fname}
+ return `
+
-
`;
+
`;
} else if (d.data.ftype == 2) {
return `
-
-
-

-
-
})
-
${d.data.fname}
+
+
+
})
+
+
`;
@@ -194,7 +189,6 @@ export default function companyPage() {
return `
${d.data.fname}
`;
};
- // tool bar start
const handleTopLayoutClick = (progressBtn) => {
progressBtn.current.style.top = 50 + 'px';
orgChart &&
@@ -215,6 +209,56 @@ export default function companyPage() {
active = 'left';
};
+ const handleFullscreen = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart && orgChart.fullscreen('body');
+ };
+
+ const handleFit = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart && orgChart.fit();
+ };
+
+ const handleFolderAddNode = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ operateCom &&
+ operateCom.showOperate(topbar.state.requestData.root, '新增节点', 1);
+ };
+
+ const addFolderNode = (id) => {
+ orgChart &&
+ orgChart.addNode({
+ id: 'd_10091',
+ fname: '测试增加节点',
+ parentId: 's_10',
+ ftype: '2',
+ });
+ };
+
+ const handleDeleteNode = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ operateCom &&
+ operateCom.showOperate(topbar.state.requestData.root, '删除节点', 2);
+ };
+
+ const deleteNode = (id) => {
+ orgChart && orgChart.removeNode('d_10091');
+ };
+
+ const handleCompact = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart &&
+ orgChart
+ .compact(!!(compact++ % 2))
+ .render()
+ .fit();
+ };
+
+ const handleExpandAll = (progressBtn) => {
+ progressBtn.current.style.top = 50 + 'px';
+ orgChart && expandAll++ % 2 ? orgChart.collapseAll() : orgChart.expandAll();
+ };
+
const handleZoomIn = (progressBtn) => {
if (progressBtn) {
let top = parseInt(progressBtn.current.style.top) - 10;
@@ -243,10 +287,6 @@ export default function companyPage() {
orgChart && orgChart.zoomBehavior(value - 50);
};
- // tool bar end
-
- // top bar start
-
function downloadPdf(chart) {
chart.exportImg({
save: false,
@@ -270,6 +310,10 @@ export default function companyPage() {
});
}
+ /**
+ * 导出
+ * @param {*} type
+ */
const handleExport = (type) => {
if (type == 'png') {
orgChart && orgChart.exportImg({ full: true });
@@ -278,7 +322,32 @@ export default function companyPage() {
}
};
- const handleSearch = (requestData) => {
+ /**
+ * 时间轴点击
+ * @param {*} timeline
+ */
+ const timeLineSearch = (timeline) => {
+ setTimelineId(timeline.id);
+ const fclass = topbar.state.requestData.fclass;
+ const resetParams = { root: undefined, level: '2', fisvitual: '0' };
+ topbar.handleFormChange({ ...resetParams });
+ topbar.getNodeTreeNode(
+ `/api/bs/hrmorganization/orgchart/getSubCompanyTree?fclass=${fclass}&id=${timeline.id}`,
+ false,
+ );
+ let requestData = { fclass: fclass, id: timeline.id, ...resetParams };
+ handleSearch(requestData, false);
+ };
+
+ /**
+ * 查询
+ * @param {*} requestData
+ */
+ const handleSearch = (requestData, cache = true) => {
+ setSpinning(true);
+ if (cache) {
+ requestData = { ...requestData, id: infoRef.current };
+ }
topBarSearchRequest = requestData;
let api =
'/api/bs/hrmorganization/orgchart/companyData' +
@@ -294,27 +363,26 @@ export default function companyPage() {
setData(data?.data);
}
}
+ setTimeout(function () {
+ setSpinning(false);
+ }, 200);
});
};
- const handleSynchronous = (requestData) => {
- setDisabled(true);
- let api = '/api/bs/hrmorganization/orgchart/synchronousData';
- fetch(api)
- .then((res) => res.json())
- .then((data) => {
- if (data.code == 200) {
- message.success('同步成功,请重新查询');
- } else {
- message.error('数据同步失败');
- }
- setDisabled(false);
- //this.handleSearch(requestData);
- });
+ /**
+ * 切换维度
+ * @param {*} requestData
+ */
+ const handleChange = (requestData) => {
+ setTimelineId(0);
+ timeLine.searchTimeLines(
+ `/api/bs/hrmorganization/orgchart/timeLines?fclass=${requestData.fclass}`,
+ );
+ requestData = { ...requestData, id: 0 };
+ handleSearch(requestData, false);
};
useEffect(() => {
- console.log('data', data);
if (active == 'left') {
orgChart &&
orgChart
@@ -329,9 +397,8 @@ export default function companyPage() {
.render();
}
}, [data]);
- // top bar end
+
if (hasRight === false) {
- //return message.error("对不起,您暂时没有权限", 2);
return (
(topbar = r)}
onExport={(type) => {
handleExport(type);
}}
onSearch={(requestData) => {
handleSearch(requestData);
}}
- onSynchronous={(requestData) => {
- handleSynchronous(requestData);
+ changeFclass={(requestData) => {
+ handleChange(requestData);
}}
- disabled={disabled}
type="company"
- url="/api/bs/hrmorganization/orgchart/getCondition?type=company"
+ url="/api/bs/hrmorganization/orgchart/getCondition?fclass=0&type=company"
/>
handleTopLayoutClick(progressBtn)}
onLeftLayoutClick={(progressBtn) =>
handleLeftLayoutClick(progressBtn)
}
+ onFullscreen={(progressBtn) => handleFullscreen(progressBtn)}
+ onFit={(progressBtn) => handleFit(progressBtn)}
+ onFolderAddNode={(progressBtn) => handleFolderAddNode(progressBtn)}
+ onDeleteNode={(progressBtn) => handleDeleteNode(progressBtn)}
+ onCompact={(progressBtn) => handleCompact(progressBtn)}
+ onExpandAll={(progressBtn) => handleExpandAll(progressBtn)}
onZoomOut={(progressBtn) => handleZoomOut(progressBtn)}
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
onZoomBehavior={(value) => handleZoomBehavior(value)}
/>
- (orgChart = chart)}
- setClick={(click) => (addNodeChildFunc = click)}
- onNodeClick={onNodeClick}
- data={data}
- onButtonClick={onButtonClick}
- buttonContent={buttonContentRender}
- nodeWidth={nodeWidthRender}
- nodeHeight={nodeHeightRender}
- nodeContent={nodeContentRender}
+ (timeLine = r)}
+ onClick={(timeline) => {
+ timeLineSearch(timeline);
+ }}
+ url={'/api/bs/hrmorganization/orgchart/timeLines?fclass=0'}
+ />
+
+ (orgChart = chart)}
+ setClick={(click) => (addNodeChildFunc = click)}
+ onNodeClick={onNodeClick}
+ data={data}
+ onButtonClick={onButtonClick}
+ buttonContent={buttonContentRender}
+ nodeWidth={nodeWidthRender}
+ nodeHeight={nodeHeightRender}
+ nodeContent={nodeContentRender}
+ />
+
+ (drawerCom = r)} />
+ (operateCom = r)}
+ addFolderNode={addFolderNode}
+ deleteNode={deleteNode}
/>
)
diff --git a/src/pages/index.less b/src/pages/index.less
index 0186693..04f4d5d 100644
--- a/src/pages/index.less
+++ b/src/pages/index.less
@@ -3,9 +3,9 @@
}
.wrapper {
- background: #F7F9FD;
+ background: #f7f9fd;
}
.contentWrapper {
- background-color: #F7F9FD;
-}
\ No newline at end of file
+ background-color: #f7f9fd;
+}
diff --git a/src/pages/user.jsx b/src/pages/user.jsx
index eea1a5e..200e89d 100644
--- a/src/pages/user.jsx
+++ b/src/pages/user.jsx
@@ -4,6 +4,7 @@ import { OrgChartComponent } from '@/components/orgChart';
import * as d3 from 'd3';
import { TopBar } from '../components/topBar';
import ToolBar from '../components/toolBar';
+import TimeLine from '../components/timeline';
import moment from 'moment';
import qs from 'qs';
import { message } from 'antd';
@@ -11,6 +12,8 @@ import jsPDF from 'jspdf';
let active = 'top';
export default function userPage() {
const [data, setData] = useState(null);
+ let topbar = null;
+ let timeLine = null;
const [topBarSearchRequest, setTpBarSearchRequest] = useState(null);
const [requestRes, setRequestRes] = useState({
date: moment(new Date()).format('YYYY-MM-DD'),
@@ -25,7 +28,7 @@ export default function userPage() {
let progressBtnRef = null;
const [hasRight, setHasRight] = useState('');
- const [disabled, setDisabled] = useState(false);
+ const [id, setId] = useState(0);
// 点击节点
function onNodeClick(nodeId) {
// alert('clicked ' + nodeId);
@@ -54,8 +57,7 @@ export default function userPage() {
qs.stringify(request, { addQueryPrefix: true });
} else {
api =
- '/api/bs/hrmorganization/orgchart/asyncUserData?fclass=0&root=0&date=' +
- moment(new Date()).format('YYYY-MM-DD') +
+ '/api/bs/hrmorganization/orgchart/asyncUserData?fclass=0&fisvitual=0&root=0&level=3&id=0' +
'&ids=' +
idsStr;
}
@@ -72,13 +74,23 @@ export default function userPage() {
}
}
+ /**
+ * 时间轴点击
+ * @param {*} timeline
+ */
+ const timeLineSearch = (timeline) => {
+ setId(timeline.id);
+ let requestData = { ...topbar.state.requestData, id: timeline.id };
+ handleSearch(requestData, false);
+ };
+
// 获取部门图片
function getDepartmentImage() {
let index = Math.floor(Math.random() * 8) + 1;
return `./img/department/${index}.png`;
}
- // 获取部门图片
+ // 获取分部图片
function getSubcompanyImage() {
let index = Math.floor(Math.random() * 3) + 1;
return `./img/subcompany/${index}.png`;
@@ -87,11 +99,10 @@ export default function userPage() {
// 获取数据
useEffect(() => {
document.cookie =
- 'Webstorm-3d4d3ad4=b8ca5bef-a131-4c2b-81da-6f8595481dc2; ecology_JSessionid=aaad2HRSW843U9BJFcUuy; JSESSIONID=aaad2HRSW843U9BJFcUuy; loginidweaver=1; languageidweaver=7; loginuuids=1; __randcode__=47f1e1cc-51de-48b3-af04-3875b717805f';
+ 'ecology_JSessionid=aaauntrtgZdkuanT5w2Ly; JSESSIONID=aaauntrtgZdkuanT5w2Ly; loginidweaver=1; languageidweaver=7; loginuuids=1; __randcode__=c5235342-7633-4eec-a754-b36eefdf8c9e';
d3.json(
// "/user/data"
- '/api/bs/hrmorganization/orgchart/userData?fclass=0&root=0&date=' +
- moment(new Date()).format('YYYY-MM-DD'),
+ '/api/bs/hrmorganization/orgchart/userData?fclass=0&fisvitual=0&root=0&level=3&id=0',
).then((data) => {
setData(data.data);
setHasRight(data?.hasRight);
@@ -161,10 +172,6 @@ export default function userPage() {
orgChart && orgChart.zoomOut();
};
- // tool bar end
-
- // top bar start
-
function downloadPdf(chart) {
chart.exportImg({
save: false,
@@ -196,7 +203,10 @@ export default function userPage() {
}
};
- const handleSearch = (requestData) => {
+ const handleSearch = (requestData, cache = true) => {
+ if (cache) {
+ requestData = { ...requestData, id: id };
+ }
setTpBarSearchRequest(requestData);
let api =
'/api/bs/hrmorganization/orgchart/userData' +
@@ -215,20 +225,15 @@ export default function userPage() {
});
};
- const handleSynchronous = (requestData) => {
- setDisabled(true);
- let api = '/api/bs/hrmorganization/orgchart/synchronousData';
- fetch(api)
- .then((res) => res.json())
- .then((data) => {
- if (data.code == 200) {
- message.success('同步成功,请重新查询');
- } else {
- message.error('数据同步失败');
- }
- setDisabled(false);
- //this.handleSearch(requestData);
- });
+ /**
+ * 切换维度
+ * @param {*} requestData
+ */
+ const handleChange = (requestData) => {
+ timeLine.searchTimeLines(
+ `/api/bs/hrmorganization/orgchart/timeLines?fclass=${requestData.fclass}`,
+ );
+ handleSearch(requestData);
};
useEffect(() => {
@@ -309,7 +314,7 @@ export default function userPage() {
? d.data.fleaderimg
: d.data.ftype == 0 || d.data.ftype == 1
? './img/company.png'
- : './img/default_avator.png'
+ : './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"/>
@@ -506,6 +511,7 @@ export default function userPage() {
hasRight && (
(topbar = r)}
onExport={(type) => {
handleExport(type);
}}
@@ -513,12 +519,11 @@ export default function userPage() {
setRequestRes(requestData);
handleSearch(requestData);
}}
- onSynchronous={(requestData) => {
- handleSynchronous(requestData);
+ changeFclass={(requestData) => {
+ handleChange(requestData);
}}
- disabled={disabled}
type="user"
- url="/api/bs/hrmorganization/orgchart/getCondition?type=user"
+ url="/api/bs/hrmorganization/orgchart/getCondition?fclass=0&type=user"
/>
handleZoomOut(progressBtn)}
onZoomIn={(progressBtn) => handleZoomIn(progressBtn)}
/>
+ (timeLine = r)}
+ onClick={(timeline) => {
+ timeLineSearch(timeline);
+ }}
+ url={'/api/bs/hrmorganization/orgchart/timeLines?fclass=0'}
+ />
(orgChart = chart)}
setClick={(click) => (addNodeChildFunc = click)}