组织结构图v1.0
@ -0,0 +1,16 @@
|
|||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
@ -0,0 +1,20 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/npm-debug.log*
|
||||||
|
/yarn-error.log
|
||||||
|
/yarn.lock
|
||||||
|
/package-lock.json
|
||||||
|
|
||||||
|
# production
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# umi
|
||||||
|
/src/.umi
|
||||||
|
/src/.umi-production
|
||||||
|
/src/.umi-test
|
||||||
|
/.env.local
|
@ -0,0 +1,8 @@
|
|||||||
|
**/*.md
|
||||||
|
**/*.svg
|
||||||
|
**/*.ejs
|
||||||
|
**/*.html
|
||||||
|
package.json
|
||||||
|
.umi
|
||||||
|
.umi-production
|
||||||
|
.umi-test
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 80,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ".prettierrc",
|
||||||
|
"options": { "parser": "json" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { defineConfig } from 'umi';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
hash: true,
|
||||||
|
history: { type: 'hash'},
|
||||||
|
base: "/spa/orgChart/",
|
||||||
|
// exportStatic: {},
|
||||||
|
publicPath: './',
|
||||||
|
nodeModulesTransform: {
|
||||||
|
type: 'none',
|
||||||
|
},
|
||||||
|
routes: [
|
||||||
|
{ path: '/user', component: '@/pages/user' },
|
||||||
|
{ path: '/company', component: '@/pages/company' }
|
||||||
|
],
|
||||||
|
fastRefresh: {},
|
||||||
|
antd: {},
|
||||||
|
proxy: {
|
||||||
|
"/api": { // 标识需要进行转换的请求的url
|
||||||
|
"target": "http://localhost:18089/api", // 服务端域名
|
||||||
|
"changeOrigin": true, // 允许域名进行转换
|
||||||
|
"pathRewrite": { "^/api": ''} // 将请求url里的ci去掉
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,15 @@
|
|||||||
|
# umi project
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
Install dependencies,
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
Start the dev server,
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ yarn start
|
||||||
|
```
|
@ -0,0 +1,158 @@
|
|||||||
|
export default {
|
||||||
|
'GET /company/data': [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"fname": "集团公司",
|
||||||
|
"ftype": 0,
|
||||||
|
"parentId": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"fname": "HRSSC共享服务中心",
|
||||||
|
"ftype": 1,
|
||||||
|
"parentId": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"fname": "事业部A",
|
||||||
|
"ftype": 1,
|
||||||
|
"parentId": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"fname": "苏州分公司",
|
||||||
|
"ftype": 1,
|
||||||
|
"parentId": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"fname": "人力资源部经理",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"fname": "招聘组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"fname": "薪酬核算组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"fname": "人事服务组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"fname": "培训组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"fname": "员工关系组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"fname": "服务管理组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"fname": "信息与数据组",
|
||||||
|
"ftype": 2,
|
||||||
|
"parentId": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'GET /user/data': [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"parentId": null,
|
||||||
|
"ftype": 0,
|
||||||
|
"fname": "维森集团",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "董事长",
|
||||||
|
"fplan": 1000,
|
||||||
|
"fonjob": 987
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"parentId": 1,
|
||||||
|
"ftype": 1,
|
||||||
|
"fname": "南京分公司",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "总经理",
|
||||||
|
"fplan": 300,
|
||||||
|
"fonjob": 287
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"parentId": 1,
|
||||||
|
"ftype": 1,
|
||||||
|
"fname": "南京分公司",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "总经理",
|
||||||
|
"fplan": 300,
|
||||||
|
"fonjob": 287
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"parentId": 1,
|
||||||
|
"ftype": 1,
|
||||||
|
"fname": "南京分公司",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "总经理",
|
||||||
|
"fplan": 300,
|
||||||
|
"fonjob": 287
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"parentId": 2,
|
||||||
|
"ftype": 2,
|
||||||
|
"fname": "销售部",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "部长",
|
||||||
|
"fplan": 200,
|
||||||
|
"fonjob": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"parentId": 5,
|
||||||
|
"ftype": 3,
|
||||||
|
"fname": "销售",
|
||||||
|
"fleadername": null,
|
||||||
|
"fleaderimg": null,
|
||||||
|
"fleaderjob": null,
|
||||||
|
"fplan": 200,
|
||||||
|
"fonjob": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"parentId": 6,
|
||||||
|
"ftype": 4,
|
||||||
|
"fname": "杨文元",
|
||||||
|
"fleadername": "杨文元",
|
||||||
|
"department": "销售部",
|
||||||
|
"fleaderimg": "./img/avator.png",
|
||||||
|
"fleaderjob": "销售",
|
||||||
|
"mobile": "13989058743",
|
||||||
|
"address": "秦淮区新街口12-201",
|
||||||
|
"fplan": 200,
|
||||||
|
"fonjob": 200
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "umi dev",
|
||||||
|
"build": "umi build",
|
||||||
|
"postinstall": "umi generate tmp",
|
||||||
|
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||||
|
"test": "umi-test",
|
||||||
|
"test:coverage": "umi-test --coverage"
|
||||||
|
},
|
||||||
|
"gitHooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,jsx,less,md,json}": [
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.ts?(x)": [
|
||||||
|
"prettier --parser=typescript --write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ant-design/pro-layout": "^6.5.0",
|
||||||
|
"@types/d3": "^7.4.0",
|
||||||
|
"d3": "7.4.4",
|
||||||
|
"d3-org-chart": "2.6.0",
|
||||||
|
"jspdf": "^2.5.1",
|
||||||
|
"moment": "^2.29.3",
|
||||||
|
"qs": "^6.11.0",
|
||||||
|
"react": "17.x",
|
||||||
|
"react-dom": "17.x",
|
||||||
|
"umi": "^3.5.26"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^17.0.0",
|
||||||
|
"@types/react-dom": "^17.0.0",
|
||||||
|
"@umijs/preset-react": "1.x",
|
||||||
|
"@umijs/test": "^3.5.26",
|
||||||
|
"lint-staged": "^10.0.7",
|
||||||
|
"prettier": "^2.2.0",
|
||||||
|
"typescript": "^4.1.2",
|
||||||
|
"yorkie": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 238 B |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 978 B |
After Width: | Height: | Size: 981 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 997 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 945 B |
After Width: | Height: | Size: 978 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 140 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 233 B |
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,58 @@
|
|||||||
|
import React, { useLayoutEffect, useRef, useEffect } from 'react';
|
||||||
|
import { OrgChart } from 'd3-org-chart';
|
||||||
|
import * as d3 from 'd3';
|
||||||
|
|
||||||
|
export const OrgChartComponent = (props, ref) => {
|
||||||
|
const d3Container = useRef(null);
|
||||||
|
let chart = null;
|
||||||
|
|
||||||
|
function addNode(node) {
|
||||||
|
chart.addNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
props.setClick(addNode);
|
||||||
|
|
||||||
|
|
||||||
|
// We need to manipulate DOM
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (props.data && d3Container.current) {
|
||||||
|
if (!chart) {
|
||||||
|
chart = new OrgChart();
|
||||||
|
}
|
||||||
|
props.setChart(chart)
|
||||||
|
try {
|
||||||
|
chart
|
||||||
|
.container(d3Container.current)
|
||||||
|
.data(props.data)
|
||||||
|
.nodeWidth(props.nodeWidth)
|
||||||
|
.nodeHeight(props.nodeHeight)
|
||||||
|
.layout("left")
|
||||||
|
|
||||||
|
.linkUpdate(function(d, i, arr) {
|
||||||
|
d3.select(this)
|
||||||
|
.attr("stroke", "#66BAF5")
|
||||||
|
.attr("stroke-width", 1)
|
||||||
|
.style("stroke-dasharray", ("3, 3"))
|
||||||
|
})
|
||||||
|
.onNodeClick((d, i, arr) => {
|
||||||
|
console.log(d, 'Id of clicked node ');
|
||||||
|
props.onNodeClick(d);
|
||||||
|
})
|
||||||
|
.buttonContent(props.buttonContent)
|
||||||
|
.nodeContent(props.nodeContent)
|
||||||
|
.render();
|
||||||
|
|
||||||
|
chart.expandAll()
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [props.data, d3Container.current]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div ref={d3Container} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
After Width: | Height: | Size: 798 B |
After Width: | Height: | Size: 744 B |
After Width: | Height: | Size: 643 B |
After Width: | Height: | Size: 438 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 515 B |
@ -0,0 +1,38 @@
|
|||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toolBarItem {
|
||||||
|
display: block;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
.topbarWrapper {
|
||||||
|
margin: 20px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
// background: red;
|
||||||
|
padding: 20px 26px 20px 26px;
|
||||||
|
box-shadow: 0px 5px 5px #e2e2e2;
|
||||||
|
border-radius: 0px 0px 0px 0px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return <div>Hello</div>
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
.title {
|
||||||
|
background: rgb(121, 242, 157);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
background: #F7F9FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contentWrapper {
|
||||||
|
background-color: #F7F9FD;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
import styles from './index.less';
|
||||||
|
|
||||||
|
export default function IndexPage() {
|
||||||
|
return (
|
||||||
|
<div className={styles.wrapper}>
|
||||||
|
<h1 className={styles.title}>Page index</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"importHelpers": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"baseUrl": "./",
|
||||||
|
"strict": true,
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"],
|
||||||
|
"@@/*": ["src/.umi/*"]
|
||||||
|
},
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"mock/**/*",
|
||||||
|
"src/**/*",
|
||||||
|
"config/**/*",
|
||||||
|
".umirc.ts",
|
||||||
|
"typings.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"lib",
|
||||||
|
"es",
|
||||||
|
"dist",
|
||||||
|
"typings",
|
||||||
|
"**/__test__",
|
||||||
|
"test",
|
||||||
|
"docs",
|
||||||
|
"tests"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
declare module '*.css';
|
||||||
|
declare module '*.less';
|
||||||
|
declare module '*.png';
|
||||||
|
declare module '*.svg' {
|
||||||
|
export function ReactComponent(
|
||||||
|
props: React.SVGProps<SVGSVGElement>,
|
||||||
|
): React.ReactElement;
|
||||||
|
const url: string;
|
||||||
|
export default url;
|
||||||
|
}
|