From fa71559c92ce8f7429971370ca4bd1139c903621 Mon Sep 17 00:00:00 2001
From: Mr Ke <kelq@hugeinfo.com.cn>
Date: Wed, 27 May 2020 11:16:05 +0800
Subject: [PATCH] oa+用户中心

---
 src/components/oa/index/rulesList/index.jsx       |    0 
 src/module/login/login.jsx                        |   20 
 src/components/common/HeadView/index.scss         |   11 
 src/module/oa/logManage/operLog.jsx               |    2 
 src/module/huge-base/FunctionManage.jsx           |  327 +++
 src/components/common/TopListTableView/tagList.js |  100 
 src/components/oa/DocumentDetailPage/index.jsx    |    0 
 src/components/oa/personal/information/index.jsx  |    0 
 src/components/oa/personal/information/index.scss |    0 
 src/components/oa/DocumentEditPage/index.jsx      |    0 
 src/module/huge-base/JobDetail.jsx                |  122 +
 src/components/oa/DocumentDetailPage/index.scss   |    0 
 src/components/oa/logManage/Rawler/index.jsx      |    0 
 src/module/huge-base/Menu.jsx                     |   51 
 src/module/huge-base/UnitDetailEdit.jsx           |  167 +
 src/routeDom/oaRouteDom.jsx                       |   42 
 src/components/oa/logManage/Rawler/index.scss     |    0 
 src/module/huge-base/HeaderCustom.jsx             |   18 
 src/module/oa/index/Announcement.jsx              |    4 
 src/api/httpurl.js                                |    4 
 src/components/oa/logManage/operLog/index.scss    |    0 
 src/module/login/login.scss                       |    0 
 src/module/oa/index/System.jsx                    |    4 
 build(修复日期显示).zip                                 |    0 
 src/module/huge-base/AppServiceManage.jsx         |  113 +
 src/module/huge-base/RoleManage.jsx               |  114 +
 src/module/huge-base/GroupManage.jsx              |  121 +
 src/components/common/SearchFormView/index.jsx    |    8 
 src/components/oa/index/rulesList/index.scss      |    0 
 src/module/huge-base/ActivitiImg.jsx              |   33 
 src/components/oa/basicConfig/UserManage.jsx      |    2 
 src/module/huge-base/UserDetail.jsx               |  444 ++++
 src/components/oa/DocumentEditPage/index.scss     |    0 
 src/components/oa/index/workbench/index.jsx       |    0 
 src/components/oa/logManage/browseLog/index.scss  |    0 
 src/module/oa/document/DocumentEdit.jsx           |    4 
 src/module/huge-base/DeptDetail.jsx               |   99 +
 src/components/oa/basicConfig/UserDetail.jsx      |    0 
 src/module/huge-base/UserManage.jsx               |  139 +
 src/module/huge-base/RoleDetail.jsx               |  187 +
 src/module/huge-base/GroupDetail.jsx              |  150 +
 src/module/oa/index/workbench.jsx                 |   61 
 src/module/oa/logManage/browseLog.jsx             |    2 
 src/module/huge-base/UnitManage.jsx               |  252 ++
 src/components/oa/AnnouncementPage/index.scss     |    0 
 src/module/oa/document/DocumentDetail.jsx         |    4 
 src/module/huge-base/AppServiceDetail.jsx         |  143 +
 src/components/common/TopListTableView/index.jsx  |   10 
 src/module/huge-base/ActivitiDetail.jsx           |   98 +
 src/components/oa/index/workbench/index.scss      |    0 
 src/module/huge-base/AuthorityManage.jsx          |  267 ++
 src/index.css                                     |   64 
 src/module/huge-base/JobManage.jsx                |  566 +++++
 src/module/huge-base/DepartmentManage.jsx         |  316 +++
 src/module/huge-base/FunctionDetail.jsx           |  104 +
 src/routeDom/userRouteDom.jsx                     |   47 
 src/module/oa/logManage/Rawler.jsx                |    2 
 src/module/menu/menu.jsx                          |   81 
 src/index.js                                      |  162 
 src/api/request.js                                |   23 
 src/module/huge-base/ModuleDetailEdit.jsx         |  209 ++
 src/module/huge-base/DeployManage.jsx             |  245 ++
 src/components/oa/AnnouncementPage/index.jsx      |    0 
 src/menu/index.js                                 |    3 
 src/menu/menu.user.js                             |   88 
 src/module/huge-base/ModulesManage.jsx            |  314 +++
 src/components/common/Tree/index.jsx              |  210 ++
 src/components/oa/logManage/browseLog/index.jsx   |    0 
 src/module/oa/personal/information.jsx            |    2 
 /dev/null                                         |   81 
 src/components/common/HeadView/index.jsx          |   84 
 src/style/reset.scss                              |    6 
 src/components/oa/logManage/operLog/index.jsx     |    0 
 src/components/common/NotifyList/index.jsx        |    2 
 src/menu/menu.oa.js                               |   73 
 75 files changed, 5,544 insertions(+), 261 deletions(-)

diff --git "a/build\050\344\277\256\345\244\215\346\227\245\346\234\237\346\230\276\347\244\272\051.zip" "b/build\050\344\277\256\345\244\215\346\227\245\346\234\237\346\230\276\347\244\272\051.zip"
new file mode 100644
index 0000000..008e32a
--- /dev/null
+++ "b/build\050\344\277\256\345\244\215\346\227\245\346\234\237\346\230\276\347\244\272\051.zip"
Binary files differ
diff --git a/src/api/httpurl.js b/src/api/httpurl.js
index 5285521..bc312c0 100644
--- a/src/api/httpurl.js
+++ b/src/api/httpurl.js
@@ -1,7 +1,7 @@
 //内网测试地址
-// let StagingUrl = 'http://192.168.0.116:9072';
+// let StagingUrl = 'http://192.168.0.106:9072';
 let StagingUrl = "http://120.79.193.119:9072";
-
+// let StagingUrl = "http://120.79.193.119:9075";
 
 //mock地址
 let MockUrl = 'http://localhost:3721/';
diff --git a/src/api/request.js b/src/api/request.js
index 2228239..5d6752d 100644
--- a/src/api/request.js
+++ b/src/api/request.js
@@ -32,7 +32,7 @@
     method = 'get',
     showToast = true,
     autoLogin = true,
-    headers = {}
+    headers = {},
   } = options;
   let token = window.localStorage.getItem('token') || undefined;
 
@@ -50,9 +50,9 @@
     method,
     data,
     params,
-    headers
+    headers,
   })
-    .then(res => {
+    .then((res) => {
       // Taro.hideLoading();
       const { code, data, msg } = res.data;
       if (code == '0') {
@@ -64,24 +64,15 @@
         code == '10003'
       ) {
         // token失效重新返回登录页面
-        this.props.history.push({ pathname: '/login' });
+        // this.props.history.push({ pathname: '/login' });
+        window.location.href = window.location.origin + '#/login';
       } else {
         message.warning(msg);
         return false;
       }
     })
-    .catch(err => {
+    .catch((err) => {
       console.log(err);
-      let defaultMsg = '';
-
-      if (err.code !== CODE_SUCCESS) {
-        defaultMsg = '请求异常,请检查网络连接状况';
-      }
-      // Taro.showToast({
-      //     title: defaultMsg,
-      //     icon: "none"
-      // });
-      // return Promise.reject({ message: defaultMsg, ...err });
-      return Promise.reject({ msg: 'error' });
+      window.location.href = window.location.origin + '#/login';
     });
 }
diff --git a/src/components/common/HeadView/index.jsx b/src/components/common/HeadView/index.jsx
index e40d599..899d80b 100644
--- a/src/components/common/HeadView/index.jsx
+++ b/src/components/common/HeadView/index.jsx
@@ -6,11 +6,17 @@
 
 /** 头部组件 */
 
-import React, { useEffect } from 'react';
-import { Layout, Menu, Dropdown, Icon, Row, Col, message } from 'antd';
+import React, { useEffect, useState, useContext } from 'react';
+import { Layout, Menu, Dropdown, Icon, Row, Col, message, Select } from 'antd';
+import { createHashHistory } from 'history';
 const { Header } = Layout;
+import logo from '../../../img/logo.png'
 import './index.scss';
+import { Context } from '../../../index';
 
+const history = createHashHistory();
+
+const { Option } = Select;
 const menu = (
   <Menu>
     <Menu.Item>
@@ -24,30 +30,70 @@
         退出
       </a>
     </Menu.Item>
-
   </Menu>
 );
 
-export default function MenuView({ }) {
-
+export default function HeadView({ props }) {
   var loginUser = window.localStorage.getItem('loginUser') || '{}';
   loginUser = JSON.parse(loginUser);
-  
+
+  const [selectList, setSelectList] = useState([{ name: 'OA系统', key: 'oa' }]);
+  // const [selectKey, setSelectKey] = useState('oa');
+
+  useEffect(() => {
+    // 获取该登录用户的菜单权限
+    let menu = window.localStorage.getItem('menu') ? JSON.parse(window.localStorage.getItem('menu')) : [];//获取权限菜单
+    let administration = menu.find(({ moduleSymbol }) => moduleSymbol == 'administration');
+    if (administration) {
+      setSelectList(selectList.concat({ name: '用户中心', key: 'user' }));
+    }
+  }, [])
+
+  function onSelectChange(value) {
+    // setSelectKey(value);
+    // setContext && setContext({ value })
+  }
+
   return (
-    <Header style={{ background: '#fff', padding: 0, boxShadow: 'inset 0 -1px 0 0 #E5E5E5' }}>
+    <Context.Consumer>
       {
-        (loginUser && Object.keys(loginUser).length) &&
-        <Row type="flex" align="middle" justify="end" >
-          <Col style={{ marginRight: 40 }}>
-            {loginUser.trueName}&nbsp;&nbsp;&nbsp;
-            <Dropdown overlay={menu}>
-              <a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
-                [{loginUser.dept} | {loginUser.post}]<Icon type="caret-down" />
-              </a>
-            </Dropdown>
-          </Col>
-        </Row>
+        ({ role, setContext }) => (
+          <Header style={{ background: '#fff', padding: 0 }} className="header-view-main">
+            <Row type="flex">
+              <Col className="header-view-main-logo-area">
+                <img src={logo} alt="恒巨科技" />
+              </Col>
+              <Col className="flex-1">
+                {
+                  (loginUser && Object.keys(loginUser).length) &&
+                  <Row type="flex" align="middle" justify="space-between" >
+                    <Col>
+                      <Select value={role} size="small" style={{ marginLeft: 20, width: 120 }} onChange={value => {
+                        setContext({ role: value });
+                        history.push('/')
+                      }}>
+                        {
+                          selectList.map(({ name, key }) => (
+                            <Option value={key} key={key}>{name}</Option>
+                          ))
+                        }
+                      </Select>
+                    </Col>
+                    <Col style={{ marginRight: 40 }}>
+                      {loginUser.trueName}&nbsp;&nbsp;&nbsp;
+                      <Dropdown overlay={menu}>
+                        <a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
+                          [{loginUser.dept} | {loginUser.post}]<Icon type="caret-down" />
+                        </a>
+                      </Dropdown>
+                    </Col>
+                  </Row>
+                }
+              </Col>
+            </Row>
+          </Header>
+        )
       }
-    </Header>
+    </Context.Consumer>
   );
 }
diff --git a/src/components/common/HeadView/index.scss b/src/components/common/HeadView/index.scss
index 5b152f5..7ee8b46 100644
--- a/src/components/common/HeadView/index.scss
+++ b/src/components/common/HeadView/index.scss
@@ -1,5 +1,12 @@
-.menu-view {
+.header-view {
   &-main {
-    padding: 8px;
+    &-logo-area{
+      width: 200px;
+      padding: 0 10px;
+      height: 100%;
+      & img{
+        width: 100%;
+      }
+    }
   }
 }
diff --git a/src/components/common/NotifyList/index.jsx b/src/components/common/NotifyList/index.jsx
index 7409e23..b6afd7d 100644
--- a/src/components/common/NotifyList/index.jsx
+++ b/src/components/common/NotifyList/index.jsx
@@ -66,7 +66,7 @@
           <marquee onMouseOut={this.onMouseOut} onMouseOver={this.onMouseOver} ref='marquee' style={{ cursor: 'pointer' }}>{notice.documentTitle || ''}</marquee>
         </div>
         {
-          notice.documentContent ? <Tooltip placement='topLeft' title={this.emoveTAG(notice.documentContent)} arrowPointAtCenter>
+          notice.documentContent ? <Tooltip placement='topLeft' title={this.emoveTAG(notice.documentContent)}>
             <div className="notify-list-main-dom-msg-content" onClick={() => { notice.id && this.linkDetail(notice.id) }}>{this.emoveTAG(notice.documentContent)}</div>
           </Tooltip> : null
         }
diff --git a/src/components/common/SearchFormView/index.jsx b/src/components/common/SearchFormView/index.jsx
index 398649e..bbc7bc1 100644
--- a/src/components/common/SearchFormView/index.jsx
+++ b/src/components/common/SearchFormView/index.jsx
@@ -107,7 +107,7 @@
     };
 
     render() {
-        const { formData = {}, data = [], children } = this.props;
+        const { formData = {}, data = [], children, width = "25%" } = this.props;
         let size = 'default';
 
         return (
@@ -117,7 +117,7 @@
 
                         {data.length > 0 &&
                             data.map((item, idx) => (
-                                <Card.Grid key={idx} style={{ width: '20%' }} hoverable={false} >
+                                <Card.Grid key={idx} style={{ width }} hoverable={false} >
                                     {(() => {
                                         switch (item.type) {
                                             case 'select':
@@ -171,7 +171,7 @@
                                                 return (
                                                     <Form.Item label={item.label}>
                                                         <RangePicker
-                                                            style={{ width: '100%'}}
+                                                            style={{ width: '100%' }}
                                                             size={size}
                                                             ranges={{
                                                                 Today: [moment(), moment()],
@@ -211,7 +211,7 @@
                                     })()}
                                 </Card.Grid>
                             ))}
-                        <Card.Grid style={{ width: '20%' }}>
+                        <Card.Grid style={{ width }}>
                             <Row type="flex" gutter={20} align="middle" align="middle" style={{ height: 40 }}>
                                 <Col>
                                     <Button
diff --git a/src/components/common/TopListTableView/index.jsx b/src/components/common/TopListTableView/index.jsx
index edb1878..d607e53 100644
--- a/src/components/common/TopListTableView/index.jsx
+++ b/src/components/common/TopListTableView/index.jsx
@@ -31,7 +31,8 @@
         this.setState({
           topList: [
             { ...tag['latenessRanking'], dataSource: res['latenessRanking'] },
-            { ...tag['meritsRanking'], dataSource: res['meritsRanking'] },
+            { ...tag['earlyRanking'], dataSource: res['earlyRanking'] },
+            // { ...tag['meritsRanking'], dataSource: res['meritsRanking'] },
             { ...tag['defectRanking'], dataSource: res['defectRanking'] },
           ]
         })
@@ -42,11 +43,12 @@
   componentDidMount() { }
 
   renderDom = ({ name, columns, dataSource }) => {
-    return <div className="top-list-table-view-main-table">
+    return <div className="top-list-table-view-main-table h-100">
       <div className="top-list-table-view-main-table-title">{name}
-        <span className="top-list-table-view-main-table-title-fuc">查看</span>
+        {/* <span className="top-list-table-view-main-table-title-fuc">查看</span> */}
       </div>
       <Table
+        scroll={{ y: 130 }}
         dataSource={dataSource ? dataSource.map((a, idx) => ({ ...a, key: idx })) : []}
         columns={columns}
         size="small"
@@ -63,7 +65,7 @@
         <Row type="flex" gutter={12}>
           {
             topList.map((item, idx) => {
-              return <Col span={24 / 3} key={idx}>{this.renderDom(item)}</Col>;
+              return <Col span={24 / topList.length} key={idx} >{this.renderDom(item)}</Col>;
             })
           }
         </Row>
diff --git a/src/components/common/TopListTableView/tagList.js b/src/components/common/TopListTableView/tagList.js
index 4de7ad2..3c19a47 100644
--- a/src/components/common/TopListTableView/tagList.js
+++ b/src/components/common/TopListTableView/tagList.js
@@ -1,4 +1,5 @@
 /* eslint-disable */
+import moment from 'moment';
 export const tag = {
   // 绩效排行
   meritsRanking: {
@@ -10,17 +11,17 @@
         key: 'index',
         render: (item, cur, idx) => {
           return idx + 1;
-        }
+        },
       },
       {
         title: '姓名',
         dataIndex: 'userName',
-        key: 'userName'
+        key: 'userName',
       },
       {
         title: '部门',
         dataIndex: 'userDeptName',
-        key: 'userDeptName'
+        key: 'userDeptName',
       },
       {
         title: '绩效得分',
@@ -28,9 +29,9 @@
         key: 'meritsGrade',
         render: (cur, item) => {
           return cur + '分';
-        }
-      }
-    ]
+        },
+      },
+    ],
   },
 
   // 缺陷排行
@@ -43,17 +44,17 @@
         key: 'index',
         render: (item, cur, idx) => {
           return idx + 1;
-        }
+        },
       },
       {
         title: '姓名',
         dataIndex: 'userName',
-        key: 'userName'
+        key: 'userName',
       },
       {
         title: '部门',
         dataIndex: 'userDeptName',
-        key: 'userDeptName'
+        key: 'userDeptName',
       },
       {
         title: '缺陷数',
@@ -61,11 +62,12 @@
         key: 'defectNumber',
         render: (cur, item) => {
           return cur + '个';
-        }
-      }
-    ]
+        },
+      },
+    ],
   },
 
+  //迟到排行
   latenessRanking: {
     name: '考勤(迟到)榜单',
     columns: [
@@ -75,34 +77,84 @@
         key: 'index',
         render: (item, cur, idx) => {
           return idx + 1;
-        }
+        },
       },
       {
         title: '姓名',
         dataIndex: 'userName',
-        key: 'userName'
+        key: 'userName',
       },
       {
         title: '部门',
         dataIndex: 'userDeptName',
-        key: 'userDeptName'
+        key: 'userDeptName',
+        width: '25%',
       },
       {
         title: '次数',
-        dataIndex: 'lateness',
-        key: 'lateness',
+        dataIndex: 'lateTimes',
+        key: 'lateTimes',
         render: (item, cur) => {
           return item + '次';
-        }
+        },
       },
       {
         title: '时长(分)',
-        dataIndex: 'latenessTime',
-        key: 'latenessTime',
+        dataIndex: 'lateMinute',
+        key: 'lateMinute',
         render: (item, cur) => {
           return item + '分钟';
-        }
-      }
-    ]
-  }
+        },
+      },
+    ],
+  },
+
+  //早到排行
+  earlyRanking: {
+    name: '考勤(早到)榜单',
+    columns: [
+      {
+        title: '名次',
+        dataIndex: 'index',
+        key: 'index',
+        render: (item, cur, idx) => {
+          return idx + 1;
+        },
+      },
+      {
+        title: '姓名',
+        dataIndex: 'userName',
+        key: 'userName',
+      },
+      {
+        title: '部门',
+        dataIndex: 'userDeptName',
+        key: 'userDeptName',
+        width: '25%',
+      },
+      {
+        title: '打卡时间',
+        dataIndex: 'onDutyUserCheckTime',
+        key: 'onDutyUserCheckTime',
+        className: 'fontSize12',
+        width: '25%',
+        render: (item, cur) => {
+          return (
+            item &&
+            // <div style={{ fontSize: 12 }}>
+            moment(item).format('MM/DD HH:mm')
+            // </div>
+          );
+        },
+      },
+      {
+        title: '早到时长',
+        dataIndex: 'earlyMinute',
+        key: 'earlyMinute',
+        render: (item, cur) => {
+          return item + '分钟';
+        },
+      },
+    ],
+  },
 };
diff --git a/src/components/common/Tree/index.jsx b/src/components/common/Tree/index.jsx
new file mode 100644
index 0000000..e43e32b
--- /dev/null
+++ b/src/components/common/Tree/index.jsx
@@ -0,0 +1,210 @@
+/* eslint-disable */
+import React from 'react';
+import { Row, Col, Tree, Input, Icon, Button } from 'antd';
+
+const TreeNode = Tree.TreeNode;
+const Search = Input.Search;
+
+const getParentKey = (title, tree) => {
+  let parentKey;
+  for (let i = 0; i < tree.length; i++) {
+    const node = tree[i];
+    if (node.children) {
+      if (node.children.some(item => item.title === title)) {
+        parentKey = node.key;
+      } else if (getParentKey(title, node.children)) {
+        parentKey = getParentKey(title, node.children);
+      }
+    }
+  }
+  return parentKey;
+};
+
+export default class SearchTree extends React.Component {
+  constructor(props) {
+    super(props)
+    this.gData = this.props.data;
+    this.dataList = []
+    this.state = {
+      expandedKeys: props.expandedKeys,
+      selectedKeys: props.selectedKeys,
+      clickEle: '',
+      searchValue: '',
+      autoExpandParent: true,
+      showSearch: true,
+      checkable: false
+    }
+  }
+  componentDidMount() {
+    const generateList = (data) => {
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i];
+        const key = node.key;
+        const title = node.title;
+        this.dataList.push({ key, title });
+        if (node.children) {
+          generateList(node.children, title);
+        }
+      }
+    };
+    generateList(this.props.data)
+  }
+
+  onExpand = (expandedKeys) => {
+    //this.props.onExpand(expandedKeys)
+    this.setState({
+      expandedKeys,
+      autoExpandParent: false,
+    });
+  }
+
+  onChange = (e) => {
+    const value = e.target.value;
+    const expandedKeys = this.dataList.map((item) => {
+      if (item.title.indexOf(value) > -1) {
+        return getParentKey(item.title, this.gData);
+      }
+      return null;
+    }).filter((item, i, self) => item && self.indexOf(item) === i);
+    this.setState({
+      expandedKeys,
+      searchValue: value,
+      autoExpandParent: true,
+    });
+  }
+
+  treeSelect = (selectedKeys, e) => {
+    console.log(selectedKeys)
+    let _this = this;
+    _this.props.onSelect && _this.props.onSelect(selectedKeys);
+    if (selectedKeys.length == 0 && typeof this.props.clearKeys !== "undefined") {
+      this.props.clearKeys();
+      this.setState({ clickEle: '' });//置空点击节点
+    }
+    const getOwnNodes = (data) => {
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i]
+        const key = node.key;
+        if (key == selectedKeys) {
+          this.setState({ clickEle: node });
+          if (data[i].children) {   //如果有子,则返回所有子节点
+            this.props.treeSelect(node.children, [node])
+          } else {   //没有子节点,就返回当前节点
+            this.props.treeSelect([node], [node])
+          }
+          return null;
+        } else {
+          if (data[i].children) {
+            getOwnNodes(data[i].children)
+          }
+        }
+      }
+    };
+    getOwnNodes(this.gData)
+  }
+
+  onCheck = (checkedKeys, { checked: bool, checkedNodes, node, event }) => {
+    console.log('checkedKeys', checkedKeys, 'checkedNodes', checkedNodes)
+    let _this = this;
+    let selectleafNodeKeys = [];
+
+    for (var i = 0; i < checkedNodes.length; i++) {
+      if (checkedNodes[i].props.children && checkedNodes[i].props.children.length > 0) {
+      } else {
+        selectleafNodeKeys.push(checkedNodes[i].key)
+      }
+    }
+    console.log('子节点选中的key', selectleafNodeKeys);
+    let treeCheckArr = [];  //选中节点的信息
+    const getOwnNodes = (data, checkedKey) => {
+      let _this = this;
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i]
+        if (node.key == checkedKey) {
+          if (data[i].children) {   //如果有子,也返回当前节点
+            treeCheckArr.push(data[i]);
+          } else {   //没有子节点,就返回当前节点
+            treeCheckArr.push(data[i]);
+          }
+          return null;
+        } else {
+          if (data[i].children) {
+            getOwnNodes(data[i].children, checkedKey)
+          }
+        }
+      }
+    };
+    for (var j = 0; j < selectleafNodeKeys.length; j++) {
+      getOwnNodes(_this.gData, selectleafNodeKeys[j]);
+    }
+    _this.props.currentTreeCheck(treeCheckArr);
+    _this.props.onCheck(checkedKeys, checkedNodes);
+  }
+
+  add = () => {
+    this.props.add()
+  }
+
+  delete = () => {
+    this.props.delete(this.state.clickEle)
+  }
+  render() {
+    const { searchValue, expandedKeys, autoExpandParent, selectedKeys } = this.state;
+    const showSearch = typeof this.props.showSearch === "undefined" ? this.state.showSearch : this.props.showSearch;
+    const checkable = typeof this.props.checkable === "undefined" ? this.state.checkable : this.props.checkable;
+
+    const loop = data => data.map((item) => {
+      const disabled = item.disabled || false;
+      const index = item.title.indexOf(searchValue);
+      const beforeStr = item.title.substr(0, index);
+      const afterStr = item.title.substr(index + searchValue.length);
+      const title = index > -1 ? (
+        <span>
+          {beforeStr}
+          <span style={{ color: '#f50' }}>{searchValue}</span>
+          {afterStr}
+        </span>
+      ) : <span>{item.title}</span>;
+      if (item.children) {
+        return (
+          <TreeNode key={item.key} title={title} disabled={disabled}>
+            {loop(item.children)}
+          </TreeNode>
+        );
+      }
+      return <TreeNode key={item.key} title={title} disabled={disabled} />;
+    });
+
+    return (
+
+      <div>
+        <div style={{ display: 'flex', justifyContent: 'space-around', alignItems: 'center' }}>
+          {showSearch && <Search style={{ marginBottom: 1 }} placeholder="搜索资源名称" onChange={this.onChange} />}
+          {this.props.add && <Button onClick={this.add} style={{ marginLeft: 5 }}><Icon type="plus-circle-o" style={{ fontSize: 16 }} /></Button>}
+          {this.props.delete && <Button onClick={this.delete} style={{ marginLeft: 5 }}><Icon type="delete" style={{ fontSize: 16 }} /></Button>}
+        </div>
+        {
+          this.gData.length > 0 &&
+          // style={{height: 413, overflowY: 'auto'}}
+          <div>
+            <Tree
+              defaultExpandAll={true}
+              onSelect={this.treeSelect}
+              // onExpand={this.onExpand}
+              // expandedKeys={expandedKeys}
+              autoExpandParent={autoExpandParent}
+              showLine
+              checkable={checkable}
+              onCheck={this.onCheck}
+              checkedKeys={this.props.checkedKeys}
+              selectedKeys={this.props.selectedKeys}
+            >
+              {loop(this.gData)}
+            </Tree>
+          </div>
+        }
+      </div>
+    );
+  }
+}
+
diff --git a/src/components/page/AnnouncementPage/index.jsx b/src/components/oa/AnnouncementPage/index.jsx
similarity index 100%
rename from src/components/page/AnnouncementPage/index.jsx
rename to src/components/oa/AnnouncementPage/index.jsx
diff --git a/src/components/page/AnnouncementPage/index.scss b/src/components/oa/AnnouncementPage/index.scss
similarity index 100%
rename from src/components/page/AnnouncementPage/index.scss
rename to src/components/oa/AnnouncementPage/index.scss
diff --git a/src/components/page/DocumentDetailPage/index.jsx b/src/components/oa/DocumentDetailPage/index.jsx
similarity index 100%
rename from src/components/page/DocumentDetailPage/index.jsx
rename to src/components/oa/DocumentDetailPage/index.jsx
diff --git a/src/components/page/DocumentDetailPage/index.scss b/src/components/oa/DocumentDetailPage/index.scss
similarity index 100%
rename from src/components/page/DocumentDetailPage/index.scss
rename to src/components/oa/DocumentDetailPage/index.scss
diff --git a/src/components/page/DocumentEditPage/index.jsx b/src/components/oa/DocumentEditPage/index.jsx
similarity index 100%
rename from src/components/page/DocumentEditPage/index.jsx
rename to src/components/oa/DocumentEditPage/index.jsx
diff --git a/src/components/page/DocumentEditPage/index.scss b/src/components/oa/DocumentEditPage/index.scss
similarity index 100%
rename from src/components/page/DocumentEditPage/index.scss
rename to src/components/oa/DocumentEditPage/index.scss
diff --git a/src/components/page/basicConfig/UserDetail.jsx b/src/components/oa/basicConfig/UserDetail.jsx
similarity index 100%
rename from src/components/page/basicConfig/UserDetail.jsx
rename to src/components/oa/basicConfig/UserDetail.jsx
diff --git a/src/components/page/basicConfig/UserManage.jsx b/src/components/oa/basicConfig/UserManage.jsx
similarity index 97%
rename from src/components/page/basicConfig/UserManage.jsx
rename to src/components/oa/basicConfig/UserManage.jsx
index 4e5a7c5..8f49e23 100644
--- a/src/components/page/basicConfig/UserManage.jsx
+++ b/src/components/oa/basicConfig/UserManage.jsx
@@ -101,7 +101,7 @@
           return <div>
             <Link to={{ pathname: "/baseManage/userDetail/" + record.id + '/Modify', query: { id: record.id } }}>修改</Link>
             <Divider type="vertical" />
-            <a href="javascript:void(0);" onClick={() => this.delete(record.id)}>删除</a>
+            <a onClick={() => this.delete(record.id)}>删除</a>
           </div>
         }
       }
diff --git a/src/components/page/index/rulesList/index.jsx b/src/components/oa/index/rulesList/index.jsx
similarity index 100%
rename from src/components/page/index/rulesList/index.jsx
rename to src/components/oa/index/rulesList/index.jsx
diff --git a/src/components/page/index/rulesList/index.scss b/src/components/oa/index/rulesList/index.scss
similarity index 100%
rename from src/components/page/index/rulesList/index.scss
rename to src/components/oa/index/rulesList/index.scss
diff --git a/src/components/page/index/workbench/index.jsx b/src/components/oa/index/workbench/index.jsx
similarity index 100%
rename from src/components/page/index/workbench/index.jsx
rename to src/components/oa/index/workbench/index.jsx
diff --git a/src/components/page/index/workbench/index.scss b/src/components/oa/index/workbench/index.scss
similarity index 100%
rename from src/components/page/index/workbench/index.scss
rename to src/components/oa/index/workbench/index.scss
diff --git a/src/components/page/logManage/Rawler/index.jsx b/src/components/oa/logManage/Rawler/index.jsx
similarity index 100%
rename from src/components/page/logManage/Rawler/index.jsx
rename to src/components/oa/logManage/Rawler/index.jsx
diff --git a/src/components/page/logManage/Rawler/index.scss b/src/components/oa/logManage/Rawler/index.scss
similarity index 100%
rename from src/components/page/logManage/Rawler/index.scss
rename to src/components/oa/logManage/Rawler/index.scss
diff --git a/src/components/page/logManage/browseLog/index.jsx b/src/components/oa/logManage/browseLog/index.jsx
similarity index 100%
rename from src/components/page/logManage/browseLog/index.jsx
rename to src/components/oa/logManage/browseLog/index.jsx
diff --git a/src/components/page/logManage/browseLog/index.scss b/src/components/oa/logManage/browseLog/index.scss
similarity index 100%
rename from src/components/page/logManage/browseLog/index.scss
rename to src/components/oa/logManage/browseLog/index.scss
diff --git a/src/components/page/logManage/operLog/index.jsx b/src/components/oa/logManage/operLog/index.jsx
similarity index 100%
rename from src/components/page/logManage/operLog/index.jsx
rename to src/components/oa/logManage/operLog/index.jsx
diff --git a/src/components/page/logManage/operLog/index.scss b/src/components/oa/logManage/operLog/index.scss
similarity index 100%
rename from src/components/page/logManage/operLog/index.scss
rename to src/components/oa/logManage/operLog/index.scss
diff --git a/src/components/page/personal/information/index.jsx b/src/components/oa/personal/information/index.jsx
similarity index 100%
rename from src/components/page/personal/information/index.jsx
rename to src/components/oa/personal/information/index.jsx
diff --git a/src/components/page/personal/information/index.scss b/src/components/oa/personal/information/index.scss
similarity index 100%
rename from src/components/page/personal/information/index.scss
rename to src/components/oa/personal/information/index.scss
diff --git a/src/index.css b/src/index.css
index 21dc559..07d27b8 100644
--- a/src/index.css
+++ b/src/index.css
@@ -34,6 +34,10 @@
   padding: 9px 8px !important;
 }
 
+.border{
+  border: 20px solid #ededed;
+}
+
 .margin {
   margin: 20px;
 }
@@ -54,4 +58,64 @@
   margin-bottom: 20px;
 }
 
+.fontSize12{
+  font-size: 12px;
+}
+
+.ant-divider-horizontal{
+  margin: 20px 0 !important;
+}
+
+.margin-bottom{
+  margin-bottom: 20px;
+}
+
+.ant-card-head-title{
+  font-weight: bold !important;
+}
+
+div{
+  box-sizing: border-box;
+}
+
+.flex-box-column{
+  display: flex;
+  flex-direction: column;
+}
+
+.flex-box {
+  display: flex;
+}
+
+.align-center{
+  align-items: center;
+}
+
+.justify-content{
+  justify-content: center;
+}
+
+.flex-1 {
+  flex: 1;
+  overflow: auto;
+}
+
+.ant-spin-nested-loading{
+  height: 100%;
+}
+.ant-spin-container{
+  height: 100%;
+}
+
+.treeNodeUnselectable {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -o-user-select: none;
+  -ms-user-select: none;
+}
+
+.ant-alert.ant-alert-no-icon {
+  padding: 2px 8px !important;
+}
+
 
diff --git a/src/index.js b/src/index.js
index ffa772b..cb0f05c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,9 +3,6 @@
 import ReactDOM from 'react-dom';
 import './index.css';
 
-import Menu from './pages/menu/menu';
-import Header from './components/common/HeadView';
-
 import * as serviceWorker from './serviceWorker';
 import { Router, Route, Switch, Redirect } from 'react-router-dom';
 import { ConfigProvider } from 'antd';
@@ -17,82 +14,111 @@
 import 'react-app-polyfill/ie11';
 import 'react-app-polyfill/stable';
 
-// 引进页面(pages)
-import Index from './pages/Index';
-import Login from './pages/login/login';
-import Workbench from './pages/index/workbench'; //首页--工作台
-import System from './pages/index/System'; //首页--工作制度
-import Announcement from './pages/index/Announcement'; //全部通知
+// 公用结构组件
+import Menu from './module/menu/menu';
+import Header from './components/common/HeadView';
 
-import DocumentEdit from './pages/document/DocumentEdit'; //新建文档
-import DocumentDetail from './pages/document/DocumentDetail'; //文档详情
-import BrowseLog from './pages/logManage/browseLog'; //浏览日志
-import OperLog from './pages/logManage/operLog'; //操作日志
-import Rawler from './pages/logManage/Rawler'; //爬虫词条管理
-import Information from './pages/personal/information'; //个人信息
+// oa路由映射
+import OaRouteDom from './routeDom/oaRouteDom';
+import UserRouteDom from './routeDom/userRouteDom';
 
-// 基础平台
-import UserManage from './components/page/basicConfig/UserManage';//用户管理
+export const Context = React.createContext();
 
 const { Content } = Layout;
 const history = createHashHistory();
 
-ReactDOM.render(
-  <ConfigProvider locale={zh_CN}>
-    <Router history={history}>
-      <Layout className="h-100">
-        <Switch>
-          <Route path="/login" component={null} />
-          <Route component={Menu} />
-        </Switch>
-        <Layout>
-          <Switch>
-            <Route path="/login" component={null} />
-            <Route component={Header} />
-          </Switch>
-          <Content>
-            <Switch>
-              {/* 基础平台 */}
-              <Route path="/baseManage/user" component={UserManage} />
+class RouteDom extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      context: {
+        role: 'oa',
+        roleMenuList: [],
+        setContext: this.setContext,
+      },
+    };
+  }
 
-              {/* 新建文档 */}
-              <Route path="/document/create/:id?" component={DocumentEdit} />
-              {/* 文档、通知详情 */}
-              <Route path="/document/detail/:id" component={DocumentDetail} />
+  componentDidMount() {
+    let pathname = history.location.pathname;
+    let menusListByRole = window.localStorage.getItem('menusListByRole')
+      ? JSON.parse(window.localStorage.getItem('menusListByRole'))
+      : [];
 
-              {/* 全部通知 */}
-              <Route
-                path="/index/workbench/announcement"
-                component={Announcement}
-              />
-              {/* 规章制度 */}
-              <Route path="/index/rules" component={System} />
-              {/* 首页 */}
-              <Route path="/index" component={Workbench} />
+    let role = Object.keys(menusListByRole).reduce((p, n) => {
+      if (
+        menusListByRole[n].menus
+          .reduce((p, n) => {
+            if (n.children) {
+              return p.concat(n.children);
+            } else {
+              return p.concat(n);
+            }
+          }, [])
+          .find(({ path }) => path == pathname)
+      ) {
+        return p.concat(n);
+      } else {
+        return p;
+      }
+    }, []);
 
-              {/* 浏览日志 */}
-              <Route path="/logManage/browseLog" component={BrowseLog} />
-              {/* 操作日志 */}
-              <Route path="/logManage/operLog" component={OperLog} />
-              {/* 爬虫词条管理 */}
-              <Route path="/logManage/rawler" component={Rawler} />
-              {/* 个人信息 */}
-              <Route path="/personal/information" component={Information} />
+    this.setState({
+      context: {
+        ...this.state.context,
+        role,
+      },
+    });
+  }
 
-              {/* 登录页 */}
-              <Route path="/login" component={Login} />
-              <Route path="/" component={Workbench} />
+  setContext = (data) => {
+    console.log('data', data);
+    this.setState({
+      context: {
+        ...this.state.context,
+        ...data,
+      }, //更新context
+    });
+  };
 
-              {/* 路由的页面重定向 */}
-              <Redirect to="/" component={Workbench} />
-            </Switch>
-          </Content>
-        </Layout>
-      </Layout>
-    </Router>
-  </ConfigProvider>,
-  document.getElementById('root')
-);
+  render() {
+    let { context } = this.state;
+    return (
+      <ConfigProvider locale={zh_CN}>
+        <Context.Provider value={context}>
+          <Router history={history}>
+            <Layout className="h-100">
+              {/* 顶部-侧边布局-通栏 */}
+              {/* 顶部 */}
+              <Switch>
+                <Route path="/login" component={null} />
+                <Route
+                  component={() => (
+                    <Header setContext={this.setContext} props={this.props} />
+                  )}
+                />
+              </Switch>
+              <Layout>
+                <Switch>
+                  <Route path="/login" component={null} />
+                  <Route component={Menu} />
+                </Switch>
+                <Layout>
+                  <Content>
+                    {context.role == 'oa' && <OaRouteDom />}
+                    {context.role == 'user' && <UserRouteDom />}
+                  </Content>
+                </Layout>
+              </Layout>
+            </Layout>
+          </Router>
+        </Context.Provider>
+      </ConfigProvider>
+    );
+  }
+}
+
+ReactDOM.render(<RouteDom></RouteDom>, document.getElementById('root'));
 
 // If you want your app to work offline and load faster, you can change
 // unregister() to register() below. Note this comes with some pitfalls.
diff --git a/src/menu/index.js b/src/menu/index.js
index 124e39c..452d5ae 100644
--- a/src/menu/index.js
+++ b/src/menu/index.js
@@ -1,2 +1,3 @@
-export { default as menus } from './menu.data';
+export { default as oaMenus } from './menu.oa';
+export { default as userMenus } from './menu.user';
 export { default as getMenuListByPermission } from './menu.permission';
\ No newline at end of file
diff --git a/src/menu/menu.data.js b/src/menu/menu.oa.js
similarity index 69%
rename from src/menu/menu.data.js
rename to src/menu/menu.oa.js
index ea7a8d4..6838ce9 100644
--- a/src/menu/menu.data.js
+++ b/src/menu/menu.oa.js
@@ -107,32 +107,32 @@
       },
       {
         key: '/logManage/rawler',
-        name: "爬虫词条管理",
-        path: "/logManage/rawler",
+        name: '爬虫词条管理',
+        path: '/logManage/rawler',
         permKey: '/logManage/rawler',
         parentKey: '/logManage',
         children: [],
       },
     ],
   },
-  {
-    key: 'administration',
-    name: '用户管理',
-    path: 'administration',
-    icon: 'team',
-    permKey: 'administration',
-    children: [
-      {
-        key: '/administration',
-        name: '用户中心',
-        path: 'http://120.79.193.119:9074/base/login.html#/',
-        permKey: 'http://120.79.193.119:9074/base/login.html#/',
-        children: [],
-        parentKey: 'administration',
-        type: 'open',
-      },
-    ],
-  },
+  // {
+  //   key: 'administration',
+  //   name: '用户管理',
+  //   path: 'administration',
+  //   icon: 'team',
+  //   permKey: 'administration',
+  //   children: [
+  //     {
+  //       key: '/administration',
+  //       name: '用户中心',
+  //       path: 'http://120.79.193.119:9074/base/login.html#/',
+  //       permKey: 'http://120.79.193.119:9074/base/login.html#/',
+  //       children: [],
+  //       parentKey: 'administration',
+  //       type: 'open',
+  //     },
+  //   ],
+  // },
   {
     key: 'personal',
     name: '个人中心',
@@ -150,6 +150,39 @@
       },
     ],
   },
+  {
+    key: 'merits',
+    name: '绩效管理',
+    path: 'merits',
+    icon: 'user',
+    permKey: 'merits',
+    children: [
+      {
+        key: '/merits/meritsOverview',
+        name: '绩效总览',
+        path: '/merits/meritsOverview',
+        permKey: '/merits/meritsOverview',
+        children: [],
+        parentKey: 'merits',
+      },
+      {
+        key: '/merits/meritsExamine',
+        name: '绩效考核',
+        path: '/merits/meritsExamine',
+        permKey: '/merits/meritsExamine',
+        children: [],
+        parentKey: 'merits',
+      },
+      {
+        key: '/merits/meritsDispose',
+        name: '参数配置',
+        path: '/merits/meritsDispose',
+        permKey: '/merits/meritsDispose',
+        children: [],
+        parentKey: 'merits',
+      },
+    ],
+  },
 ];
 
 export default menus;
diff --git a/src/menu/menu.user.js b/src/menu/menu.user.js
new file mode 100644
index 0000000..99927b1
--- /dev/null
+++ b/src/menu/menu.user.js
@@ -0,0 +1,88 @@
+/**
+ * 菜单列表
+ * key, path需要保持唯一
+ * permKey表示权限Key值
+ */
+const menus = [
+  {
+    name: '用户管理',
+    path: '/baseManage/user',
+    icon: 'user',
+  },
+  {
+    name: '组管理',
+    path: '/baseManage/group',
+    icon: 'team',
+  },
+  {
+    name: '组织管理',
+    icon: 'solution',
+    path: '/organizationMgt',
+    children: [
+      {
+        name: '单位管理',
+        path: '/organizationMgt/unit',
+        parentKey: '/organizationMgt',
+      },
+      {
+        name: '部门管理',
+        path: '/organizationMgt/department',
+        parentKey: '/organizationMgt',
+      },
+      {
+        name: '岗位管理',
+        path: '/organizationMgt/job',
+        parentKey: '/organizationMgt',
+      },
+    ],
+  },
+  {
+    name: '资源管理',
+    icon: 'book',
+    path: '/resourceMgt',
+    children: [
+      {
+        name: '应用服务管理',
+        path: '/resourceMgt/appService',
+        parentKey: '/resourceMgt'
+      },
+      {
+        name: '模块管理',
+        path: '/resourceMgt/modules',
+        parentKey: '/resourceMgt'
+      },
+      {
+        name: '功能管理',
+        path: '/resourceMgt/function',
+        parentKey: '/resourceMgt'
+      },
+    ],
+  },
+  {
+    name: '权限管理',
+    icon: 'tool',
+    path: '/authorityMgt',
+    children: [
+      {
+        name: '角色管理',
+        path: '/authorityMgt/role',
+        parentKey: '/authorityMgt'
+      },
+      {
+        name: '权限管理',
+        path: '/authorityMgt/authority',
+        parentKey: '/authorityMgt'
+      },
+    ],
+  },
+  // ,{
+  //   name: '工作流管理',
+  //   children: [{
+  //     name: '流程部署管理',
+  //     path: '/activitiManage/deploy',
+  //   }
+  // ]
+  // }
+];
+
+export default menus;
diff --git a/src/module/huge-base/ActivitiDetail.jsx b/src/module/huge-base/ActivitiDetail.jsx
new file mode 100644
index 0000000..88f63bd
--- /dev/null
+++ b/src/module/huge-base/ActivitiDetail.jsx
@@ -0,0 +1,98 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Icon, Button, Table, message,Breadcrumb,Layout } from 'antd';
+import Fetch from '../fetch';
+const { Column } = Table;
+
+
+export default class ActivitiDetail extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      loading: true,
+      tableData: [],
+    };
+  }
+
+  componentDidMount() {
+    const deploymentId = this.props.location.state.deploymentId;
+    let _this = this;
+    _this.setState({ loading: true });
+    Fetch.getProcessDefinition({
+      deploymentId
+    }).then( res => {
+      console.log(res)
+      let tmpArr = [];
+      res.map(e => {
+        let obj = {
+          key: e.id,
+          _key:e.key, 
+          id:e.id,
+          version:e.version,
+          status:e.status,
+          name: e.name, 
+          createTime: e.createTime,
+        }
+        tmpArr.push(obj)
+      })
+      this.setState({
+        tableData: tmpArr,
+        loading: false,
+      });
+    })
+  }
+
+  render() {
+    return (
+      <Layout className="h-100 page-table">
+        <Row>
+          <Breadcrumb className="breadcrumb-style">
+            <Breadcrumb.Item>工作流管理</Breadcrumb.Item>
+            <Breadcrumb.Item>流程部署管理</Breadcrumb.Item>
+            <Breadcrumb.Item>详情</Breadcrumb.Item>
+          </Breadcrumb>
+        </Row>
+        <Card style={{border:20, margin:20, padding:20}}>
+        <Row>
+        <Link to="/activitiManage/deploy"><Button type="default">返回</Button></Link>
+        </Row>
+          <Row>
+            <Table dataSource={this.state.tableData} pagination={false}>
+              <Column
+                title="流程KEY"
+                dataIndex="_key"
+                key="_key"
+              />
+              <Column
+                title="流程名称"
+                dataIndex="name"
+                key="name"
+              />
+              <Column
+                title="流程版本"
+                dataIndex="version"
+                key="version"
+              />
+              <Column
+                title="当前状态"
+                dataIndex="status"
+                key="status"
+                render={(text, record) => text?"运行":"挂起"}
+              />
+              <Column
+                title="操作"
+                key="action"
+                render={(text, record) => (
+                  <span>
+                    <Link to={{ pathname: "/activitiManage/activitiImg", state: { id: record.id} }}>流程图</Link>
+                  </span>
+                )}
+              />
+            </Table>
+
+          </Row>
+        </Card>
+      </Layout>
+    )
+  } 
+}
diff --git a/src/module/huge-base/ActivitiImg.jsx b/src/module/huge-base/ActivitiImg.jsx
new file mode 100644
index 0000000..e5342cc
--- /dev/null
+++ b/src/module/huge-base/ActivitiImg.jsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Icon, Button,message,Breadcrumb,Layout } from 'antd';
+import { domain } from '../fetch/_';
+
+export default class ActivitiImg extends React.Component {
+
+  render() {
+    return (
+      <Layout className="h-100 page-table">
+        <Row>
+          <Breadcrumb className="breadcrumb-style">
+            <Breadcrumb.Item>工作流管理</Breadcrumb.Item>
+            <Breadcrumb.Item>流程部署管理</Breadcrumb.Item>
+            <Breadcrumb.Item>流程图</Breadcrumb.Item>
+          </Breadcrumb>
+        </Row>
+        <Card style={{border:20, margin:20, padding:20}}>
+        <Row>
+        <Row style={{borderStyle:'solid', borderWidth:0.01}}>
+          <span style={{fontSize:25}}>流程图</span>
+          <div style={{float:'right'}}>
+          <Link to="/activitiManage/deploy"><Button type="default">返回</Button></Link>
+          </div>
+        </Row>
+        </Row>
+          <img src={ domain+"api/workflow/image?processDefinitionId=" + this.props.location.state.id }
+                                style={{  border: "1px solid #999" }}/>
+        </Card>
+      </Layout>
+    )
+  }
+}
diff --git a/src/module/huge-base/AppServiceDetail.jsx b/src/module/huge-base/AppServiceDetail.jsx
new file mode 100644
index 0000000..79e9898
--- /dev/null
+++ b/src/module/huge-base/AppServiceDetail.jsx
@@ -0,0 +1,143 @@
+import React from 'react';
+import { Card, Row, Col, Form, Input, Button, message, Spin } from 'antd';
+import { createHashHistory } from 'history';
+import fetch from '../../api/request';
+
+const history = createHashHistory();
+const FormItem = Form.Item;
+const { TextArea } = Input;
+
+class AppServiceDeatil extends React.Component {
+  constructor(props) {
+    super(props)
+    this.id = props.match.params.id == 'new' ? '' : props.match.params.id;
+    this.flag = props.match.params.flag == 'Modify' ? '修改' : '新增';
+
+    this.state = {
+      spinning: false,//页面loading
+      dataSet: {}
+    }
+  }
+
+  componentWillMount() { }
+
+  //获取应用服务详情
+  componentDidMount() {
+    if (this.id !== '') {
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/app/getById`,
+        params: { id: this.id }
+      }).then(res => {
+        this.setState({ loading: false });
+        if (res) {
+          this.setState({ dataSet: res, spinning: false });
+        }
+      })
+    }
+  }
+
+  // 提交表单数据(保存)
+  handleSubmit = (e) => {
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      if (err) return;
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/app/save`,
+        method: 'POST',
+        data: { ...values, id: this.id }
+      }).then(res => {
+        this.setState({ spinning: false });
+        if (res) {
+          message.success('保存成功');
+          history.goBack();//返回至列表页面
+        }
+      })
+    })
+  }
+
+  //返回上一个页面
+  onBack = () => {
+    history.goBack();
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const { dataSet } = this.state;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+
+    return (
+      <div className="appservicedetail-main h-100 margin padding bg-white">
+        <Spin spinning={this.state.spinning}>
+          <div>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title={this.id ? '应用服务信息编辑' : '应用服务信息新增'} bordered={false}
+                extra={<Row type="flex" gutter={20}>
+                  <Col>
+                    <Button onClick={this.onBack}>返回</Button>
+                  </Col>
+                  <Col>
+                    <Button type="primary" htmlType="submit">确定</Button>
+                  </Col>
+                </Row>}
+              >
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"名称"} {...formItemLayout}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '请输入名称' }],
+                        initialValue: dataSet.name || ''
+                      })(
+                        <Input placeholder="请输入描述" rows={5} />
+                      )}
+                    </FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"根路径"} {...formItemLayout}>
+                      {getFieldDecorator('rootUrl', {
+                        rules: [{ required: true, message: '请输入根路径' }],
+                        initialValue: dataSet.rootUrl || '',
+                      })(
+                        <Input placeholder="请输入根路径" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"标识符"} {...formItemLayout}>
+                      {getFieldDecorator('symbol', {
+                        rules: [{ required: true, message: '请输入标识符' }],
+                        initialValue: dataSet.symbol || '',
+                      })(
+                        <Input placeholder="请输入标识符" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"描述"} {...formItemLayout}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description || ''
+                      })(
+                        <TextArea placeholder="请输入描述" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+const AppServiceDeatilForm = Form.create()(AppServiceDeatil);
+export default AppServiceDeatilForm;
\ No newline at end of file
diff --git a/src/module/huge-base/AppServiceManage.jsx b/src/module/huge-base/AppServiceManage.jsx
new file mode 100644
index 0000000..450ebf1
--- /dev/null
+++ b/src/module/huge-base/AppServiceManage.jsx
@@ -0,0 +1,113 @@
+/* eslint-disable */
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Icon, Form, Input, Button, Select, Table, DatePicker, message, Breadcrumb, Layout, Popconfirm, Divider, Modal } from 'antd';
+import TableView from '../../components/common/TableView';
+import SearchFormView from '../../components/common/SearchFormView';
+import moment from 'moment';
+import fetch from '../../api/request';
+
+const FormItem = Form.Item;
+const confirm = Modal.confirm;
+
+
+export default class AppServiceManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      },
+    };
+  }
+
+  componentDidMount() { }
+
+  setFormData = data => {
+    this.setState({
+      formData: data,
+    });
+  }
+
+  //添加应用
+  add = () => {
+    this.props.history.push('/resourceMgt/appService/Detail/new/Add')
+  }
+
+  //删除应用
+  delete = (id) => {
+    let _this = this;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该应用吗?</span>,
+      onOk() {
+        fetch({
+          url: `api/function/delete`,
+          params: { ids: id }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.setState({
+              formData: {
+                ..._this.state.formData,
+                __key: Date.now()
+              }
+            })
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  //表格列显示
+  renderColumns = () => {
+    return [
+      { title: '名称', className: "txt-c", dataIndex: 'name', key: 'name' },
+      { title: '根路径', className: "txt-c", dataIndex: 'rootUrl', key: 'rootUrl' },
+      { title: '标识符', className: "txt-c", dataIndex: 'symbol', key: '' },
+      { title: '创建时间', className: "txt-c", dataIndex: 'updateTime', key: 'updateTime', render: (text, record) => text !== "" && text != null ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      {
+        title: '操作', className: "txt-c", key: 'operation', render: (text, record) => {
+          return <div>
+            <Link to={{ pathname: "/resourceMgt/appService/Detail/" + record.id + '/Modify', state: { id: record.id } }}>修改</Link>
+            <span>&nbsp;|&nbsp;</span>
+            <a onClick={() => this.delete(record.id)}>删除</a>
+          </div>
+        }
+      }
+    ]
+  }
+  render() {
+    const { formData, userSyncLoading } = this.state;
+    let tableParams = {
+      url: `api/app/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {},
+      setFormData: this.setFormData
+    }
+
+    return (
+      <div className="appservicemanage-main h-100 margin padding bg-white">
+        <SearchFormView
+          formData={formData}
+          setFormData={this.setFormData}
+          data={[
+            { type: 'input', name: '名称', label: '名称', key: 'name' },
+            { type: 'input', name: '标识符', label: '标识符', key: 'symbol' },
+          ]} />
+        <Row type="flex" className="margin-bottom">
+          <Col>
+            <Button type="primary" onClick={this.add}>新增</Button>
+          </Col>
+        </Row>
+        <TableView {...tableParams} />
+      </div>
+    )
+  }
+
+
+}
diff --git a/src/module/huge-base/AuthorityManage.jsx b/src/module/huge-base/AuthorityManage.jsx
new file mode 100644
index 0000000..d42204d
--- /dev/null
+++ b/src/module/huge-base/AuthorityManage.jsx
@@ -0,0 +1,267 @@
+import React from 'react';
+import { Card, Row, Col, Icon, Form, Input, Button, Table, DatePicker, message, Breadcrumb, Tree, Modal, Layout, Popconfirm, List, Spin, Empty } from 'antd';
+import SearchTree from '../../components/common/Tree';
+import fetch from '../../api/request';
+
+const Search = Input.Search;
+const confirm = Modal.confirm;
+
+class ResourceManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      spinning: false,
+      resourceList: [],
+      treeKey: 'init',
+      expandedKeys: [],
+      treeData: [],
+      edit: 'false',
+      rightShow: false,
+      dataSet: {},
+      currentNode: [],
+
+      roleList: [],  //角色列表
+      resourceIds: [],  //资源集合
+      treeCheckArr: [],
+      roleId: '',
+      checkedKeys: [],
+
+      leftRoleLoading: false,//左侧角色列表loading
+      rightTreeRightLoading: false,//右侧角色对应菜单权限loading
+
+    };
+  }
+
+  componentDidMount() {
+    this.findRoles();
+    this.getAllFunctionsByTree();
+  }
+
+  //取消按钮
+  cancelFun = () => {
+    this.setState({
+      edit: 'false',
+      rightShow: false,
+      roleId: ''
+    })
+  }
+
+  //所有角色列表
+  findRoles = () => {
+    this.setState({ leftRoleLoading: true });
+    fetch({
+      url: `api/role/finds`
+    }).then(res => {
+      this.setState({ leftRoleLoading: false });
+      if (res) {
+        this.setState({ roleList: res });
+      }
+    })
+  }
+
+  //加载所有应用菜单树形结构
+  getAllFunctionsByTree = () => {
+    this.setState({ rightTreeRightLoading: true });
+    fetch({
+      url: `api/function/getAllFunctionsByTree`,
+    }).then(res => {
+      this.setState({ rightTreeRightLoading: false });
+      if (res) {
+        for (let i = 0; i < res.length; i++) {
+          res[i].resourceType = 1;
+        }
+        res = this.handleTreeData(res);
+        this.setState({ treeData: res })
+      }
+    })
+  }
+
+  //通过角色id查询对应角色的菜单权限
+  getResourcesByRoleId = (id) => {
+    this.setState({ rightTreeRightLoading: true });
+    fetch({
+      url: `api/role/getResourcesByRoleId`,
+      params: { roleId: id }
+    }).then(res => {
+      this.setState({ rightTreeRightLoading: false });
+      console.log('res', res);
+      if (res) {
+        this.setState({
+          checkedKeys: res.map(({ id }) => id),
+          treeCheckArr: res
+        })
+      }
+    })
+  }
+
+  //处理树形数据结构
+  handleTreeData = data => {
+    for (let i = 0; i < data.length; i++) {
+      const node = data[i];
+      node.key = node.id;
+      node.title = node.name;
+      if (data[i].modules) {
+        data[i].children = data[i].modules;
+        this.handleTreeData(node.children);
+      }
+      if (data[i].children) {
+        this.handleTreeData(node.children);
+      }
+      if (data[i].functions) {
+        data[i].children = data[i].functions;
+        this.handleTreeData(node.children);
+      }
+    }
+    return data;
+  };
+
+
+  treeSelect = (tableData, currentNode) => {
+    console.log(tableData, currentNode);
+    // 点击任意节点都可以查看、编辑、添加
+    this.setState({
+      rightShow: true
+    })
+    this.setState({
+      leafNodes: tableData,
+      currentNode
+    })
+  };
+
+  currentTreeCheck = (treeCheckArr) => {
+    this.setState({
+      treeCheckArr
+    })
+  }
+
+  onExpand = (expandedKeys) => {
+    this.setState({
+      expandedKeys,
+    });
+  }
+
+  //选中角色
+  selectRole = (e) => {
+    let roleId = e.target.getAttribute("data-roleid");
+    console.log(roleId)
+    this.setState({
+      rightShow: true,
+      roleId,
+      spinning: true
+    }, () => {
+      this.getResourcesByRoleId(this.state.roleId);//查询角色权限
+    })
+  }
+
+  onCheck = (checkedKeys, checkedNodes) => {
+    console.log('checkedNodes', checkedNodes);
+    this.setState({
+      checkedKeys
+    })
+  }
+
+  saveFun = () => {
+    const { treeCheckArr, roleId, funs } = this.state;
+    let resourceIds = [];
+
+    console.log(resourceIds, treeCheckArr);
+    this.setState({ rightTreeRightLoading: true });
+    fetch({
+      url: `api/role/auth`,
+      method: 'POST',
+      data: {
+        roleId,
+        resourceIds: treeCheckArr.map(({ id, resourceType }) => ({ resourceId: id, resourceType }))
+      }
+    }).then(res => {
+      this.setState({ rightTreeRightLoading: false });
+      if (res) {
+        message.success('配置保存成功');
+      }
+    })
+  }
+
+  render() {
+    const { rightShow, treeData, roleList, roleId, leftRoleLoading, rightTreeRightLoading } = this.state;
+
+    return (
+      <div className="authormanage-main h-100 margin padding bg-white">
+
+        <div className="padding h-100" >
+          <Row style={{ height: '100%' }} >
+            <Col span={8} style={{ border: "1px solid #e8e8e8", padding: 10 }} className="h-100">
+              <Spin spinning={leftRoleLoading}>
+                <Row style={{ marginTop: 10 }} >
+
+                  {
+                    roleList.map((item, idx) => {
+                      return (
+                        roleId == item.id ?
+                          <div key={item.id} data-roleid={item.id} onClick={this.selectRole} style={{ border: "1px solid #e8e8e8", padding: 8, textAlign: 'center', cursor: 'pointer' }} className="ant-btn-primary ant-menu-submenu-selected">
+                            {item.name}
+                          </div> :
+                          <div key={item.id} data-roleid={item.id} onClick={this.selectRole} style={{ border: "1px solid #e8e8e8", padding: 8, textAlign: 'center', cursor: 'pointer' }}>
+                            {item.name}
+                          </div>
+                      )
+                    })
+                  }
+                </Row>
+              </Spin>
+            </Col>
+            <Col span={1}></Col>
+            <Col span={15} style={{ border: "1px solid #e8e8e8" }} className="h-100">
+              {rightShow &&
+                <div className="h-100">
+                  <Spin spinning={rightTreeRightLoading} height={'100%'}>
+                    <div>
+                      <Form>
+                        <Card title={'模块权限配置'} bordered={false} extra={
+                          <Row type="flex" gutter={20}>
+                            <Col>
+                              <Button onClick={this.cancelFun}>取消</Button>
+                            </Col>
+                            <Col>
+                              <Button className="button-do" htmlType="submit" onClick={this.saveFun} type="primary">保存</Button>
+                            </Col>
+                          </Row>
+                        }>
+                          {/* 此处的key用于控制滚动条的位置 */}
+                          <div style={{ height: '65vh', overflow: 'auto' }} key={roleId}>
+                            <SearchTree
+                              data={treeData}
+                              onExpand={this.onExpand}
+                              expandedKeys={this.state.expandedKeys}
+                              treeSelect={this.treeSelect}
+                              showSearch={false}
+                              checkable={true}
+                              defaultExpandAll={true}
+                              currentTreeCheck={this.currentTreeCheck}
+                              checkedKeys={this.state.checkedKeys}
+                              onCheck={this.onCheck}
+                            />
+                          </div>
+                        </Card>
+                      </Form>
+                    </div>
+                  </Spin>
+                </div>
+              }
+              {
+                !rightShow &&
+                <Empty description={'暂无数据,请点击左侧树形结构'} className="h-100 flex-box-column align-center justify-content" />
+              }
+            </Col>
+          </Row>
+          <Row>
+          </Row>
+        </div>
+      </div>
+    )
+  }
+}
+
+
+
+const ResourceManageList = Form.create()(ResourceManage);
+export default ResourceManageList;
\ No newline at end of file
diff --git a/src/module/huge-base/DepartmentManage.jsx b/src/module/huge-base/DepartmentManage.jsx
new file mode 100644
index 0000000..9a37d84
--- /dev/null
+++ b/src/module/huge-base/DepartmentManage.jsx
@@ -0,0 +1,316 @@
+/* eslint-disable */
+import React from "react";
+import { Row, Col, Form, Button, message, Modal, Popconfirm, Empty, Spin } from "antd";
+import moment from "moment";
+import SearchTree from '../../components/common/Tree';
+import SearchFormView from '../../components/common/SearchFormView';
+import TableView from '../../components/common/TableView';
+import fetch from '../../api/request';
+import DeptDetail from './DeptDetail';//部门详情
+
+const FormItem = Form.Item;
+const confirm = Modal.confirm;
+
+export default class DepartmentManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      treeKey: "init",
+      expandedKeys: [],
+      tableData: [],
+      totalElements: 1,
+      pageSize: 10,
+      page: 1,
+
+      treeData: [],
+      leafNodes: [],
+      currentNode: [],
+      rightShow: false,
+      modify: false,
+      parentId: '',
+      id: '',
+      dataSet: {},
+      selectedKeys: [],
+      treeLoading: false,//左侧树结构loading
+      loading: false,//部门详情的loading
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      }
+
+    };
+  }
+  componentDidMount() {
+    this.loadData();
+  }
+
+  //加载左侧树形数据
+  loadData = () => {
+    this.setState({
+      treeLoading: true
+    })
+    fetch({
+      url: `api/unit/getAllUnitsByCascade`
+    }).then(res => {
+      this.setState({ treeLoading: false })
+      res = this.handleTreeData(res);
+      if (res) {
+        this.setState({
+          treeData: res,//树形数据
+          treeKey: Date.now()
+        })
+      }
+    })
+  };
+
+  //处理树形数据
+  handleTreeData = data => {
+    for (let i = 0; i < data.length; i++) {
+      const node = data[i];
+      node.key = node.id;
+      node.title = node.name;
+      if (data[i].children) {
+        this.handleTreeData(node.children);
+      }
+    }
+    return data;
+  };
+
+  //点击树形结构节点
+  treeSelect = (tableData, currentNode) => {
+    // if (currentNode[0].children && currentNode[0].children.length > 0) {
+    //   _this.setState({
+    //     rightShow: false
+    //   })
+    //   message.error("请选择下级的节点");
+    //   return;
+    // } else {
+    //   message.success("已选择" + currentNode[0].name)
+    // }
+    message.success("已选择:" + currentNode[0].name)
+    this.setState({
+      leafNodes: tableData,
+      currentNode,
+      unitLocation: currentNode[0].name,
+      parentId: currentNode[0].parentId,
+      selectedKeys: [currentNode[0].id]
+    }, () => {
+      this.loadTableData()
+    })
+  };
+
+  //加载右侧table表格数据
+  loadTableData = () => {
+    let { formData, currentNode } = this.state;
+    this.setState({
+      rightShow: true,
+      formData: {
+        ...formData,
+        __key: Date.now(),
+        unitId: currentNode[0].id
+      }
+    })
+  }
+
+  //点击table修改|新增按钮
+  modifyFun = (id) => {
+    this.setState({
+      modify: true,
+      id,
+      dataSet: {}
+    })
+    if (id !== '') {
+      this.setState({ loading: true });
+      fetch({
+        url: `api/dept/getById`,
+        params: { id }
+      }).then(res => {
+        this.setState({ loading: false });
+        if (res) {
+          this.setState({ dataSet: res })
+        }
+      })
+    }
+  }
+
+  // 部门 新增|编辑 函数
+  saveFun = (obj) => {
+    let { formData } = this.state;
+    this.setState({ loading: true });
+    fetch({
+      url: `api/dept/save`,
+      method: 'POST',
+      data: obj
+    }).then(res => {
+      this.setState({ loading: false });
+      if (res) {
+        message.success('保存部门成功');
+        this.setState({
+          modify: false,
+          formData: {
+            ...formData,
+            __key: Date.now()
+          }
+        });
+      }
+    })
+  }
+
+  //删除单位
+  delete = (id) => {
+    let _this = this;
+    let { formData } = _this.state;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该部门吗?</span>,
+      onOk() {
+        fetch({
+          url: `api/dept/delete`,
+          params: { ids: id }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.setState({
+              formData: {
+                ...formData,
+                __key: Date.now()
+              }
+            });
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  clearKeys = () => {
+    this.setState({
+      currentNode: [],
+      rightShow: false,
+    })
+  }
+
+  cancelFun = () => {
+    this.setState({
+      modify: false
+    })
+  }
+
+  onExpand = expandedKeys => {
+    this.setState({
+      expandedKeys
+    });
+    this.setState({
+      treeKey: Date.now()
+    });
+  };
+
+  onSelect = (selectedKeys) => {
+    this.setState({
+      selectedKeys
+    })
+  }
+
+  setFormData = data => {
+    this.setState({
+      formData: data,
+    });
+  }
+
+  renderColumns = () => {
+    return [
+      { title: "部门名称", dataIndex: "name" },
+      { title: "描述", dataIndex: "description", ellipsis: true },
+      { title: '创建时间', dataIndex: 'updateTime', key: 'updateTime', render: (text, record) => text !== "" && text != null ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      {
+        title: "操作",
+        key: "operation",
+        render: (text, record) => {
+          return (
+            <div>
+              <a onClick={() => this.modifyFun(record.id)}>修改</a>
+              <span>&nbsp;|&nbsp;</span>
+              <a onClick={() => this.delete(record.id)}>删除</a>
+            </div>
+          );
+        }
+      }
+    ];
+  };
+
+  render() {
+    const { treeKey, treeData, rightShow, treeLoading, formData, currentNode } = this.state;
+
+    const params = {
+      id: this.state.id,
+      currentNode
+    }
+
+    let tableParams = {
+      url: `api/dept/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {
+        unitId: currentNode.length ? currentNode[0].id : ''
+      },
+      setFormData: this.setFormData
+    }
+
+    return (
+      <div className="departmentmanage-main margin padding bg-white h-100">
+        {
+          !this.state.modify &&
+          <React.Fragment>
+            <div className="h-100 padding">
+              <Row style={{ height: "100%" }}>
+                <Col span={8} style={{ border: "1px solid #e8e8e8", padding: 10 }} className="h-100">
+                  <Spin spinning={treeLoading}>
+                    <SearchTree
+                      key={treeKey}
+                      data={treeData}
+                      onExpand={this.onExpand}
+                      expandedKeys={this.state.expandedKeys}
+                      treeSelect={this.treeSelect}
+                      clearKeys={this.clearKeys}
+                      selectedKeys={this.state.selectedKeys}
+                      onSelect={this.onSelect}
+                    />
+                  </Spin>
+                </Col>
+                <Col span={1} />
+                <Col span={15} style={{ border: "1px solid #e8e8e8", padding: 10 }} className="h-100">
+                  {rightShow &&
+                    <div>
+                      <SearchFormView data={[{ type: 'input', name: '部门名称', label: '部门名称', key: 'name' }]} width={'50%'} formData={formData} setFormData={this.setFormData} />
+                      <Row className="margin-bottom">
+                        <Col>
+                          <Button onClick={() => this.modifyFun('')} type="primary" className="button-do">
+                            新增
+                          </Button>
+                        </Col>
+                      </Row>
+                      <TableView {...tableParams} />
+                    </div>
+                  }
+                  {
+                    !rightShow &&
+                    <Empty description={'暂无数据,请点击左侧树形结构'} className="h-100 flex-box-column align-center justify-content" />
+                  }
+                </Col>
+
+              </Row>
+            </div>
+          </React.Fragment>
+        }
+
+        {this.state.modify &&
+          <DeptDetail cancelFun={this.cancelFun} params={params} dataSet={this.state.dataSet} saveFun={this.saveFun} loading={this.state.loading}></DeptDetail>
+        }
+      </div>
+    );
+  }
+
+}
+
+
diff --git a/src/module/huge-base/DeployManage.jsx b/src/module/huge-base/DeployManage.jsx
new file mode 100644
index 0000000..20d8a55
--- /dev/null
+++ b/src/module/huge-base/DeployManage.jsx
@@ -0,0 +1,245 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Icon, Form, Input, Button, Select, Table, DatePicker, message,Breadcrumb,Upload,Modal, Layout } from 'antd';
+import moment from 'moment';
+import Fetch from '../fetch';
+import UploadXML from '../component/upload/index';
+import { deploymentDel } from '../fetch/api';
+
+const FormItem = Form.Item;
+const confirm = Modal.confirm;
+
+class DeployManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      loading: true,
+      name:'',
+      tableData: [],
+      totalElements: 1,
+      pageSize:10,
+      page: 1
+    };
+  }
+  componentDidMount() {
+    this.loadData(1, this.state.pageSize);
+  }
+  render() {
+    const { name } = this.state;
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 10 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 14 }, },
+    };
+    const formItemLayout1 = {
+      labelCol: { xs: { span: 24 }, sm: { span: 8 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 16 }, },
+    };
+    const formMultiItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+    return (
+      <Layout className="h-100 page-table">
+        <Row>
+          <Breadcrumb className="breadcrumb-style">
+            <Breadcrumb.Item>工作流管理</Breadcrumb.Item>
+            <Breadcrumb.Item>流程部署管理</Breadcrumb.Item>
+          </Breadcrumb>
+        </Row>
+        <Card style={{border:20, margin:20, padding:20}}>
+          <Form onSubmit={this.handleSubmit} className="searchForm" layout="inline">
+            <Row>
+              <Col span={7}>
+                <FormItem label="流程名称" {...formItemLayout1}>
+                  {getFieldDecorator('name', {
+                    rules: [{ required: false, whitespace: false }],
+                    initialValue: ''
+                  })(
+                    <Input placeholder="请输入流程名称" />
+                  )}
+                </FormItem>
+              </Col>
+              <Col span={7}>
+              <FormItem {...formItemLayout1}>
+                <span style={{float:'right'}}>
+                  <Button className="search-btn" htmlType="submit" type="primary"><Icon type='search' />查询</Button>
+                  <Button className="search-btn" onClick={this.reset} >重置</Button>
+                </span>
+                </FormItem>
+              </Col>
+            </Row>
+            </Form>
+            <Row>
+            </Row>
+            <Row>
+              <Col span={7}>
+              <FormItem>
+                <UploadXML action={ "api/workflow/deploy"} ifSuccess={this.ifSuccess}/>
+                </FormItem>
+              </Col>
+            </Row>
+          <Row>
+            <Table
+              className="rowColor"
+              size="middle"
+              dataSource={this.state.tableData}
+              loading={{spinning: this.state.loading}}
+              columns={this.getColumns()}
+              pagination={{
+                pageSize: this.state.pageSize,
+                onChange: this.pageChange,
+                total: this.state.totalElements,
+                showSizeChanger:true,
+                onShowSizeChange:this.onShowSizeChange,
+                showTotal:(total, range) => `共${total}条记录 `,
+                itemRender: this.itemRender,
+                showQuickJumper: true,
+                defaultCurrent: 1,
+                current: this.state.page
+              }}
+            />
+          </Row>
+        </Card>
+      </Layout>
+    )
+  }
+  
+  itemRender = (current, type, originalElement) => {
+    if (type === 'prev') {
+      return <a>上一页&nbsp;</a>;
+    } else if (type === 'next') {
+      return <a>&nbsp;下一页</a>;
+    }
+    return originalElement;
+  }
+  ifSuccess = result => {
+    result&&this.loadData(1,this.state.pageSize)
+  }
+  getColumns = () => {
+    let obj = this;
+    return [
+      { title: '流程KEY', className: "txt-c", dataIndex: '_key'},
+      { title: '流程名称', className: "txt-c", dataIndex: 'name' },
+      { title: '当前状态', className: "txt-c", dataIndex: 'status', render:(text,record) =>text?"运行":"挂起" },
+      { title: '流程版本', className: "txt-c", dataIndex: 'version' },
+      { title: '创建时间', className: "txt-c", dataIndex: 'createTime', key: 'createTime', render: (text, record) => text !== "" && text != null ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      { title: '操作', className: "txt-c", key: 'operation', render: (text, record) => {
+          return <div>
+            <a onClick={()=>this.delete(record.deploymentId)}>删除</a>
+            <span>&nbsp;|&nbsp;</span>
+            <Link to={{ pathname: "/activitiManage/activitiImg", state: { id: record.id} }}>流程图</Link>
+            <span>&nbsp;|&nbsp;</span>
+            <Link to={{ pathname: "/activitiManage/activitiDetail", state: { deploymentId: record.id} }}>其他版本</Link>
+          </div>
+        }
+      }
+    ]
+  }
+
+  delete = deploymentId => {
+    let _this= this
+    confirm({
+      title: <span style={{fontSize:19}}>警告</span>,
+      content: <span style={{fontSize:18}}>确定删除吗</span>,
+      onOk() {
+        deploymentDel(deploymentId).then( res => {
+          if(res.code == 0) {
+            message.success("删除成功");
+            _this.loadData(1,_this.state.pageSize)
+          }else{
+            message.error(res.msg);
+          }
+        })
+      },
+      onCancel() {},
+    });
+  }
+  reset = () =>{
+    this.props.form.setFieldsValue({
+      name:'',
+    });
+    this.loadData(1, this.state.pageSize)
+  }
+  handleSubmit = (e) => {
+    e.preventDefault();
+    this.loadData(1, this.state.pageSize);
+  }
+  onShowSizeChange = (current, pageSize) =>{
+    this.setState({pageSize, page: 1})
+    this.loadData(1, pageSize);
+  }
+  pageChange = (page, pageSize) => {
+    this.loadData(page, pageSize);
+  }
+  loadData = (page, pageSize) => {
+    let _this = this;
+    _this.props.form.validateFields((err, values) => {
+      if (err) return;
+      _this.setState({ loading: true });
+      let obj = {
+        key:values.key,
+        page: page,
+        pageSize: pageSize,
+      };
+      // let promise = Get("/workflow/definition/listProcessDefinitionByPage?number=" + obj.page + "&size=" + obj.pageSize + "&key=" + obj.key);
+      // promise.then(reson => {
+      //   let tmpArr = [];
+      //   reson.data.content.map(e => {
+      //     let obj = {
+      //       key: e.id,
+      //       _key:e.key, 
+      //       id:e.id,
+      //       version:e.version,
+      //       status:e.status,
+      //       name: e.name,
+      //       deploymentId:e.deploymentId,
+      //     }
+      //     tmpArr.push(obj)
+      //   })
+
+      //   this.setState({
+      //     tableData: tmpArr,
+      //     totalElements: reson.data.totalElements,
+      //     loading: false,
+      //   });
+      // }).catch(err => {
+      //   this.setState({ loading: false });
+      //   message.error("数据加载失败,请稍后再试");
+      //   console.log(err.toString());
+      // });
+
+      Fetch.getProcessDefinition({
+        ...values,
+        page: page,
+        size: pageSize
+      })
+      .then(res => {
+        let tmpArr = [];
+        res.map(e => {
+          let obj = {
+            key: e.id,
+            _key:e.key, 
+            id:e.id,
+            version:e.version,
+            status:e.status,
+            name: e.name,
+            deploymentId:e.deploymentId,
+            createTime: e.createTime
+          }
+          tmpArr.push(obj)
+        })
+        this.setState({
+          tableData: tmpArr,
+          loading: false,
+          page,
+          totalElements: res.totalElements,
+        });
+      });
+      
+    });
+  }
+}
+const header={"content-type":"multipart/form-data"}
+const DeployManageList = Form.create()(DeployManage);
+export default DeployManageList;
\ No newline at end of file
diff --git a/src/module/huge-base/DeptDetail.jsx b/src/module/huge-base/DeptDetail.jsx
new file mode 100644
index 0000000..aeba659
--- /dev/null
+++ b/src/module/huge-base/DeptDetail.jsx
@@ -0,0 +1,99 @@
+/* eslint-disable */
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Form, Input, Button, Select, Spin } from 'antd';
+import fetch from '../../api/request'
+
+const FormItem = Form.Item;
+const { TextArea } = Input;
+
+
+class DeptDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+      spinning: true,
+      id: "",
+      dataSet: {}
+    }
+  }
+
+  componentDidMount() { }
+
+  handleSubmit = (e) => { // 提交表单数据
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      if (err) return;
+      let obj = {
+        ...values,
+        id: this.props.params.id,//部门id
+        unitId: this.props.params.currentNode[0].id//单位编号
+      }
+      //触发父级函数,调用保存接口
+      this.props.saveFun(obj)
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const { params, dataSet } = this.props;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+
+    return (
+      <div className="deptdetail-main h-100">
+        <Spin spinning={this.props.loading}>
+          <div>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title={params.id == '' ? '部门新增' : '部门编辑'} bordered={false}
+                extra={<Row type="flex" gutter={20}>
+                  <Col>
+                    <Button onClick={this.props.cancelFun}>返回</Button>
+                  </Col>
+                  <Col>
+                    <Button type="primary" htmlType="submit" >确认</Button>
+                  </Col>
+                </Row>}
+              >
+                <Row type="flex" >
+                  <Col span={14}>
+                    <FormItem label={"单位"} {...formItemLayout}>
+                      <span>{params.currentNode[0].name}</span>
+                    </FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex" >
+                  <Col span={14}>
+                    <FormItem label={"部门名称"} {...formItemLayout}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '请输入部门名称' }],
+                        initialValue: dataSet.name || '',
+                      })(
+                        <Input placeholder="请输入部门名称" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex" >
+                  <Col span={14}>
+                    <FormItem label={"描述"} {...formItemLayout}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description
+                      })(
+                        <TextArea placeholder="请输入描述" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+const DeptDetailForm = Form.create()(DeptDetail);
+export default DeptDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/FunctionDetail.jsx b/src/module/huge-base/FunctionDetail.jsx
new file mode 100644
index 0000000..d60060b
--- /dev/null
+++ b/src/module/huge-base/FunctionDetail.jsx
@@ -0,0 +1,104 @@
+import React from 'react';
+import { Card, Row, Col, Form, Input, Button, Spin } from 'antd';
+
+const FormItem = Form.Item;
+const { TextArea } = Input;
+
+class FunctionDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+      dataSet: {}
+    }
+  }
+
+  handleSubmit = (e) => { // 提交表单数据
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      console.log('提交表单数据:', values);
+      if (err) return;
+      let obj = {
+        ...values,
+        id: this.props.params.id,  //编号
+        moduleId: this.props.params.currentNode[0].id  //模块编号
+      }
+      this.props.saveFun(obj);
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const { params, dataSet } = this.props;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+
+    return (
+      <div className="functiondetail-main">
+        <Spin spinning={this.props.loading}>
+          <div style={{ margin: 20 }}>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title={params.id ? '功能信息(编辑)' : '功能信息(新增)'} bordered={false}
+                extra={
+                  <Row type="flex" gutter={20}>
+                    <Col>
+                      <Button onClick={this.props.cancelFun}>返回</Button>
+                    </Col>
+                    <Col>
+                      <Button type="primary" htmlType="submit">确认</Button>
+                    </Col>
+                  </Row>
+                }
+              >
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"模块名称"} {...formItemLayout}>
+                      <span>{this.props.params.currentNode[0].name}</span>
+                    </FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"标识符"} {...formItemLayout}>
+                      {getFieldDecorator('symbol', {
+                        rules: [{ required: true, message: '请输入标识符' }],
+                        initialValue: dataSet.symbol || '',
+                      })(
+                        <Input placeholder="请输入标识符" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"功能名称"} {...formItemLayout}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '请输入功能名称' }],
+                        initialValue: dataSet.name || '',
+                      })(
+                        <Input placeholder="请输入功能名称" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={14}>
+                    <FormItem label={"描述"} {...formItemLayout}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description
+                      })(
+                        <TextArea placeholder="请输入描述" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+const FunctionDetailForm = Form.create()(FunctionDetail);
+export default FunctionDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/FunctionManage.jsx b/src/module/huge-base/FunctionManage.jsx
new file mode 100644
index 0000000..e913c5d
--- /dev/null
+++ b/src/module/huge-base/FunctionManage.jsx
@@ -0,0 +1,327 @@
+import React from "react";
+import { Link } from "react-router-dom";
+import { Card, Row, Col, Icon, Form, message, Tree, Modal, Layout, Popconfirm, Divider, Spin, Button, Empty } from "antd";
+import moment from "moment";
+import SearchTree from '../../components/common/Tree';
+import SearchFormView from '../../components/common/SearchFormView';
+import TableView from '../../components/common/TableView';
+import FunctionDetail from './FunctionDetail';//功能详情
+import fetch from '../../api/request';
+
+const FormItem = Form.Item;
+const confirm = Modal.confirm;
+const TreeNode = Tree.TreeNode;
+
+class FunctionManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      resourceList: [],
+      treeKey: Date.now(),
+      expandedKeys: [],
+      tableData: [],
+      totalElements: 1,
+      pageSize: 10,
+      page: 1,
+
+      treeData: [],
+      leafNodes: [],
+      currentNode: [],
+      rightShow: false,
+      modify: false,
+      parentId: "",
+      id: "",
+      dataSet: {},
+      selectedKeys: [],
+      treeLoading: false,//左侧树结构loading
+      loading: false,//部门详情的loading
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      }
+    };
+  }
+  componentDidMount() {
+    this.loadData();
+  }
+
+  //加载左侧树形数据
+  loadData = () => {
+    this.setState({ treeLoading: true });
+    fetch({
+      url: `api/module/getAllModulesByTree`
+    }).then(res => {
+      this.setState({ treeLoading: false });
+      if (res) {
+        res = this.handleTreeData(res);
+        this.setState({ treeData: res, treeKey: Date.now() })
+      }
+    })
+  };
+
+  //处理树形数据结构
+  handleTreeData = data => {
+    for (let i = 0; i < data.length; i++) {
+      const node = data[i];
+      node.key = node.id;
+      node.title = node.name;
+      if (data[i].modules) {
+        data[i].children = data[i].modules;
+        this.handleTreeData(node.children);
+      }
+      if (data[i].children) {
+        this.handleTreeData(node.children);
+      }
+      // else{
+      //   this.handleTreeData([node])
+      // }
+    }
+    return data;
+  };
+
+  //点击树形节点触发函数
+  treeSelect = (tableData, currentNode) => {
+    console.log(tableData, currentNode);
+    if (currentNode[0].children && currentNode[0].children.length > 0) {
+      message.error("请选择下级的节点");
+      this.setState({
+        rightShow: false
+      });
+      return;
+    } else {
+      message.success("已选择:" + currentNode[0].name);
+    }
+    this.setState(
+      {
+        leafNodes: tableData,
+        currentNode,
+        unitLocation: currentNode[0].name,
+        parentId: currentNode[0].parentId,
+        selectedKeys: [currentNode[0].id]
+      },
+      () => {
+        this.loadTableData();
+      }
+    );
+  };
+
+  //加载右侧table表格数据
+  loadTableData = () => {
+    const { currentNode, formData } = this.state;
+    if (currentNode[0].length < 0) {
+      message.error("请选择左边节点后进行查询操作");
+      return;
+    }
+    this.setState({
+      rightShow: true,
+      formData: {
+        ...formData,
+        __key: Date.now(),
+        moduleId: currentNode[0].id
+      }
+    })
+  };
+
+  //功能(新增 | 编辑),详情接口
+  modifyFun = id => {
+    this.setState({
+      modify: true,
+      id,
+      dataSet: {}
+    });
+    if (id) {
+      this.setState({ loading: true });
+      fetch({
+        url: `api/function/getById`,
+        params: { id }
+      }).then(res => {
+        this.setState({ loading: false });
+        if (res) {
+          this.setState({ dataSet: res })
+        }
+      })
+    }
+  };
+
+  clearKeys = () => {
+    let _this = this;
+    _this.setState({
+      currentNode: [],
+      rightShow: false
+    });
+  };
+
+  cancelFun = () => {
+    this.setState({
+      modify: false
+    });
+  };
+
+  //保存表单(确定按钮)
+  saveFun = data => {
+    this.setState({ loading: true });
+    fetch({
+      url: `api/function/save`,
+      method: 'POST',
+      data
+    }).then(res => {
+      this.setState({ loading: false });
+      if (res) {
+        message.success("保存功能成功");
+        this.setState({ modify: false });
+        this.loadTableData();//重新加载表格table数据
+      }
+    })
+  };
+
+  onExpand = expandedKeys => {
+    this.setState({
+      expandedKeys
+    });
+  };
+
+  onSelect = selectedKeys => {
+    this.setState({
+      selectedKeys
+    });
+  };
+
+  //删除功能
+  delete = id => {
+    let _this = this;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该功能吗?</span>,
+      onOk() {
+        fetch({
+          url: `api/function/delete`,
+          params: { ids: id }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.loadTableData();
+          }
+        })
+      },
+      onCancel() { }
+    });
+  };
+
+  setFormData = data => {
+    console.log('form', data);
+    this.setState({
+      formData: data,
+    });
+  }
+
+  renderColumns = () => {
+    return [
+      { title: "功能名称", dataIndex: "name" },
+      { title: "标识符", dataIndex: "symbol", ellipsis: true },
+      { title: "功能描述", dataIndex: "description", ellipsis: true },
+      { title: "创建时间", dataIndex: "updateTime", render: (text, record) => (text && moment(text).format("YYYY-MM-DD HH:mm")) },
+      {
+        title: "操作", key: "operation", render: (text, record) => {
+          return (
+            <div>
+              <a onClick={() => this.modifyFun(record.id)}>修改</a>
+              <Divider type="vertical" />
+              <a onClick={() => this.delete(record.id)}>删除</a>
+            </div>
+          );
+        }
+      }
+    ];
+  };
+
+  render() {
+    const { treeKey, treeData, rightShow, treeLoading, formData, currentNode } = this.state;
+
+    const params = {
+      id: this.state.id,
+      currentNode
+    };
+
+    let tableParams = {
+      url: `api/function/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {
+        moduleId: currentNode.length ? currentNode[0].id : ''
+      },
+      setFormData: this.setFormData
+    }
+
+    return (
+      <div className="functionmanage-main h-100 padding margin bg-white">
+        {!this.state.modify && (
+          <React.Fragment>
+            <div className="padding h-100">
+              <Row style={{ height: "100%" }}>
+                <Col
+                  span={8}
+                  style={{ border: "1px solid #e8e8e8", padding: 10 }}
+                  className="h-100"
+                >
+                  <Spin spinning={treeLoading}>
+                    <SearchTree
+                      key={treeKey}
+                      data={treeData}
+                      onExpand={this.onExpand}
+                      expandedKeys={this.state.expandedKeys}
+                      treeSelect={this.treeSelect}
+                      clearKeys={this.clearKeys}
+                      onSelect={this.onSelect}
+                      selectedKeys={this.state.selectedKeys}
+                    />
+                  </Spin>
+                </Col>
+                <Col span={1} />
+                <Col
+                  span={15}
+                  style={{ border: "1px solid #e8e8e8", padding: 10 }}
+                  className="h-100"
+                >
+                  {
+                    rightShow && (
+                      <div>
+                        <SearchFormView data={[{ type: 'input', name: '功能名称', label: '功能名称', key: 'name' }]} width={'50%'} formData={formData} setFormData={this.setFormData} width={'50%'}/>
+                        <Row className="margin-bottom">
+                          <Col>
+                            <Button onClick={() => this.modifyFun('')} type="primary" className="button-do">
+                              新增
+                          </Button>
+                          </Col>
+                        </Row>
+                        <TableView {...tableParams} />
+                      </div>
+                    )}
+                  {
+                    !rightShow && (
+                      <Empty description={'暂无数据,请点击左侧树形结构'} className="h-100 flex-box-column align-center justify-content" />
+                    )}
+                </Col>
+              </Row>
+            </div>
+          </React.Fragment>
+        )}
+
+        {this.state.modify && (
+          <FunctionDetail
+            cancelFun={this.cancelFun}
+            params={params}
+            dataSet={this.state.dataSet}
+            saveFun={this.saveFun}
+            loading={this.state.loading}
+          />
+        )}
+      </div>
+    );
+  }
+
+
+}
+
+const FunctionManageList = Form.create()(FunctionManage);
+export default FunctionManageList;
diff --git a/src/module/huge-base/GroupDetail.jsx b/src/module/huge-base/GroupDetail.jsx
new file mode 100644
index 0000000..0f93c44
--- /dev/null
+++ b/src/module/huge-base/GroupDetail.jsx
@@ -0,0 +1,150 @@
+/* eslint-disable */
+import React from 'react';
+import { Card, Row, Col, Form, Input, Button, Select, message, Spin } from 'antd';
+import { createHashHistory } from 'history'
+import fetch from '../../api/request'
+
+const history = createHashHistory();
+const { TextArea } = Input;
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+class GroupDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.id = props.match.params.id == 'new' ? '' : props.match.params.id;
+    this.flag = props.match.params.flag == 'Modify' ? '修改' : '新增';
+    this.state = {
+      spinning: false,
+      dataSet: {}
+    }
+  }
+
+  componentDidMount() {
+    if (this.id) {
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/group/getById`,
+        params: { id: this.id }
+      }).then(res => {
+        this.setState({ spinning: false });
+        if (res) {
+          this.setState({ dataSet: res });
+        }
+      })
+    }
+  }
+
+  // 返回
+  goBack = () => {
+    history.goBack();
+  }
+
+  // 确定
+  handleSubmit = (e) => {
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      if (err) return;
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/group/save`,
+        method: 'POST',
+        data: {
+          ...this.state.dataSet,
+          ...values
+        }
+      }).then(res => {
+        this.setState({ spinning: false });
+        message.success("保存组成功");
+        history.goBack();
+      })
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const { dataSet } = this.state;
+
+    const formItemLayout1 = {
+      labelCol: { xs: { span: 24 }, sm: { span: 10 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 14 }, },
+    };
+    const formItemLayout2 = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+
+    return (
+      <div className="groupdetail-main margin padding bg-white">
+
+        <Spin spinning={this.state.spinning}>
+          <div style={{ margin: 20 }}>
+            <Form onSubmit={this.handleSubmit}>
+
+              <Card title={this.id ? '基础信息(编辑)' : '基础信息(新增)'} bordered={false} extra={
+                <Row type="flex" gutter={20}>
+                  <Col>
+                    <Button onClick={this.goBack}>返回</Button>
+                  </Col>
+                  <Col>
+                    <Button htmlType="submit" type="primary">确定</Button>
+                  </Col>
+                </Row>
+              }>
+                <Row type="flex">
+                  <Col span={8}>
+                    <FormItem label={"标识符"} {...formItemLayout1}>
+                      {getFieldDecorator('symbol', {
+                        rules: [{ required: true, message: '标识符必填' }],
+                        initialValue: dataSet.symbol || '',
+                      })(
+                        <Input placeholder="请输入标识符" />
+                      )}</FormItem>
+                  </Col>
+                  <Col span={8}>
+                    <FormItem label={"组名称"} {...formItemLayout1}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '组名称必填' }],
+                        initialValue: dataSet.name || ''
+                      })(
+                        <Input placeholder="请输入组名称" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row>
+                  <Col span={8}>
+                    <FormItem label={"组类型"} {...formItemLayout1}>
+                      {getFieldDecorator('groupType', {
+                        rules: [{ required: true, message: '组类型必选' }],
+                        initialValue: dataSet.groupType || undefined
+                      })(
+                        <Select style={{ width: '100%' }} placeholder="请选择" allowClear>
+                          <Option value={1}>用户类型</Option>
+                          <Option value={2}>角色类型</Option>
+                          <Option value={3}>资源类型</Option>
+                        </Select>
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row>
+                  <Col span={16}>
+                    <FormItem label={"描述"} {...formItemLayout2}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description || ''
+                      })(
+                        <TextArea placeholder="请输入描述" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+const GroupDetailForm = Form.create()(GroupDetail);
+export default GroupDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/GroupManage.jsx b/src/module/huge-base/GroupManage.jsx
new file mode 100644
index 0000000..03d8b0b
--- /dev/null
+++ b/src/module/huge-base/GroupManage.jsx
@@ -0,0 +1,121 @@
+/* eslint-disable */
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Row, Col, Icon, Button, message, Modal, Divider } from 'antd';
+import TableView from '../../components/common/TableView';
+import SearchFormView from '../../components/common/SearchFormView';
+import moment from 'moment';
+import fetch from '../../api/request';
+
+const confirm = Modal.confirm;
+
+export default class GroupManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      },
+    };
+  }
+
+  componentDidMount() { }
+
+  setFormData = data => {
+    this.setState({
+      formData: data,
+    });
+  }
+
+  renderColumns = () => {
+    let obj = this;
+    return [
+      { title: '标识符', className: "txt-c", dataIndex: 'symbol' },
+      { title: '组名称', className: "txt-c", dataIndex: 'name' },
+      { title: '组类型', className: "txt-c", dataIndex: 'groupType', render: (text, record) => text == "1" ? "用户类型" : text == "2" ? "角色类型" : text == "3" ? "资源类型" : "" },
+      { title: '描述', className: "txt-c", dataIndex: 'description', render: (text, record) => text == null ? text : (text.length <= 20 ? text : (text.substring(0, 20) + '...')) },
+      { title: '创建时间', className: "txt-c", dataIndex: 'createTime', render: (text, record) => text !== "" && text != null ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      {
+        title: '操作', className: "txt-c", key: 'operation', render: (text, record) => {
+          return <div>
+            <Link to={{ pathname: "/baseManage/group/Detail/" + record.id + '/Modify', query: { id: record.id } }}>修改</Link>
+            <span>&nbsp;|&nbsp;</span>
+            <a onClick={() => this.delete(record.id)}>删除</a>
+          </div>
+        }
+      }
+    ]
+  }
+
+  // 新增组
+  add = () => {
+    this.props.history.push('/baseManage/group/Detail/new/Add')
+  }
+
+  //删除组
+  delete = (id) => {
+    let _this = this
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该组吗?</span>,
+      content: <span style={{ fontSize: 18 }}>删除该组的同时,会删除与该组的所有关系。</span>,
+      onOk() {
+        fetch({
+          url: `api/group/delete`,
+          params: {
+            ids: id
+          }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.setState({
+              formData: {
+                ..._this.state.formData,
+                __key: Date.now()
+              }
+            })
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  render() {
+    const { formData } = this.state;
+    let tableParams = {
+      url: `api/group/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {},
+      setFormData: this.setFormData
+    }
+    return (
+      <div className="groupmanage-main margin padding bg-white">
+        <SearchFormView
+          formData={formData}
+          setFormData={this.setFormData}
+          data={[
+            { type: 'input', name: '标识符', label: '标识符', key: 'symbol' },
+            { type: 'input', name: '组名称', label: '组名称', key: 'name' },
+            {
+              type: 'select', name: '组类型', label: '组类型', key: 'groupType', list: [
+                { name: 0, value: '全部' },
+                { name: 1, value: '用户类型' },
+                { name: 2, value: '角色类型' },
+                { name: 3, value: '资源类型' },
+              ]
+            },
+          ]} />
+        <Row type="flex" gutter={20} className="margin-bottom">
+          <Col>
+            <Button type="primary" onClick={this.add}>新增组</Button>
+          </Col>
+        </Row>
+        <TableView {...tableParams} />
+      </div>
+    )
+  }
+}
diff --git a/src/module/huge-base/HeaderCustom.jsx b/src/module/huge-base/HeaderCustom.jsx
new file mode 100644
index 0000000..0d99d17
--- /dev/null
+++ b/src/module/huge-base/HeaderCustom.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { Layout } from 'antd';
+import data from '../data/menu';
+import HeaderCustom from '../component/HeaderCustom';
+
+export default class Menu extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      collapsed: false
+    }
+  }
+  render() {
+    return (
+      <HeaderCustom />
+    )
+  }
+}
diff --git a/src/module/huge-base/JobDetail.jsx b/src/module/huge-base/JobDetail.jsx
new file mode 100644
index 0000000..f1a6df8
--- /dev/null
+++ b/src/module/huge-base/JobDetail.jsx
@@ -0,0 +1,122 @@
+import React from 'react';
+import { Card, Row, Col, Icon, Form, Input, Button, Select, Table, DatePicker, message, Breadcrumb, Spin, Layout, Upload, Modal } from 'antd';
+
+const { TextArea } = Input;
+const FormItem = Form.Item;
+const Option = Select.Option;
+const ButtonGroup = Button.Group;
+
+class JobDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+
+    }
+  }
+
+  handleSubmit = (e) => { // 提交表单数据
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      console.log('提交表单数据:', values);
+      if (err) return;
+      let obj = {
+        ...values,
+        id: this.props.params.id || '',  //岗位id
+        unitId: this.props.params.unitId, //单位id
+      }
+      this.props.saveFun(obj);
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+    const { dataSet, params } = this.props;
+    console.log(dataSet)
+
+    return (
+      <div className="jobdetail-main h-100 margin padding bg-white">
+        <Spin spinning={this.props.spinning}>
+          <div>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title={params.postId ? '岗位信息(编辑)' : '岗位信息(新增)'} bordered={false} extra={
+                <Row type="flex" gutter={20}>
+                  <Col>
+                    <Button onClick={this.props.cancelFun}>返回</Button>
+                  </Col>
+                  <Col>
+                    <Button type="primary" htmlType="submit" >确定</Button>
+                  </Col>
+                </Row>
+              }>
+                <Row type="flex">
+                  <Col span={13}>
+                    <FormItem label={"岗位名称"} {...formItemLayout}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '请输入岗位名称' }],
+                        initialValue: dataSet.name || '',
+                      })(
+                        <Input placeholder="请输入岗位名称" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={13}>
+                    <FormItem label={"岗位级别"} {...formItemLayout}>
+                      {getFieldDecorator('level', {
+                        initialValue: dataSet.level || undefined
+                      })(
+                        <Select placeholder="请选择岗位级别">
+                          <Option value={1}>厅级</Option>
+                          <Option value={2}>处级</Option>
+                          <Option value={3}>科级</Option>
+                        </Select>
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row type="flex">
+                  <Col span={13}>
+                    <FormItem label={"所属部门"} {...formItemLayout}>
+                      {getFieldDecorator('deptId', {
+                        rules: [{ required: true, message: '所属部门' }],
+                        initialValue: dataSet.deptId || undefined
+                      })(
+                        <Select placeholder="请选择所属部门">
+                          {
+                            params.depts.map((item, idx) => {
+                              return (
+                                <Option value={item.id} key={item.id}>{item.name}</Option>
+                              )
+                            })
+                          }
+                        </Select>
+                      )}</FormItem>
+                  </Col>
+                </Row>
+
+                <Row type="flex">
+                  <Col span={13}>
+                    <FormItem label={"岗位描述"} {...formItemLayout}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description
+                      })(
+                        <TextArea placeholder="请输入备注" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+// const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+const JobDetailForm = Form.create()(JobDetail);
+export default JobDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/JobManage.jsx b/src/module/huge-base/JobManage.jsx
new file mode 100644
index 0000000..dd1b5c5
--- /dev/null
+++ b/src/module/huge-base/JobManage.jsx
@@ -0,0 +1,566 @@
+import React from "react";
+import { Link } from "react-router-dom";
+import { Card, Row, Col, Icon, Form, Input, Button, Table, DatePicker, message, Breadcrumb, Tree, Modal, Layout, Popconfirm, Select, Cascader, Spin, Alert, Tooltip, Empty, Statistic, Dropdown, Menu, Tag } from "antd";
+import moment from "moment";
+import SearchTree from '../../components/common/Tree';
+import fetch from '../../api/request';
+// import SearchTree from "../component/tree/index";
+// import Fetch from "../fetch";
+import JobDetail from "./JobDetail";
+// import {
+//   getUnitByAssociate,
+//   getUserOfPost,
+//   jobCount,
+//   postSet,
+//   getPostDetail,
+//   savePost
+// } from "../fetch/api";
+
+const FormItem = Form.Item;
+const confirm = Modal.confirm;
+const TreeNode = Tree.TreeNode;
+const Search = Input.Search;
+
+class JobManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      options: [],
+      selectOptionId: "",
+      spinning: false,
+      dataSet: {},
+      jobCount: {},
+      user: {},
+
+      jobData: [],
+      selectUser: {}, //右边选中的user
+      selectUserLeft: {}, //左边选中的user
+      visible: false,
+      tsData: {}, //临时数据
+
+      // unitId: ''  //单位编号
+      showUnder: false,
+      modify: false, //是否切换详情
+      params: {
+        postId: "", //岗位id
+        unitId: "", //所选的单位id
+        depts: [] //单位下的部门所有信息
+      },
+
+      detailData: {}, //详情数据,
+      getUnitByAssociate: null,//部门下的岗位分配情况
+      searchCode: '',//模糊查询字符串
+
+      currentSelectUnMatchUsers: null,//当前所选未配岗人员
+
+    };
+  }
+  componentDidMount() {
+    this.getAllUnits();
+  }
+
+  //获取所有的单位树形结构
+  getAllUnits = () => {
+    fetch({
+      url: 'api/unit/getAllUnitsByCascade'
+    }).then(res => {
+      if (res) {
+        this.setState({ options: res })
+      }
+    })
+  }
+
+  //级联框onChange事件
+  onChange = (value, selectedOptions) => {
+    this.setState({
+      selectOptionId: selectedOptions.length && selectedOptions[selectedOptions.length - 1].id,
+    }, () => {
+      if (this.state.selectOptionId) { this.loadJobData() }
+      else { this.setState({ showUnder: false }) }
+    });
+  };
+
+  // 加载关于岗位的相关接口
+  loadJobData = () => {
+    this.setState({
+      spinning: true
+    });
+    let p = [this.jobCount(), this.getUnitByAssociate(), this.getUserOfPost()]
+    Promise.all(p).then(res => {
+      this.setState({ spinning: false });
+      if (res.length == p.length) {
+        this.setState({
+          showUnder: true,
+          jobCount: res[0],
+          getUnitByAssociate: res[1],
+          getUserOfPost: res[2]
+        })
+      }
+    })
+  };
+
+  // 获取单位相关数据(包含单位下的部门,部门下的岗位)
+  getUnitByAssociate = () => {
+    let { selectOptionId } = this.state;//单位id
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/unit/getUnitByAssociate`,
+        params: { id: selectOptionId }
+      }).then(res => {
+        if (res) {
+          resolve(res);
+        }
+      })
+    })
+  }
+
+  //获取配岗用户
+  getUserOfPost = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/user/getUserOfPost`
+      }).then(res => {
+        if (res) {
+          resolve(res);
+        }
+      })
+    })
+  }
+
+  // 获取岗位统计数
+  jobCount = () => {
+    let { selectOptionId } = this.state;//单位id
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/post/count`,
+        params: { unitId: selectOptionId }
+      }).then(res => {
+        if (res) {
+          resolve(res);
+        }
+      })
+    })
+  }
+
+  //从左侧选择员工(兼岗、调岗、撤岗)
+  selectLeft = e => {
+    document.querySelector("body").style.cursor = "crosshair";
+  };
+
+
+  cancelFun = () => {
+    this.setState({
+      modify: false
+    });
+  };
+
+  //兼岗
+  setJG = () => {
+    let { dgOrjgData, currentSelectUnMatchUsers } = this.state;
+    fetch({
+      url: `api/post/set`,
+      method: 'POST',
+      data: {
+        operateType: 2,
+        userId: currentSelectUnMatchUsers.id,//员工id
+        sourcePostId: dgOrjgData.id//岗位id
+      }
+    }).then(res => {
+      if (res) {
+        message.success('设置兼岗成功');
+        this.setState({ visible: false, currentSelectUnMatchUsers: null })
+        this.loadJobData();
+      }
+    })
+  };
+
+  //调岗
+  setDG = () => {
+    let { dgOrjgData, currentSelectUnMatchUsers } = this.state;
+    fetch({
+      url: `api/post/set`,
+      method: 'POST',
+      data: {
+        operateType: 3,
+        userId: currentSelectUnMatchUsers.id,
+        sourcePostId: currentSelectUnMatchUsers.postId,
+        targetPostId: dgOrjgData.id
+      }
+    }).then(res => {
+      if (res) {
+        message.success('设置调岗成功');
+        this.setState({ visible: false, currentSelectUnMatchUsers: null })
+        this.loadJobData();
+      }
+    })
+  };
+
+  //撤岗
+  setCG = (data) => {
+    let _this = this;
+    let { currentSelectUnMatchUsers } = _this.state;
+    confirm({
+      title: `你确定要对员工(${data.userTrueName})撤岗吗?`,
+      onOk() {
+        fetch({
+          url: `api/post/set`,
+          method: 'POST',
+          data: {
+            operateType: 4,
+            userId: data.userId,//员工id
+            sourcePostId: data.id//岗位id
+          }
+        }).then(res => {
+          if (res) {
+            message.success('撤岗成功');
+            _this.loadJobData();
+            if (currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == data.userId) {
+              _this.setState({ currentSelectUnMatchUsers: null })//取消其高亮显示
+            }
+          }
+        })
+      },
+      onCancel() { },
+    });
+  };
+
+  //右侧选中员工,进行配岗操作
+  setPG = (post) => {
+    let _this = this;
+    let { currentSelectUnMatchUsers, getUnitByAssociate } = _this.state;
+    if (!currentSelectUnMatchUsers) {
+      return message.warning('请于右侧待配岗员工列表中选择待岗员工')
+    }
+
+    if (getUnitByAssociate && getUnitByAssociate.depts.reduce((p, n) => (
+      n.posts ? p.concat(n.posts) : p
+    ), []).findIndex(({ userId }) => userId == currentSelectUnMatchUsers.id) !== -1) {
+      // 此处触发调岗、兼岗操作
+      return _this.setState({ visible: true, dgOrjgData: post });
+    }
+    confirm({
+      title: `已选择员工(${currentSelectUnMatchUsers.trueName}), 您确定要对该员工配岗吗?`,
+      onOk() {
+        fetch({
+          url: `api/post/set`,
+          method: 'POST',
+          data: {
+            operateType: 1, //设置主岗
+            sourcePostId: post.id,
+            userId: currentSelectUnMatchUsers.id,
+            userTrueName: currentSelectUnMatchUsers.trueName
+          }
+        }).then(res => {
+          if (res) {
+            message.success('配岗成功');
+            _this.setState({ currentSelectUnMatchUsers: null });
+            _this.loadJobData();
+          }
+        })
+
+      },
+      onCancel() { },
+    });
+  }
+
+  // 员工的模糊搜索
+  onInputChange = (e) => {
+    this.setState({ searchCode: e.target.value })
+  }
+
+  onCancel = () => {
+    this.setState({
+      visible: false
+    });
+  };
+
+  // 岗位(新增 | 编辑)
+  modifyFun = (data) => {
+    let { getUnitByAssociate } = this.state;
+    let { id } = data;
+    this.setState({
+      modify: true,
+      params: {
+        ...data,
+        depts: getUnitByAssociate.depts
+      }
+    });
+    if (id) {
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/post/getById`,
+        params: { id }
+      }).then(res => {
+        if (res) {
+          this.setState({
+            detailData: res,
+            spinning: false,
+          })
+        }
+      })
+    } else {
+      this.setState({
+        detailData: {}//置空表单数据
+      })
+    }
+  };
+
+  //保存岗位
+  saveFun = data => {
+    this.setState({ spinning: true });
+    fetch({
+      url: `api/post/save`,
+      method: 'POST',
+      data
+    }).then(res => {
+      this.setState({ spinning: false });
+      if (res) {
+        message.success("保存岗位成功");
+        this.setState({ modify: false });
+        this.loadJobData();
+      }
+    })
+  };
+
+  //删除岗位
+  postDel = (data) => {
+    let _this = this;
+    let { id, name } = data;
+    confirm({
+      title: `您确定要删除岗位(${name})吗?`,
+      onOk() {
+        fetch({
+          url: `api/post/delete`,
+          params: { ids: id }
+        }).then(res => {
+          if (res) {
+            message.success('删除岗位成功');
+            _this.loadJobData();
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  // 选中当前待配岗人员
+  setCurrentSelectUnMatchUsers = (person) => {
+    let { currentSelectUnMatchUsers } = this.state;
+    currentSelectUnMatchUsers = currentSelectUnMatchUsers && person.id == currentSelectUnMatchUsers.id ? null : person;
+    if (currentSelectUnMatchUsers) {
+      message.success('已选中:' + currentSelectUnMatchUsers.trueName)
+    }
+    this.setState({
+      currentSelectUnMatchUsers
+    })
+  }
+
+  render() {
+    const { options, jobCount, visible, params, getUnitByAssociate, searchCode, getUserOfPost, currentSelectUnMatchUsers } = this.state;
+
+    const gridStyle = { width: '25%', padding: 8, boxShadow: 'none' };
+
+    return (
+      <React.Fragment>
+        <div
+          className="h-100 border padding bg-white"
+          style={{ display: !this.state.modify ? "flex" : "none" }}
+        >
+          <React.Fragment>
+            {visible && (
+              <Modal
+                onCancel={this.onCancel}
+                visible={true}
+                footer={
+                  <div>
+                    <Button onClick={this.setJG} type="primary">兼岗</Button>
+                    <Button onClick={this.setDG} type="primary">调岗</Button>
+                    <Button onClick={this.onCancel}>取消</Button>
+                  </div>
+                }
+              >
+                <p>您已经对此员工进行配岗,你还可以对他进行</p>
+              </Modal>
+            )}
+            <div
+              style={{
+                width: '100%',
+                display: "flex",
+                flexDirection: "column",
+                overflowY: "auto"
+              }}
+            >
+              {/* 单位级联框 */}
+              <div className="padding-tb">
+                <Cascader
+                  fieldNames={{
+                    label: "name",
+                    value: "name",
+                    children: "children"
+                  }}
+                  options={options}
+                  onChange={this.onChange}
+                  placeholder="请选择单位"
+                  style={{ width: "100%" }}
+                  changeOnSelect
+                />
+              </div>
+
+              <div className="flex-1">
+                <Spin spinning={this.state.spinning}>
+                  {this.state.showUnder && (
+                    <React.Fragment>
+                      <Row style={{ height: "100%" }}>
+                        <Col
+                          span={15}
+                          style={{ border: "1px solid #e8e8e8", display: 'flex', flexDirection: 'column', padding: 10 }}
+                          className="h-100 treeNodeUnselectable"
+                        >
+                          {/* 当前单位的配岗信息 */}
+                          <Row type="flex" justify="space-between" gutter={20}>
+                            <Col>
+                              <Row type="flex" gutter={30} style={{ marginBottom: 15 }}>
+                                <Col>
+                                  <div className="flex-box align-center">
+                                    <a className="statistic-label">总岗位:</a>
+                                    <Statistic value={jobCount.totalNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
+                                  </div>
+                                </Col>
+                                <Col>
+                                  <div className="flex-box align-center">
+                                    <div className="statistic-label">实岗:</div>
+                                    <Statistic value={jobCount.fullNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
+                                  </div>
+                                </Col>
+                                <Col>
+                                  <div className="flex-box align-center">
+                                    <div className="statistic-label">空岗:</div>
+                                    <Statistic value={jobCount.emptyNum || 0} valueStyle={{ fontSize: 16, fontWeight: 'bold' }} />
+                                  </div>
+                                </Col>
+                              </Row>
+                            </Col>
+                            <Col>
+                              <Button type='primary' size="small" onClick={() => { this.modifyFun({ id: '' }) }}>新增岗位</Button>
+                            </Col>
+                          </Row>
+
+                          <div className="flex-1">
+                            {
+                              getUnitByAssociate && getUnitByAssociate.depts && getUnitByAssociate.depts.map(({ posts, name, id }, deptIndex) => (
+                                <Card type="inner" title={'部门:' + name} style={{ marginBottom: 15 }} size="small" key={id}>
+                                  {
+                                    posts && posts.length > 0 ? posts.map((p, posIndex) => (
+                                      <Card.Grid style={gridStyle} hoverable={false} key={p.id}>
+                                        <Row type="flex" gutter={10}>
+                                          <Col>
+                                            {/* 岗位名(编辑,删除) */}
+                                            <Dropdown overlay={<Menu>
+                                              <Menu.Item key="1" onClick={() => this.modifyFun(p)}>编辑岗位</Menu.Item>
+                                              <Menu.Item key="2" onClick={() => this.postDel(p)}>删除岗位</Menu.Item>
+                                            </Menu>} trigger={['contextMenu']}>
+                                              <div style={{ cursor: 'pointer' }} >{p.name}</div>
+                                            </Dropdown>
+                                          </Col>
+                                          {p.userTrueName &&
+                                            <Col>
+                                              <Dropdown overlay={<Menu>
+                                                <Menu.Item key="1" onClick={() => this.setCG({ ...p, deptIndex, posIndex })}>撤岗</Menu.Item>
+                                              </Menu>} trigger={['contextMenu']}>
+                                                {/* <a>{p.userTrueName}</a> */}
+                                                {currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == p.userId ?
+                                                  <Tag style={{ cursor: 'pointer' }} color="#cc4e45" onDoubleClick={() => this.setCurrentSelectUnMatchUsers({ id: p.userId, trueName: p.userTrueName, postId: p.id })}>{p.userTrueName}</Tag> :
+                                                  <a onDoubleClick={() => this.setCurrentSelectUnMatchUsers({ id: p.userId, trueName: p.userTrueName, postId: p.id })}>{p.userTrueName}</a>
+                                                }
+                                              </Dropdown>
+                                            </Col>}
+                                          {!p.userTrueName && <Col><a onClick={() => { this.setPG(p) }}>[ 请选择 ]</a></Col>}
+                                        </Row>
+                                      </Card.Grid>
+                                    )) : <Row type="flex" justify="center">
+                                        <Col>该 部 门 下 暂 无 岗 位</Col>
+                                      </Row>
+                                  }
+                                </Card>
+                              ))
+                            }
+                          </div>
+
+                          <Row>
+                            <Alert message="您可以右键点击‘岗位’进行岗位编辑、删除,双击人员选中该人员,对该人员进行配岗操作" type="warning" />
+                          </Row>
+                        </Col>
+                        <Col span={1} />
+                        <Col
+                          span={8}
+                          style={{
+                            border: "1px solid #e8e8e8",
+                            display: "flex",
+                            flexDirection: "column",
+                            overflow: 'auto',
+                            padding: 10
+                          }}
+                          className="h-100 treeNodeUnselectable"
+                        >
+                          <div style={{ fontSize: 16, fontWeight: 'bold', textAlign: 'center', paddingBottom: 10 }}>
+                            待配岗人员
+                          </div>
+                          <Input
+                            style={{ marginBottom: 1 }}
+                            placeholder="请输入人员姓名"
+                            onChange={this.onInputChange}
+                            allowClear
+                            prefix={<Icon type="search" />}
+                          />
+                          <div className="flex-1">
+                            <Card bordered={false} bodyStyle={{ padding: 10 }}>
+                              {
+                                getUserOfPost && getUserOfPost.unMatchUsers && getUserOfPost.unMatchUsers.length > 0 ?
+                                  getUserOfPost.unMatchUsers.filter(({ trueName }) => trueName.indexOf(searchCode) !== -1).map((person) => (
+                                    <Card.Grid style={{ ...gridStyle, width: '20%' }} key={person.id}>
+                                      {currentSelectUnMatchUsers && currentSelectUnMatchUsers.id == person.id ?
+                                        <Tag style={{ cursor: 'pointer' }} color="#cc4e45" onDoubleClick={() => this.setCurrentSelectUnMatchUsers(person)}>{person.trueName}</Tag> :
+                                        <Tag style={{ cursor: 'pointer' }} onDoubleClick={() => this.setCurrentSelectUnMatchUsers(person)}>{person.trueName}</Tag>
+                                      }
+                                    </Card.Grid>
+                                  )) : <Empty description={'暂无待配岗人员'} className="h-100 flex-box-column align-center justify-content" />
+                              }
+                            </Card>
+
+                          </div>
+                          <div style={{ marginTop: 10 }}>
+                            <Row>
+                              <Alert message="您可以双击人员选中未配岗人员,对该人员进行配岗操作" type="warning" />
+                            </Row>
+                          </div>
+                        </Col>
+                      </Row>
+                      <Row />
+                    </React.Fragment>
+                  )}
+
+                  {!this.state.showUnder && (
+                    <Empty description={'暂无数据,请选择单位'} className="h-100 flex-box-column align-center justify-content" />
+                  )}
+                </Spin>
+              </div>
+            </div>
+          </React.Fragment>
+        </div>
+
+        <div style={{ display: this.state.modify ? "block" : "none" }}>
+          <JobDetail
+            cancelFun={this.cancelFun}
+            params={params}
+            dataSet={this.state.detailData}
+            saveFun={this.saveFun}
+            spinning={this.state.spinning}
+          />
+        </div>
+      </React.Fragment>
+    );
+  }
+}
+
+const JobManageList = Form.create()(JobManage);
+export default JobManageList;
diff --git a/src/module/huge-base/Menu.jsx b/src/module/huge-base/Menu.jsx
new file mode 100644
index 0000000..6493c7d
--- /dev/null
+++ b/src/module/huge-base/Menu.jsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import { Layout } from 'antd';
+
+import TreeMenu from '../component/TreeMenu';
+import data from '../data/menu';
+const { Sider } = Layout;
+function find(data, pathname) {
+  for (const { path, children } of data) {
+    if (path === pathname) return path;
+    if (children) {
+      const result = find(children, pathname);
+      if (result) return result;
+    }
+  }
+  return null;
+}
+
+function selected(data, pathname) {
+  if (!pathname || pathname === '/') return pathname;
+  return find(data, pathname) || selected(data, pathname.split('/').slice(0, -1).join('/'));
+}
+
+export default class Menu extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      collapsed: false
+    }
+  }
+  onCollapse = collapsed => {
+    this.setState({ collapsed });
+  }
+  render() {
+    const pathname = selected(data, this.props.location.pathname);
+    let defaultOpenKeys = (data.find(node => node.children && node.children.find(child => child.path == pathname)) || {}).name
+    return (
+      <Sider onCollapse={this.onCollapse}
+        collapsed={this.state.collapsed}
+        className="sider-light"
+        breakpoint="lg"
+        collapsible={false}
+      >
+        <TreeMenu
+          data={data}
+          defaultOpenKeys={[(data.find(node => node.children && node.children.find(child => child.path == pathname)) || {}).name]}
+          defaultSelectedKeys={[pathname]}
+        />
+      </Sider>
+    )
+  }
+}
diff --git a/src/module/huge-base/ModuleDetailEdit.jsx b/src/module/huge-base/ModuleDetailEdit.jsx
new file mode 100644
index 0000000..3be8c48
--- /dev/null
+++ b/src/module/huge-base/ModuleDetailEdit.jsx
@@ -0,0 +1,209 @@
+import React from 'react';
+import { Card, Row, Col, Icon, Form, Input, Button, Spin, Modal, Radio } from 'antd';
+
+const { TextArea } = Input;
+const FormItem = Form.Item;
+const RadioButton = Radio.Button;
+const RadioGroup = Radio.Group;
+
+class ModuleDetailEdit extends React.Component {
+  constructor(props) {
+    super(props)
+    // this.id = props.match.params.id;
+    // this.flag = props.match.params.flag == 'Modify' ? '修改' : '新增';
+    this.state = {
+      spinning: false,
+      id: '',
+      parentId: '',
+      dataSet: {},
+    }
+  }
+
+  componentDidMount() { }
+
+  //提交表单数据(保存)
+  handleSubmit = (e) => {
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      console.log('提交表单数据:', values);
+      if (err) return;
+      //触发父级保存接口函数
+      this.props.saveFun(values);
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+    const { dataSet, params, loading } = this.props;
+
+    return (
+      <div>
+        {
+          this.props.edit == 'true' ?
+            <div>
+              <Spin spinning={loading}>
+
+                <div>
+                  <Form onSubmit={this.handleSubmit}>
+                    <Card title={params.id ? '模块信息(编辑)' : '模块信息(新增)'} bordered={false}>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"资源类型"} {...formItemLayout}>
+                            {getFieldDecorator('isMenu', {
+                              rules: [{ required: true, message: '资源类型必选' }],
+                              initialValue: dataSet.isMenu
+                            })(
+                              <RadioGroup>
+                                <RadioButton value={1}>菜单</RadioButton>
+                                <RadioButton value={0}>模块</RadioButton>
+                              </RadioGroup>
+                            )}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"标识符"} {...formItemLayout}>
+                            {getFieldDecorator('symbol', {
+                              rules: [{ required: true, message: '请输入标志符' }],
+                              initialValue: dataSet.symbol || '',
+                            })(
+                              <Input placeholder="请输入标识符" />
+                            )}</FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"资源名称"} {...formItemLayout}>
+                            {getFieldDecorator('name', {
+                              rules: [{ required: true, message: '请输入资源名称' }],
+                              initialValue: dataSet.name || '',
+                            })(
+                              <Input placeholder="请输入资源名称" />
+                            )}</FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"路径"} {...formItemLayout}>
+                            {getFieldDecorator('url', {
+                              rules: [{ required: true, message: '请输入路径' }],
+                              initialValue: dataSet.url || '',
+                            })(
+                              <Input />
+                            )}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"路径设置"} {...formItemLayout}>
+                            {getFieldDecorator('urlType', {
+                              rules: [{ required: true, message: '路径类型必选' }],
+                              initialValue: dataSet.urlType || undefined
+                            })(
+                              <RadioGroup>
+                                <RadioButton value={1}>相对路径</RadioButton>
+                                <RadioButton value={0}>绝对路径</RadioButton>
+                              </RadioGroup>
+                            )}
+                          </FormItem>
+                        </Col>
+                      </Row>
+
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"描述"} {...formItemLayout}>
+                            {getFieldDecorator('description', {
+                              rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                              initialValue: dataSet.description || ''
+                            })(
+                              <TextArea placeholder="请输入描述" rows={5} />
+                            )}</FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex" gutter={20} style={{ width: '75%' }} justify="center">
+                        <Col>
+                          <Button onClick={this.props.cancelFun}>取消</Button>
+                        </Col>
+                        <Col>
+                          <Button className="button-do" htmlType="submit" type="primary">保存</Button>
+                        </Col>
+                      </Row>
+                    </Card>
+                  </Form>
+                </div>
+              </Spin>
+            </div>
+            :
+            <div>
+              <Spin spinning={loading}>
+                <div>
+                  <Form onSubmit={this.props.editFun}>
+                    <Card title={'模块信息'} bordered={false}>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"资源类型"} {...formItemLayout}>
+                            {dataSet.isMenu == 1 && '菜单'}
+                            {dataSet.isMenu == 0 && '模块'}
+
+                          </FormItem>
+                        </Col>
+                      </Row>
+
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"标识符"} {...formItemLayout}>
+                            {dataSet.symbol}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"资源名称"} {...formItemLayout}>
+                            {dataSet.name}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"路径"} {...formItemLayout}>
+                            {dataSet.url}
+                            {dataSet.urlType == 1 && "(相对地址)"}
+                            {dataSet.urlType == 0 && "(绝对地址)"}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"描述"} {...formItemLayout}>
+                            <TextArea value={dataSet.description} rows={5} disabled={true} />
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex" gutter={20} style={{ width: '75%' }} justify="center">
+                        <Col>
+                          <Button onClick={this.props.cancelData}>取消</Button>
+                        </Col>
+                        <Col>
+                          <Button type="primary" htmlType="submit">编辑</Button>
+                        </Col>
+                      </Row>
+                    </Card>
+                  </Form>
+                </div>
+              </Spin>
+            </div>
+        }
+      </div>
+    )
+  }
+}
+
+// const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+const ModuleDetailEditForm = Form.create()(ModuleDetailEdit);
+export default ModuleDetailEditForm;
\ No newline at end of file
diff --git a/src/module/huge-base/ModulesManage.jsx b/src/module/huge-base/ModulesManage.jsx
new file mode 100644
index 0000000..64bc2c9
--- /dev/null
+++ b/src/module/huge-base/ModulesManage.jsx
@@ -0,0 +1,314 @@
+import React from 'react';
+import { Row, Col, Form, message, Modal, Popconfirm, Empty, Spin } from 'antd';
+import moment from 'moment';
+import SearchTree from '../../components/common/Tree';
+import fetch from '../../api/request';
+import ModuleDetailEdit from './ModuleDetailEdit';
+
+const confirm = Modal.confirm;
+
+class ModulesManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      treeKey: Date.now(),
+      expandedKeys: [],
+      tableData: [],
+      totalElements: 1,
+      pageSize: 10,
+      treeData: [],
+      edit: 'false',
+      rightShow: false,
+      dataSet: {},
+      currentNode: [],
+      moduleId: '',
+      saveParams: {
+        id: '',
+        parentId: '',
+        appId: ''
+      },
+      selectedKeys: [],
+      treeLoading: false,//左侧树形数据loading
+      loading: false,//右侧详情loading
+
+    };
+  }
+
+  componentDidMount() {
+    this.loadData()
+  }
+
+  //加载左侧树形数据
+  loadData = () => {
+    this.setState({ treeLoading: true });
+    fetch({
+      url: `api/module/getAllModulesByTree`
+    }).then(res => {
+      this.setState({ treeLoading: false })
+      if (res) {
+        res = this.handleTreeData(res);
+        this.setState({
+          treeData: res,
+          treeKey: Date.now()
+        })
+      }
+    })
+  };
+
+  //处理树形数据
+  handleTreeData = data => {
+    for (let i = 0; i < data.length; i++) {
+      const node = data[i];
+      node.key = node.id;
+      node.title = node.name;
+      if (data[i].modules) {
+        data[i].children = data[i].modules;
+        this.handleTreeData(node.children);
+      }
+      if (data[i].children) {
+        this.handleTreeData(node.children);
+      }
+      // else{
+      //   this.handleTreeData([node])
+      // }
+    }
+    return data;
+  };
+
+  editFun = () => {
+    this.setState({
+      edit: 'true'
+    })
+  }
+
+  //点击保存按钮
+  saveFun = (data) => {
+    let { saveParams } = this.state;
+    console.log('data', this.state.saveParams)
+    this.setState({
+      edit: 'false',
+      // dataSet: data,
+      loading: true
+    });
+    fetch({
+      url: `api/module/save`,
+      method: 'POST',
+      data: { ...data, ...saveParams }
+    }).then(res => {
+      this.setState({ loading: false });
+      if (res) {
+        message.success("保存成功");
+        this.setState({ dataSet: data });
+        this.loadData();
+        // 处于新增节点的场景,保存成功之后,隐藏详情,清空表单数据(执行清空操作)
+        if (!saveParams.id) {
+          this.clearKeys();
+        }
+      }
+    })
+  }
+
+  //取消(保存界面下)
+  cancelFun = () => {
+    const { dataSet, currentNode } = this.state;
+    if (currentNode.length == 0) {
+      this.setState({
+        rightShow: false
+      })
+    } else {
+      this.setState({
+        edit: 'false'
+      });
+      if (Object.keys(dataSet).length == 0) {
+        // getModuleDetail(currentNode[0].id).then(res => {
+        //   this.setState({
+        //     dataSet: res.data,
+        //     loading: false
+        //   })
+        // })
+      }
+    }
+  }
+
+  //取消(查看界面下)
+  cancelData = () => {
+    this.setState({
+      rightShow: false,
+      dataSet: {},//清空表单数据
+      selectedKeys: [],
+      currentNode: []
+    })
+  }
+
+  onSelect = (selectedKeys) => {
+    let _this = this;
+    _this.setState({
+      selectedKeys
+    })
+  }
+
+  // 点击树形节点触发函数
+  treeSelect = (tableData, currentNode) => {
+    // 此处做判断,如果是根节点(顶级),点击时不出现右边编辑
+    if (currentNode[0].root) {
+      this.setState({
+        rightShow: false,
+        currentNode,
+        saveParams: {
+          ...this.state.saveParams,
+          appId: currentNode[0].id
+        },
+        selectedKeys: [currentNode[0].id]
+      })
+      // message.error('请选择子节点模块');
+      return
+    }
+    this.setState({
+      rightShow: true
+    })
+    // 此处为对应(模块、菜单)的详情
+    this.setState({
+      dataSet: {},//先清空之前的表单数据
+      leafNodes: tableData,
+      currentNode,
+      saveParams: {
+        ...this.state.saveParams,
+        appId: currentNode[0].appId || currentNode[0].id,
+        id: currentNode[0].id,
+      }
+    }, () => {
+      this.setState({ loading: true });
+      fetch({
+        url: `api/module/getById`,
+        params: { id: currentNode[0].id }
+      }).then(res => {
+        this.setState({ loading: false })
+        if (res) {
+          this.setState({ edit: 'false', dataSet: res })
+        }
+      })
+
+    })
+  };
+
+  //清除选中
+  clearKeys = () => {
+    this.setState({
+      dataSet: {},
+      currentNode: [],
+      rightShow: false,
+      selectedKeys: []
+    })
+  }
+
+  //点击左侧添加按钮,添加模块
+  addBtn = () => {
+    const { currentNode } = this.state;
+    if (currentNode.length == 0 || currentNode[0].length == 0) {
+      message.error("请选择节点之后添加");
+      return;
+    }
+    this.setState({
+      rightShow: true,
+      dataSet: {},
+      edit: 'true',
+      saveParams: {
+        ...this.state.saveParams,
+        id: '',
+        parentId: ''
+      }
+    })
+  }
+
+  //点击删除按钮
+  deleteBtn = (node) => {
+    const { currentNode } = this.state;
+    if (node == "") {
+      message.error("没有选择资源,无法删除")
+    } else {
+      if (currentNode[0].root) {
+        message.error("请选择子模块进行删除")
+      }
+      else {
+        this.ConfirmTip(node)
+      }
+    }
+  }
+
+  ConfirmTip = (node) => {
+    let _this = this;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该资源吗?</span>,
+      content: <span style={{ fontSize: 18 }}>删除该资源的同时,会删除与该资源的所有关系,也会删除所有的子资源。</span>,
+      onOk() {
+        fetch({
+          url: `api/module/delete`,
+          params: { ids: node.id }
+        }).then(res => {
+          if (res) {
+            message.success('模块删除成功');
+            _this.setState({ rightShow: false});
+            _this.loadData();
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  onExpand = (expandedKeys) => {
+    this.setState({
+      expandedKeys,
+    });
+  }
+
+  render() {
+    const { treeKey, rightShow, treeData, edit, treeLoading, loading } = this.state;
+    const saveParams = {
+      ...this.state.saveParams,
+      currentNode: this.state.currentNode,
+    }
+
+    return (
+      <div className="modulesmanage-main h-100 margin padding bg-white">
+        <div className="padding h-100">
+          <Row style={{ height: '100%' }} >
+            <Col span={8} style={{ border: "1px solid #e8e8e8", padding: 10 }} className="h-100">
+              <Spin spinning={treeLoading}>
+                <SearchTree key={treeKey}
+                  data={treeData}
+                  onExpand={this.onExpand}
+                  expandedKeys={this.state.expandedKeys}
+                  treeSelect={this.treeSelect}
+                  add={this.addBtn}
+                  delete={this.deleteBtn}
+                  clearKeys={this.clearKeys}
+                  onSelect={this.onSelect}
+                  selectedKeys={this.state.selectedKeys}
+                />
+              </Spin>
+            </Col>
+            <Col span={1}></Col>
+            <Col span={15} style={{ border: "1px solid #e8e8e8" }} className="h-100">
+              {
+                rightShow &&
+                <ModuleDetailEdit loading={loading} edit={edit} editFun={this.editFun} saveFun={this.saveFun} cancelFun={this.cancelFun} dataSet={this.state.dataSet} params={saveParams} cancelData={this.cancelData}></ModuleDetailEdit>
+              }
+              {
+                !rightShow &&
+                <Empty description={'暂无数据,请点击左侧树形结构'} className="h-100 flex-box-column align-center justify-content" />
+              }
+            </Col>
+          </Row>
+          <Row>
+          </Row>
+        </div>
+      </div>
+    )
+  }
+}
+
+
+
+const ModulesManageList = Form.create()(ModulesManage);
+export default ModulesManageList;
\ No newline at end of file
diff --git a/src/module/huge-base/RoleDetail.jsx b/src/module/huge-base/RoleDetail.jsx
new file mode 100644
index 0000000..2e9753b
--- /dev/null
+++ b/src/module/huge-base/RoleDetail.jsx
@@ -0,0 +1,187 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Form, Input, Button, message, Spin, TreeSelect } from 'antd';
+import MultiSelect from '../../components/common/multiSelect';
+import { createHashHistory } from 'history';
+import fetch from '../../api/request';
+
+const history = createHashHistory();
+const { TextArea } = Input;
+const FormItem = Form.Item;
+
+class RoleDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.id = props.match.params.id == 'new' ? '' : props.match.params.id;
+    this.flag = props.match.params.flag == 'Modify' ? '修改' : '新增';
+
+    this.state = {
+      spinning: false,//页面loading
+      groupList: [],
+      ownGroups: [],
+      title: '修改',
+      dataSet: {},
+    }
+  }
+
+  componentDidMount() {
+    let p = [this.findGroups()];
+    if (this.id) {
+      p = p.concat(this.getRoleDetail())
+    }
+    this.setState({ spinning: true });
+    Promise.all(p).then(res => {
+      console.log('res', res);
+      if (res.length == p.length) {
+        this.setState({ spinning: false });
+        this.setState({
+          groupList: res[0], //所有组
+        })
+        if (this.id) {
+          this.setState({
+            dataSet: res[res.length - 1],//角色信息
+            groupIds: res[res.length -1].groupIds || []//拥有组
+          })
+        }
+      }
+    })
+  }
+
+  //组
+  findGroups = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/group/finds`,
+      }).then(res => {
+        resolve(res)
+      })
+    })
+  }
+
+  //角色详情
+  getRoleDetail = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/role/getById`,
+        params: { id: this.id }
+      }).then(res => {
+        resolve(res)
+      })
+    })
+  }
+
+  groupChange = checkedValues => {
+    this.setState({ groupIds: checkedValues })
+  }
+
+  // 提交表单数据(新增 | 编辑)
+  handleSubmit = (e) => {
+    e.preventDefault();
+    this.props.form.validateFields((err, values) => {
+      if (err) return;
+      this.setState({ spinning: true });
+      fetch({
+        url: `api/role/save`,
+        method: 'POST',
+        data: {
+          role: { ...values, id: this.id },
+          groupIds: this.state.groupIds
+        }
+      }).then(res => {
+        this.setState({ spinning: false });
+        if (res) {
+          message.success('保存角色成功');
+          history.goBack();
+        }
+      })
+    });
+  }
+
+  //返回函数
+  onBack = () => {
+    history.goBack();
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout1 = {
+      labelCol: { xs: { span: 24 }, sm: { span: 10 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 14 }, },
+    };
+    const formItemLayout2 = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+    const { groupList, dataSet, groupIds } = this.state;
+
+    return (
+      <div className="roledetail-main h-100 margin padding bg-white">
+        <Spin spinning={this.state.spinning}>
+          <div>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title={'基础信息'} bordered={false}
+                extra={
+                  <Row type="flex" gutter={20}>
+                    <Col>
+                      <Button onClick={this.onBack}>返回</Button>
+                    </Col>
+                    <Col>
+                      <Button htmlType="submit" type='primary'>确定</Button>
+                    </Col>
+                  </Row>
+                }
+              >
+                <Row type="flex">
+                  <Col span={8}>
+                    <FormItem label={"标识符"} {...formItemLayout1}>
+                      {getFieldDecorator('symbol', {
+                        rules: [{ required: true, message: '标识符必填' }],
+                        initialValue: dataSet.symbol || ''
+                      })(
+                        <Input placeholder="请输入标识符" />
+                      )}</FormItem>
+                  </Col>
+                  <Col span={8}>
+                    <FormItem label={"角色名称"} {...formItemLayout1}>
+                      {getFieldDecorator('name', {
+                        rules: [{ required: true, message: '角色名称必填' }],
+                        initialValue: dataSet.name || ''
+                      })(
+                        <Input placeholder="请输入角色名称" />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+                <Row>
+                  <Col span={16}>
+                    <FormItem label={"描述"} {...formItemLayout2}>
+                      {getFieldDecorator('description', {
+                        rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                        initialValue: dataSet.description || ''
+                      })(
+                        <TextArea placeholder="请输入描述" rows={5} />
+                      )}</FormItem>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+            <Card title={'拥有组'} bordered={false} extra={
+              <Row>
+                <Link to={{ pathname: "/baseManage/group/Detail/new/Add", state: { id: '' } }}>
+                  没有组?点击新建
+                </Link>
+              </Row>
+            }>
+              <Row>
+                <MultiSelect key={groupIds ? groupIds.toString() : 'init'} all={groupList} own={groupIds} onChange={this.groupChange} />
+              </Row>
+            </Card>
+          </div>
+        </Spin>
+      </div>
+    )
+  }
+}
+
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+const RoleDetailForm = Form.create()(RoleDetail);
+export default RoleDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/RoleManage.jsx b/src/module/huge-base/RoleManage.jsx
new file mode 100644
index 0000000..c790f42
--- /dev/null
+++ b/src/module/huge-base/RoleManage.jsx
@@ -0,0 +1,114 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Row, Col, Button, message, Modal, Divider } from 'antd';
+import TableView from '../../components/common/TableView';
+import SearchFormView from '../../components/common/SearchFormView';
+import moment from 'moment';
+import fetch from '../../api/request';
+
+const confirm = Modal.confirm;
+
+export default class RoleManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      },
+
+    };
+  }
+
+  componentDidMount() { }
+
+  setFormData = data => {
+    console.log('form', data);
+    this.setState({
+      formData: data,
+    });
+  }
+
+  // 增加角色
+  add = () => {
+    this.props.history.push('/organizationMgt/role/Detail/new/Add')
+  }
+
+  //删除角色
+  delete = (id) => {
+    let _this = this;
+    let { formData } = _this.state;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该角色吗?</span>,
+      content: <span style={{ fontSize: 18 }}>删除该角色的同时,会删除与该角色的所有关系。</span>,
+      onOk() {
+        fetch({
+          url: `api/role/delete`,
+          params: { ids: id }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.setState({
+              formData: {
+                ...formData,
+                __key: Date.now()//刷新表格数据
+              }
+            })
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  //表格列显示
+  renderColumns = () => {
+    return [
+      { title: '标识符', className: "txt-c", dataIndex: 'symbol' },
+      { title: '角色名称', className: "txt-c", dataIndex: 'name' },
+      { title: '描述', className: "txt-c", dataIndex: 'description', ellipsis: true, width: '35%' },
+      { title: '创建时间', className: "txt-c", dataIndex: 'updateTime', render: (text, record) => text ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      {
+        title: '操作', className: "txt-c", key: 'operation', render: (text, record) => {
+          return <div>
+            <Link to={{ pathname: "/organizationMgt/role/Detail/" + record.id + '/Modify', query: { id: record.id } }}>修改</Link>
+            <Divider type="vertical" />
+            <a onClick={() => this.delete(record.id)}>删除</a>
+          </div>
+        }
+      }
+    ]
+  }
+
+
+
+  render() {
+    const { formData } = this.state;
+    let tableParams = {
+      url: `api/role/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {},
+      setFormData: this.setFormData
+    }
+    return (
+      <div className="rolemanage-main h-100 margin padding bg-white">
+        <SearchFormView
+          formData={formData}
+          setFormData={this.setFormData}
+          data={[
+            { type: 'input', name: '标识符', label: '标识符', key: 'symbol' },
+            { type: 'input', name: '角色名称', label: '角色名称', key: 'name' }
+          ]} />
+        <Row type="flex" gutter={20} className="margin-bottom">
+          <Col>
+            <Button type="primary" onClick={this.add}>新增角色</Button>
+          </Col>
+        </Row>
+        <TableView {...tableParams} />
+      </div>
+    )
+  }
+}
diff --git a/src/module/huge-base/UnitDetailEdit.jsx b/src/module/huge-base/UnitDetailEdit.jsx
new file mode 100644
index 0000000..a42cc6e
--- /dev/null
+++ b/src/module/huge-base/UnitDetailEdit.jsx
@@ -0,0 +1,167 @@
+/* eslint-disable */
+import React from 'react';
+import { Card, Row, Col, Form, Input, Button, Spin, message } from 'antd';
+import fetch from '../../api/request';
+
+const { TextArea } = Input;
+const FormItem = Form.Item;
+
+class GroupDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+      spinning: false,
+      id: '',
+      parentId: '',
+      dataSet: {},
+      btnLoading: false,//保存按钮loading
+    }
+  }
+
+  componentWillMount() {
+  }
+  componentDidMount() {
+  }
+
+  handleSubmit = (e) => { // 提交表单数据
+    e.preventDefault();
+    let parentId = '';
+    if (this.props.params.currentNode.length == 0) {
+      //没有选中节点 
+      parentId = '';
+    } else {
+      // 判断是新增还是编辑
+      if (this.props.params.id == '') {
+        parentId = this.props.params.currentNode[0].id  //此为新增
+      } else {
+        parentId = this.props.params.currentNode[0].parentId  //此为编辑
+      }
+    }
+    this.props.form.validateFields((err, values) => {
+      if (err) return;
+      this.setState({ btnLoading: true });
+      fetch({
+        url: `api/unit/save`,
+        method: 'POST',
+        data: {
+          ...values,
+          id: this.props.params.id,
+          parentId
+        }
+      }).then(res => {
+        this.setState({ btnLoading: false })
+        if (res) {
+          message.success("保存成功");
+          this.props.saveFun(values);//触发父级保存响应函数,刷新页面数据
+        }
+      })
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 5 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 19 }, },
+    };
+
+    const { params } = this.props;
+    const dataSet = this.props.dataSet || {};
+    const { btnLoading } = this.state;
+
+    return (
+      <div>
+        {
+          this.props.edit == 'true' ?
+            <div>
+              <Spin spinning={this.props.loading}>
+                <div>
+                  <Form onSubmit={this.handleSubmit}>
+                    <Card title={this.props.params.id ? '单位信息(编辑)' : '单位信息(新增)'} bordered={false}>
+                      {
+                        this.props.params.currentNode.length > 0 && Object.keys(dataSet).length == 0 &&
+                        <Row type="flex">
+                          <Col span={16}>
+                            <FormItem label={"上级单位"} {...formItemLayout}>
+                              <span>{params.currentNode[0].name}</span>
+                            </FormItem>
+                          </Col>
+                        </Row>
+                      }
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"单位名称"} {...formItemLayout}>
+                            {getFieldDecorator('name', {
+                              rules: [{ required: true, message: '请输入单位名称' }],
+                              initialValue: dataSet.name || '',
+                            })(
+                              <Input placeholder="请输入单位名称" />
+                            )}</FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"描述"} {...formItemLayout}>
+                            {getFieldDecorator('description', {
+                              rules: [{ max: 200, message: '描述的内容不能超过200字' }],
+                              initialValue: dataSet.description || ''
+                            })(
+                              <TextArea placeholder="请输入描述" rows={5} />
+                            )}</FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex" justify="center" gutter={20} style={{ width: '75%' }}>
+                        <Col>
+                          <Button onClick={this.props.cancelFun}>取消</Button>
+                        </Col>
+                        <Col>
+                          <Button type="primary" htmlType="submit" loading={btnLoading}>保存</Button>
+                        </Col>
+                      </Row>
+                    </Card>
+                  </Form>
+                </div>
+              </Spin>
+            </div>
+            :
+            <div>
+              <Spin spinning={this.props.loading}>
+                <div>
+                  <Form onSubmit={this.props.editFun}>
+
+                    <Card title={'单位信息'} bordered={false}>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"单位名称"} {...formItemLayout} style={{ marginBottom: 10 }}>
+                            <span>{dataSet.name || '暂无'}</span>
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type="flex">
+                        <Col span={16}>
+                          <FormItem label={"描述"} {...formItemLayout} style={{ marginBottom: 10 }}>
+                            {dataSet.description || '暂无'}
+                          </FormItem>
+                        </Col>
+                      </Row>
+                      <Row type='flex' gutter={20} justify="center" style={{ width: '75%' }}>
+                        <Col>
+                          <Button onClick={this.props.cancelData}>取消</Button>
+                        </Col>
+                        <Col>
+                          <Button className="button-do" htmlType="submit" type="primary">编辑</Button>
+                        </Col>
+                      </Row>
+                    </Card>
+                  </Form>
+                </div>
+              </Spin>
+            </div>
+        }
+      </div>
+    )
+  }
+}
+
+const GroupDetailForm = Form.create()(GroupDetail);
+export default GroupDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/UnitManage.jsx b/src/module/huge-base/UnitManage.jsx
new file mode 100644
index 0000000..999c139
--- /dev/null
+++ b/src/module/huge-base/UnitManage.jsx
@@ -0,0 +1,252 @@
+import React from 'react';
+import { Row, Col, Form, message, Modal, Empty, Spin } from 'antd';
+import SearchTree from '../../components/common/Tree';
+import fetch from '../../api/request';
+import UnitDetailEdit from './UnitDetailEdit';
+
+const confirm = Modal.confirm;
+
+class UnitManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      loading: false,//右侧详情loading
+      resourceList: [],
+      treeKey: 'init',
+      expandedKeys: [],
+      tableData: [],
+      totalElements: 1,
+      pageSize: 10,
+      treeData: [],
+      edit: 'false',
+      rightShow: false,
+      dataSet: {},
+      currentNode: [],
+      id: '',
+      selectedKeys: []
+    };
+  }
+
+  componentDidMount() {
+    this.loadData()
+  }
+
+  // 加载单位树形数据
+  loadData = () => {
+    this.setState({
+      treeLoading: true
+    })
+    fetch({
+      url: `api/unit/getAllUnitsByCascade`
+    }).then(res => {
+      res = this.handleTreeData(res);
+      if (res) {
+        this.setState({
+          treeLoading: false,
+          treeData: res,//树形数据
+          treeKey: Date.now()
+        })
+      }
+    })
+  };
+
+  //处理树形数据
+  handleTreeData = data => {
+    for (let i = 0; i < data.length; i++) {
+      const node = data[i];
+      node.key = node.id;
+      node.title = node.name;
+      if (data[i].children) {
+        this.handleTreeData(node.children);
+      }
+    }
+    return data;
+  };
+
+  editFun = () => {
+    this.setState({
+      edit: 'true'
+    })
+  }
+
+  saveFun = (obj) => {
+    this.setState({
+      edit: 'false',
+      dataSet: obj,
+      expandedKeys: []
+    })
+    this.loadData();
+    this.setState({ treeKey: Date.now() })
+  }
+
+  cancelFun = () => {
+    const { dataSet, currentNode } = this.state;
+    if (currentNode.length == 0) {
+      this.setState({
+        rightShow: false
+      })
+    } else {
+      this.setState({
+        edit: 'false'
+      });
+      if (Object.keys(dataSet).length == 0) {
+        // Fetch.unitDetail({id: currentNode[0].id}).then(res => {
+        //   _this.setState({
+        //     dataSet: res,
+        //     id: currentNode[0].id,
+        //     loading: false
+        //   })
+        // })
+      }
+    }
+
+  }
+
+  cancelData = () => {
+    let _this = this;
+    this.setState({
+      rightShow: false,
+      selectedKeys: [],
+      currentNode: []
+    });
+  }
+
+  onSelect = (selectedKeys) => {
+    let _this = this;
+    _this.setState({
+      selectedKeys
+    })
+  }
+
+  // 点击任意节点都可以查看、编辑、添加(获取单位信息详情)
+  treeSelect = (tableData, currentNode) => {
+    this.setState({
+      rightShow: true,
+      loading: true,
+      leafNodes: tableData,
+      currentNode,
+      selectedKeys: [currentNode[0].id]
+    }, () => {
+      fetch({
+        url: `api/unit/getById`,
+        params: { id: currentNode[0].id }
+      }).then(res => {
+        if (res) {
+          this.setState({
+            edit: 'false',
+            dataSet: res,
+            id: currentNode[0].id,
+            loading: false
+          })
+        }
+      })
+    })
+  };
+
+  addBtn = () => {
+    this.setState({
+      rightShow: true,
+      dataSet: {},
+      edit: 'true',
+      id: ''
+    })
+  }
+
+  //删除按钮
+  deleteBtn = (node) => {
+    if (node == "") {
+      message.error("没有选择资源,无法删除")
+    } else {
+      this.ConfirmTip(node);
+    }
+  }
+
+  //删除单位(提示操作)
+  ConfirmTip = (node) => {
+    let _this = this;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该资源吗?</span>,
+      content: <span style={{ fontSize: 18 }}>删除该资源的同时,会删除与该资源的所有关系,也会删除所有的子资源。</span>,
+      onOk() {
+        fetch({
+          url: `api/unit/delete`,
+          params: {
+            ids: node.id
+          }
+        }).then(res => {
+          if (res) {
+            message.success('节点删除成功');
+            _this.loadData();
+            _this.setState({ treeKey: Date.now(), rightShow: false })
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  onExpand = (expandedKeys) => {
+    this.setState({
+      expandedKeys
+    });
+  }
+
+  clearKeys = () => {
+    let _this = this;
+    _this.setState({
+      currentNode: [],
+      rightShow: false
+    })
+  }
+
+  render() {
+    const { treeKey, rightShow, treeData, edit, treeLoading } = this.state;
+
+    const params = {
+      currentNode: this.state.currentNode,
+      id: this.state.id
+    }
+
+    return (
+      <div className="unitmanage-main margin padding bg-white h-100">
+
+        <div className="h-100 padding">
+          <Row style={{ height: '100%' }}>
+            <Col span={8} style={{ border: "1px solid #e8e8e8", padding: 10 }} className="h-100">
+              <Spin spinning={treeLoading}>
+                <SearchTree key={treeKey}
+                  data={treeData}
+                  onExpand={this.onExpand}
+                  expandedKeys={this.state.expandedKeys}
+                  treeSelect={this.treeSelect}
+                  add={this.addBtn}
+                  delete={this.deleteBtn}
+                  clearKeys={this.clearKeys}
+                  onSelect={this.onSelect}
+                  selectedKeys={this.state.selectedKeys}
+                />
+              </Spin>
+            </Col>
+            <Col span={1}></Col>
+            <Col span={15} style={{ border: "1px solid #e8e8e8" }} className="h-100">
+              {
+                rightShow &&
+                <UnitDetailEdit edit={edit} editFun={this.editFun} saveFun={this.saveFun} cancelFun={this.cancelFun} dataSet={this.state.dataSet} params={params} cancelData={this.cancelData} loading={this.state.loading}></UnitDetailEdit>}
+              {
+                !rightShow &&
+                <Empty description={'暂无数据,请点击左侧树形结构进行创建'} className="h-100 flex-box-column align-center justify-content" />
+              }
+            </Col>
+          </Row>
+          <Row>
+          </Row>
+        </div>
+      </div>
+    )
+  }
+
+}
+
+
+const UnitManageList = Form.create()(UnitManage);
+export default UnitManageList;
\ No newline at end of file
diff --git a/src/module/huge-base/UserDetail.jsx b/src/module/huge-base/UserDetail.jsx
new file mode 100644
index 0000000..0f5a42f
--- /dev/null
+++ b/src/module/huge-base/UserDetail.jsx
@@ -0,0 +1,444 @@
+/* eslint-disable */
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Card, Row, Col, Icon, Form, Input, Button, Select, Table, DatePicker, message, Breadcrumb, Spin, Layout, Upload, Modal } from 'antd';
+import MultiSelect from '../../components/common/multiSelect';
+import { BASE_URL } from '../../api/httpurl';
+import fetch from '../../api/request';
+import ChangePswView from '../../components/common/ChangePswView';
+import { createHashHistory } from 'history';
+
+const history = createHashHistory();
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+class UserDetail extends React.Component {
+  constructor(props) {
+    super(props)
+    this.id = props.match.params.id == 'new' ? '' : props.match.params.id;
+    this.flag = props.match.params.flag == 'Modify' ? '修改' : '新增';
+    this.state = {
+      spinning: false,
+      user: {},
+      account: {},
+      groupIds: [], //组
+      roleIds: [], //角色
+
+      previewVisible: false,
+      previewImage: '',
+      fileList: [],
+
+      roleList: [],
+      ownRoles: [],
+      groupList: [],
+      ownGroups: [],
+      changePswVisible: false,
+      btnLoading: false
+    }
+  }
+  componentDidMount() {
+    let p = [this.findGroups(), this.findRoles()];
+    if (this.id) {
+      p = p.concat(this.getUserDetail());
+    }
+    this.setState({
+      spinning: true
+    })
+    Promise.all(p).then(res => {
+      if (res.length == p.length) {
+        this.setState({
+          spinning: false,
+          groupList: res[0],
+          roleList: res[1]
+        });
+        if (this.id) {
+          let detail = res[res.length - 1]; //用户信息
+          this.setState({
+            dataSet: detail,
+            spinning: false,
+            user: detail.user,
+            account: detail.account,
+            groupIds: detail.groupIds,
+            roleIds: detail.roleIds,
+            fileList: (detail.user.avatar == null || detail.user.avatar == '') ? [] : [{
+              uid: '-1',
+              name: 'xxx.png',
+              status: 'done',
+              url: detail.user.avatar
+            }]
+          })
+        }
+      }
+    })
+  }
+
+  //组
+  findGroups = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/group/finds`,
+      }).then(res => {
+        resolve(res)
+      })
+    })
+  }
+
+  // 角色
+  findRoles = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/role/finds`,
+      }).then(res => {
+        resolve(res)
+      })
+    })
+  }
+
+  // 基础信息
+  getUserDetail = () => {
+    return new Promise((resolve, reject) => {
+      fetch({
+        url: `api/user/getById`,
+        params: {
+          id: this.id
+        }
+      }).then(res => {
+        if (res) {
+          resolve(res)
+        }
+      })
+    })
+  }
+
+  // 返回函数
+  goBack = () => {
+    history.goBack();
+  }
+
+  handleCancel = () => this.setState({ previewVisible: false })
+
+  handlePreview = (file) => {
+    this.setState({
+      previewImage: file.url || file.thumbUrl,
+      previewVisible: true,
+    });
+  }
+
+  handleChange = ({ fileList, file }) => {
+    const { user } = this.state;
+    this.setState({
+      fileList,
+    })
+    if (file.status == 'done') {
+      this.setState({
+        user: {
+          ...user,
+          avatar: file.response.data
+        }
+      })
+    }
+  }
+
+  handleRemove = ({ fileList }) => {
+    const { user } = this.state;
+    this.setState({
+      user: {
+        ...user,
+        avatar: ''
+      },
+      fileList: []
+    })
+  }
+
+  roleChange = checkedValues => {
+    this.setState({ roleIds: checkedValues })
+  }
+  groupChange = checkedValues => {
+    this.setState({ groupIds: checkedValues })
+  }
+
+  //修改用户密码
+  onOK = (data) => {
+    let formData = {
+      accountId: this.state.account.id,
+      newPassword: data.newPassWord
+    }
+    this.setState({
+      btnLoading: true
+    })
+    fetch({
+      url: `api/account/changePassword`,
+      params: formData
+    }).then(res => {
+      this.setState({
+        btnLoading: false,
+        changePswVisible: false
+      })
+      if (res) {
+        message.success("密码修改成功");
+      }
+    })
+  }
+
+  // 确定修改|保存
+  handleSubmit = (e) => { // 提交表单数据
+    e.preventDefault();
+    let _this = this;
+    _this.props.form.validateFields((err, values) => {
+      if (err) return;
+      _this.setState({ spinning: true });
+      fetch({
+        url: `api/user/save`,
+        method: 'POST',
+        data: {
+          account: {
+            ..._this.state.account,
+            id: _this.state.account.id || '',
+            account: values.account,
+            credential: values.credential,
+          },
+          user: {
+            ..._this.state.user,
+            id: _this.state.user.id,
+            trueName: values.trueName,
+            sex: values.sex,
+            idcard: values.idcard,
+            mobile: values.mobile,
+            email: values.email,
+          },
+          roleIds: _this.state.roleIds,
+          groupIds: _this.state.groupIds
+        }
+      }).then(res => {
+        _this.setState({ spinning: false })
+        if (res) {
+          message.success('保存用户成功');
+          history.goBack();
+        }
+      })
+    })
+  }
+
+  isMobile = (rule, value, callback) => {
+    const regMobile = /^0?1[3|4|5|8][0-9]\d{8}$/
+    if (!regMobile.test(value)) {
+      if (value == "") {
+        callback();
+        return;
+      } else {
+        callback('手机号码格式不正确');
+        return;
+      }
+    }
+    callback()
+  }
+
+  isIdCard = (rule, value, callback) => {
+    const regMobile = /^[1-9]\d{7}((0[1-9])|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/;
+    if (!regMobile.test(value)) {
+      if (value == "") {
+        callback();
+        return;
+      } else {
+        callback('身份证号码格式不正确');
+        return;
+      }
+    }
+    callback()
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form;
+    const formItemLayout = {
+      labelCol: { xs: { span: 24 }, sm: { span: 10 }, },
+      wrapperCol: { xs: { span: 24 }, sm: { span: 14 }, },
+    };
+    const { user, account, groupIds, roleIds, previewVisible, previewImage, fileList, roleList, groupList, changePswVisible, btnLoading } = this.state;
+    const uploadButton = (
+      <div>
+        <Icon type="plus" />
+        <div className="ant-upload-text">上传头像</div>
+      </div>
+    );
+    return (
+      <div className="userdetail-main margin padding bg-white">
+
+        <Spin spinning={this.state.spinning}>
+          <Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
+            <img alt="example" style={{ width: '100%' }} src={previewImage} />
+          </Modal>
+          <div style={{ margin: 20 }}>
+            <Form onSubmit={this.handleSubmit}>
+              <Card title="账号信息" bordered={false} extra={
+                <Row type="flex" gutter={20}>
+                  <Col>
+                    <Button onClick={this.goBack}>返回</Button>
+                  </Col>
+                  <Col>
+                    <Button type="primary" htmlType="submit" >确认</Button>
+                  </Col>
+                </Row>
+              }>
+                <Row>
+                  <Col span={16}>
+                    {
+                      this.flag == '修改' ?
+                        <Row>
+                          <Col span={12}>
+                            <FormItem label={"账号"} {...formItemLayout}>
+                              {account.account || ''}
+                            </FormItem>
+                          </Col>
+                          <Col span={12}>
+                            <FormItem label={"密码"} {...formItemLayout}>
+                              {'********'}
+                            </FormItem>
+                          </Col>
+                        </Row>
+                        :
+                        <Row>
+                          <Col span={12}>
+                            <FormItem label={"账号"} {...formItemLayout}>
+                              {getFieldDecorator('account', {
+                                rules: [{ required: true, message: '账号必填' }],
+                                initialValue: account.account || ''
+                              })(
+                                <Input placeholder="请输入账号" />
+                              )}</FormItem>
+                          </Col>
+                          <Col span={12}>
+                            <FormItem label={"密码"} {...formItemLayout} hasFeedback>
+                              {getFieldDecorator('credential', {
+                                rules: [{ required: true, message: '密码必填' }],
+                                initialValue: account.credential || ''
+                              })(
+                                <Input.Password placeholder="请输入密码" type="password" />
+                              )}</FormItem>
+                          </Col>
+                        </Row>
+                    }
+                  </Col>
+                  {
+                    this.flag == '修改' &&
+                    <Col span={8}>
+                      <div style={{ marginLeft: '20%' }}>
+                        <Button type="primary" onClick={() => {
+                          this.setState({
+                            changePswVisible: true
+                          })
+                        }}>修改密码</Button>
+                      </div>
+                    </Col>
+                  }
+                </Row>
+              </Card>
+
+              <Card title="基础信息" bordered={false} >
+                <Row>
+                  <Col span={16}>
+                    <Row>
+                      <Col span={12}>
+                        <FormItem label={"姓名"} {...formItemLayout}>
+                          {getFieldDecorator('trueName', {
+                            rules: [{ required: true, message: '姓名必填' }],
+                            initialValue: user.trueName || ''
+                          })(
+                            <Input placeholder="请输入姓名" />
+                          )}</FormItem>
+                      </Col>
+                      <Col span={12}>
+                        <FormItem label={"性别"} {...formItemLayout}>
+                          {getFieldDecorator('sex', {
+                            rules: [{ required: true, message: '微信用户名称必填' }],
+                            initialValue: user.sex || undefined
+                          })(
+                            <Select placeholder="请选择">
+                              <Option value={1}>男</Option>
+                              <Option value={2}>女</Option>
+                            </Select>
+                          )}</FormItem>
+                      </Col>
+                    </Row>
+                    <Row>
+                      <Col span={12}>
+                        <FormItem label={"手机号码"} {...formItemLayout}>
+                          {getFieldDecorator('mobile', {
+                            rules: [{
+                              required: true, message: '手机号码必填'
+                            }, {
+                              validator: this.isMobile
+                            }],
+                            initialValue: user.mobile || ''
+                          })(
+                            <Input placeholder="请输入手机号码" />
+                          )}</FormItem>
+                      </Col>
+                      <Col span={12}>
+                        <FormItem label={"电子邮箱"} {...formItemLayout}>
+                          {getFieldDecorator('email', {
+                            rules: [{
+                              type: 'email', message: '电子邮箱格式不正确',
+                            }],
+                            initialValue: user.email || ''
+                          })(
+                            <Input placeholder="请输入电子邮箱" />
+                          )}</FormItem>
+                      </Col>
+                    </Row>
+                    <Row>
+                      <Col span={12}>
+                        <FormItem label={"身份证号码"} {...formItemLayout}>
+                          {getFieldDecorator('idcard', {
+                            rules: [{
+                              required: true, message: '身份证号码必填'
+                            }, {
+                              validator: this.isIdCard
+                            }],
+                            initialValue: user.idcard || ''
+                          })(
+                            <Input placeholder="请输入身份证号码" />
+                          )}</FormItem>
+                      </Col>
+                    </Row>
+                  </Col>
+                  <Col span={8}>
+                    <div style={{ marginLeft: '20%' }}>
+                      <Upload
+                        action={BASE_URL + `api/user/uploadAvatar`}
+                        listType="picture-card"
+                        fileList={fileList}
+                        onPreview={this.handlePreview}
+                        onChange={this.handleChange}
+                        onRemove={this.handleRemove}
+                      >
+                        {fileList.length > 0 ? null : uploadButton}
+                      </Upload>
+                    </div>
+                  </Col>
+                </Row>
+              </Card>
+            </Form>
+
+            <Card title="拥有角色" bordered={false} extra={<Link to={{ pathname: "/organizationMgt/roleDetail/new/Add", state: { id: 'new' } }}>没有角色?点击新建</Link>}>
+              <Row>
+                <MultiSelect key={roleIds ? roleIds.toString() : 'init'} all={roleList} own={roleIds} onChange={this.roleChange} />
+              </Row>
+            </Card>
+
+            <Card title="拥有组" bordered={false} extra={<Link to={{ pathname: "/baseManage/groupDetail/new/Add", state: { id: '' } }}>没有组?点击新建</Link>}>
+              <Row>
+                <MultiSelect key={groupIds ? groupIds.toString() : 'init'} all={groupList} own={groupIds} onChange={this.groupChange} />
+              </Row>
+            </Card>
+          </div>
+        </Spin>
+        {
+          changePswVisible && <ChangePswView onCancel={() => { this.setState({ changePswVisible: false }) }} onOK={this.onOK} btnLoading={btnLoading} />
+        }
+      </div>
+    )
+  }
+}
+
+const UserDetailForm = Form.create()(UserDetail);
+export default UserDetailForm;
\ No newline at end of file
diff --git a/src/module/huge-base/UserManage.jsx b/src/module/huge-base/UserManage.jsx
new file mode 100644
index 0000000..5f6ea8a
--- /dev/null
+++ b/src/module/huge-base/UserManage.jsx
@@ -0,0 +1,139 @@
+/* eslint-disable */
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Row, Col, Icon, Button, Select, message, Modal, Divider, Avatar } from 'antd';
+import TableView from '../../components/common/TableView';
+import SearchFormView from '../../components/common/SearchFormView';
+import moment from 'moment';
+import fetch from '../../api/request';
+
+const confirm = Modal.confirm;
+
+export default class UserManage extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      formData: {
+        __key: Date.now(),
+        page: 1,
+        size: 10,
+      },
+      userSyncLoading: false
+    };
+  }
+
+  componentDidMount() { }
+
+  setFormData = data => {
+    this.setState({
+      formData: data,
+    });
+  }
+
+  // 新增用户
+  add = () => {
+    this.props.history.push('/baseManage/user/Detail/new/Add')
+  }
+
+  // 微信同步
+  userSync = () => {
+    this.setState({ userSyncLoading: true })
+    fetch({
+      url: `api/user/syncCpUser`
+    }).then(res => {
+      this.setState({ userSyncLoading: false });
+      if (res) {
+        message.success("同步成功!");
+        this.setState({
+          formData: {
+            ...this.state.formData,
+            __key: Date.now()
+          }
+        })
+      }
+    })
+  }
+
+  //表格列显示
+  renderColumns = () => {
+    return [
+      { title: '头像', className: "txt-c", dataIndex: 'avatar', key: 'avatar', render: (text, record) => text ? <image style={{ height: 23, width: 25 }} src={text} /> : <Avatar icon="user" /> },
+      { title: '姓名', className: "txt-c", dataIndex: 'trueName', key: 'trueName' },
+      { title: '身份证', className: "txt-c", dataIndex: 'idcard', key: 'idcard' },
+      { title: '邮箱', className: "txt-c", dataIndex: 'email', key: 'email' },
+      { title: '手机号码', className: "txt-c", dataIndex: 'mobile', key: 'mobile' },
+      { title: '创建时间', className: "txt-c", dataIndex: 'createTime', key: 'createTime', render: (text, record) => text !== "" && text != null ? moment(text).format("YYYY-MM-DD HH:mm") : "" },
+      {
+        title: '操作', className: "txt-c", key: 'operation', render: (text, record) => {
+          return <div>
+            <Link to={{ pathname: "/baseManage/user/Detail/" + record.id + '/Modify', query: { id: record.id } }}>修改</Link>
+            <Divider type="vertical" />
+            <a onClick={() => this.delete(record.id)}>删除</a>
+          </div>
+        }
+      }
+    ]
+  }
+
+  //删除用户
+  delete = (id) => {
+    let _this = this;
+    confirm({
+      title: <span style={{ fontSize: 19 }}>确定要删除该用户吗?</span>,
+      onOk() {
+        fetch({
+          url: 'api/user/delete',
+          params: {
+            ids: id
+          }
+        }).then(res => {
+          if (res) {
+            message.success("删除成功");
+            _this.setState({
+              formData: {
+                ..._this.state.formData,
+                __key: Date.now()
+              }
+            })
+          }
+        })
+      },
+      onCancel() { },
+    });
+  }
+
+  render() {
+    const { formData, userSyncLoading } = this.state;
+    let tableParams = {
+      url: `api/user/query`,
+      formData,
+      key: formData.__key,
+      columns: this.renderColumns(),
+      extraFromData: {},
+      setFormData: this.setFormData
+    }
+
+    return (
+      <div className="usermanage-main margin padding bg-white">
+        <SearchFormView
+          formData={formData}
+          setFormData={this.setFormData}
+          data={[
+            { type: 'input', name: '姓名', label: '姓名', key: 'trueName' },
+            { type: 'input', name: '身份证号码', label: '身份证号码', key: 'idcard' },
+            { type: 'input', name: '手机号码', label: '手机号码', key: 'mobile' },
+            { type: 'input', name: '电子邮箱', label: '电子邮箱', key: 'email' },
+          ]} />
+        <Row type="flex" gutter={20} className="margin-bottom">
+          <Col>
+            <Button type="primary" loading={userSyncLoading} onClick={this.userSync}>同步微信用户</Button>
+          </Col>
+          <Col>
+            <Button type="primary" onClick={this.add}>新增用户</Button>
+          </Col>
+        </Row>
+        <TableView {...tableParams} />
+      </div>
+    )
+  }
+}
diff --git a/src/pages/login/login.jsx b/src/module/login/login.jsx
similarity index 84%
rename from src/pages/login/login.jsx
rename to src/module/login/login.jsx
index 3d77cf0..30856a9 100644
--- a/src/pages/login/login.jsx
+++ b/src/module/login/login.jsx
@@ -10,8 +10,8 @@
 import './login.scss';
 
 import logo from '../../img/logo.png';
-
 import fetch from '../../api/request';
+import { oaMenus, userMenus, getMenuListByPermission } from '../../menu';
 
 class NormalLoginForm extends React.Component {
   constructor(props) {
@@ -66,8 +66,22 @@
       console.log('res', res);
       if (res) {
         window.localStorage.setItem('menu', JSON.stringify(res));
+        window.localStorage.setItem('menusListByRole', JSON.stringify({
+          user: { role: 'user', menus: userMenus },
+          oa: {
+            role: 'oa', menus: getMenuListByPermission(oaMenus, res && res.map(({ symbol }) => (symbol)).concat(res.map(({ moduleSymbol }) => (moduleSymbol))).reduce((p, n) => {
+              if (p.indexOf(n) == -1) {
+                return p.concat(n)
+              } else {
+                return p
+              }
+            }, []))
+          }
+        }));//所有模块菜单
         message.success('登录成功');
-        this.props.history.push({ pathname: "/index" });
+        setTimeout(() => {
+          this.props.history.push({ pathname: "/index" });
+        }, 1500);//延时跳转
       }
     })
   }
@@ -99,7 +113,7 @@
                 <Form.Item className="login-div-content-form-flex">
                   {getFieldDecorator('credential', {
                     rules: [{ required: true, message: '请输入密码!' }],
-                    initialValue: 'admin'
+                    // initialValue: 'admin'
                   })(
                     <Input
                       style={{ width: '300px', height: '48px', margin: '12px' }}
diff --git a/src/pages/login/login.scss b/src/module/login/login.scss
similarity index 100%
rename from src/pages/login/login.scss
rename to src/module/login/login.scss
diff --git a/src/module/menu/menu.jsx b/src/module/menu/menu.jsx
new file mode 100644
index 0000000..8f486c1
--- /dev/null
+++ b/src/module/menu/menu.jsx
@@ -0,0 +1,81 @@
+/* eslint-disable */
+/**柯礼钦
+ * 4/2/2020, 11:22:51 AM
+ * doc comment for the file goes here
+ */
+
+/** 菜单组件 */
+
+import React from 'react';
+import { Spin, Layout, Menu, Icon } from 'antd';
+import MenView from '../../components/common/MenuView';
+import { oaMenus, getMenuListByPermission } from '../../menu';
+import fetch from '../../api/request';
+import { Context } from '../../index';
+
+const { Sider } = Layout;
+
+function find(data, pathname) {
+  for (const { path, children } of data) {
+    if (path === pathname) return path;
+    if (children) {
+      const result = find(children, pathname);
+      if (result) return result;
+    }
+  }
+  return null;
+}
+
+function selected(data, pathname) {
+  if (!pathname || pathname === '/') return pathname;
+  return find(data, pathname) || selected(data, pathname.split('/').slice(0, -1).join('/'));
+}
+
+export default class MenuView extends React.Component {
+  // static contextType = context;
+  constructor(props) {
+    super(props);
+    this.state = {
+      collapsed: true,
+      menusListByRole: null
+    };
+  }
+
+  componentDidMount() {
+    // 获取从登录页面记录在缓存里的菜单数据
+    let menusListByRole = window.localStorage.getItem('menusListByRole') ? JSON.parse(window.localStorage.getItem('menusListByRole')) : null;
+    this.setState({ menusListByRole });
+  }
+
+  onCollapse = collapsed => {
+    this.setState({ collapsed });
+  }
+
+  render() {
+    const { collapsed, menusListByRole } = this.state;
+    return (
+      <Context.Consumer>
+        {({ role }) => (
+          <React.Fragment>
+            <Sider
+              onCollapse={this.onCollapse}
+              collapsed={collapsed}
+              breakpoint="lg"
+              collapsible={true}
+            >
+              {
+                menusListByRole &&
+                <MenView
+                  history={this.props.history}
+                  pathname={selected(menusListByRole[role].menus, this.props.location.pathname)}
+                  menudata={menusListByRole[role].menus || []}
+                />
+              }
+            </Sider>
+          </React.Fragment>
+        )}
+      </Context.Consumer>
+    );
+  }
+
+}
diff --git a/src/pages/document/DocumentDetail.jsx b/src/module/oa/document/DocumentDetail.jsx
similarity index 84%
rename from src/pages/document/DocumentDetail.jsx
rename to src/module/oa/document/DocumentDetail.jsx
index df40271..61e4a38 100644
--- a/src/pages/document/DocumentDetail.jsx
+++ b/src/module/oa/document/DocumentDetail.jsx
@@ -8,8 +8,8 @@
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
 // import { Link } from 'react-router-dom';
 // import { Icon } from 'antd';
-import BreadcrumbView from '../../components/common/BreadcrumbView';
-import DocumentDetailPage from '../../components/page/DocumentDetailPage';
+import BreadcrumbView from '../../../components/common/BreadcrumbView';
+import DocumentDetailPage from '../../../components/oa/DocumentDetailPage';
 
 export default class DocumentDetail extends Component {
   constructor(props) {
diff --git a/src/pages/document/DocumentEdit.jsx b/src/module/oa/document/DocumentEdit.jsx
similarity index 85%
rename from src/pages/document/DocumentEdit.jsx
rename to src/module/oa/document/DocumentEdit.jsx
index e0f05bf..71e9e88 100644
--- a/src/pages/document/DocumentEdit.jsx
+++ b/src/module/oa/document/DocumentEdit.jsx
@@ -8,8 +8,8 @@
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
 // import { Link } from 'react-router-dom';
 // import { Icon } from 'antd';
-import BreadcrumbView from '../../components/common/BreadcrumbView';
-import DocumentEditPage from '../../components/page/DocumentEditPage'
+import BreadcrumbView from '../../../components/common/BreadcrumbView';
+import DocumentEditPage from '../../../components/oa/DocumentEditPage'
 
 export default class DocumentEdit extends Component {
   constructor(props) {
diff --git a/src/pages/index/Announcement.jsx b/src/module/oa/index/Announcement.jsx
similarity index 79%
rename from src/pages/index/Announcement.jsx
rename to src/module/oa/index/Announcement.jsx
index 0462c88..6b2035c 100644
--- a/src/pages/index/Announcement.jsx
+++ b/src/module/oa/index/Announcement.jsx
@@ -6,8 +6,8 @@
 
 /** Happy Coding */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import BreadcrumbView from '../../components/common/BreadcrumbView';
-import AnnouncementPage from '../../components/page/AnnouncementPage'
+import BreadcrumbView from '../../../components/common/BreadcrumbView';
+import AnnouncementPage from '../../../components/oa/AnnouncementPage'
 
 export default class Announcement extends Component {
   constructor(props) {
diff --git a/src/pages/index/System.jsx b/src/module/oa/index/System.jsx
similarity index 79%
rename from src/pages/index/System.jsx
rename to src/module/oa/index/System.jsx
index 0dcf598..4e0b0e0 100644
--- a/src/pages/index/System.jsx
+++ b/src/module/oa/index/System.jsx
@@ -6,8 +6,8 @@
 
 /** Happy Coding */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import BreadcrumbView from '../../components/common/BreadcrumbView';
-import RulesList from '../../components/page/index/rulesList'
+import BreadcrumbView from '../../../components/common/BreadcrumbView';
+import RulesList from '../../../components/oa/index/rulesList'
 
 export default class System extends Component {
   constructor(props) {
diff --git a/src/module/oa/index/workbench.jsx b/src/module/oa/index/workbench.jsx
new file mode 100644
index 0000000..0132823
--- /dev/null
+++ b/src/module/oa/index/workbench.jsx
@@ -0,0 +1,61 @@
+/* eslint-disable */
+/**柯礼钦
+ * 4/6/2020, 10:16:55 AM
+ * doc comment for the file goes here
+ */
+
+/** 首页 -- 工作台 */
+import React, { ReactNode, ReactEventHandler, Component } from 'react';
+import BreadcrumbView from '../../../components/common/BreadcrumbView';
+import WorkbenchPage from '../../../components/oa/index/workbench'
+
+export default class Workbench extends Component {
+  constructor(props) {
+    super(props);
+    this.config = {
+    };
+    this.state = {
+    };
+  }
+
+  componentWillMount() { }
+
+  componentDidMount() {
+    // let _this = this;
+
+    // this.iframeWin = this.refs.iframe.contentWindow;
+    // this.refs.iframe && this.refs.iframe.addEventListener("load", function () {
+    //   //代码能执行到这里说明已经载入成功完毕了
+    //   console.log('执行完');
+    //   //这里是回调函数
+    //   _this.iframeWin.postMessage({
+    //     token: window.localStorage.getItem('token') || undefined
+    //   }, '*');
+    // }, false);
+  }
+
+  componentDidShow() { }
+
+  render() {
+    return (
+      <div className="workbench-page-main flex-box-column">
+        <div className="flex-1">
+          <WorkbenchPage {...this.props} />
+          {/* <iframe
+            className="h-100"
+            style={{ width: '100%' }}
+            onLoad={() => { }}
+            ref="iframe"
+            src={'http://localhost:3000/#/index'}
+            width="100%"
+            height={this.state.iFrameHeight}
+            scrolling="no"
+            frameBorder="0"
+          /> */}
+
+        </div>
+      </div>
+    )
+  }
+}
+
diff --git a/src/pages/logManage/Rawler.jsx b/src/module/oa/logManage/Rawler.jsx
similarity index 88%
rename from src/pages/logManage/Rawler.jsx
rename to src/module/oa/logManage/Rawler.jsx
index 4f26819..d85f9a3 100644
--- a/src/pages/logManage/Rawler.jsx
+++ b/src/module/oa/logManage/Rawler.jsx
@@ -6,7 +6,7 @@
 
 /** 爬虫词条管理 */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import RawlerPage from '../../components/page/logManage/Rawler'
+import RawlerPage from '../../../components/oa/logManage/Rawler'
 
 
 export default class Rawler extends Component {
diff --git a/src/pages/logManage/browseLog.jsx b/src/module/oa/logManage/browseLog.jsx
similarity index 88%
rename from src/pages/logManage/browseLog.jsx
rename to src/module/oa/logManage/browseLog.jsx
index 1c8c204..c2f375d 100644
--- a/src/pages/logManage/browseLog.jsx
+++ b/src/module/oa/logManage/browseLog.jsx
@@ -6,7 +6,7 @@
 
 /** 浏览日志 */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import BrowseLogPage from '../../components/page/logManage/browseLog';
+import BrowseLogPage from '../../../components/oa/logManage/browseLog';
 
 export default class BrowseLog extends Component {
  constructor(props) {
diff --git a/src/pages/logManage/operLog.jsx b/src/module/oa/logManage/operLog.jsx
similarity index 88%
rename from src/pages/logManage/operLog.jsx
rename to src/module/oa/logManage/operLog.jsx
index 7f2d1e9..e2c6aab 100644
--- a/src/pages/logManage/operLog.jsx
+++ b/src/module/oa/logManage/operLog.jsx
@@ -6,7 +6,7 @@
 
 /** 操作日志 */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import OperLogPage from '../../components/page/logManage/operLog'
+import OperLogPage from '../../../components/oa/logManage/operLog'
 
 export default class OperLog extends Component {
  constructor(props) {
diff --git a/src/pages/personal/information.jsx b/src/module/oa/personal/information.jsx
similarity index 90%
rename from src/pages/personal/information.jsx
rename to src/module/oa/personal/information.jsx
index 362e006..4ce97b2 100644
--- a/src/pages/personal/information.jsx
+++ b/src/module/oa/personal/information.jsx
@@ -6,7 +6,7 @@
 
 /** 个人信息 */
 import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import InformationPage from '../../components/page/personal/information';
+import InformationPage from '../../../components/oa/personal/information';
 import { now } from 'moment';
 
 export default class Information extends Component {
diff --git a/src/pages/Index.jsx b/src/pages/Index.jsx
deleted file mode 100644
index 9cbd063..0000000
--- a/src/pages/Index.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * 姓名<example@email.com>
- * 2019年12月10日 17:17
- *
- */
-
-
-import React from 'react';
-// import { Modal } from 'antd-mobile';
-// import { Icon } from 'antd';
-import fetch from '../api/request';
-
-export default class Index extends React.Component {
-  constructor(props) {
-    super(props);
-    this.state = {
-      data: null
-    };
-  }
-
-  componentDidMount() {
-    document.title = 'Index';
-  }
-
-  render() {
-    return (
-      <div className="app-page">
-        Index页面
-      </div>
-    );
-  }
-
-}
diff --git a/src/pages/index/workbench.jsx b/src/pages/index/workbench.jsx
deleted file mode 100644
index aa2fa7d..0000000
--- a/src/pages/index/workbench.jsx
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable */
-/**柯礼钦
- * 4/6/2020, 10:16:55 AM
- * doc comment for the file goes here
- */
-
-/** 首页 -- 工作台 */
-import React, { ReactNode, ReactEventHandler, Component } from 'react';
-import BreadcrumbView from '../../components/common/BreadcrumbView';
-import WorkbenchPage from '../../components/page/index/workbench'
-
-export default class Workbench extends Component {
-  constructor(props) {
-    super(props);
-    this.config = {
-    };
-    this.state = {
-    };
-  }
-
-  componentWillMount() { }
-
-  componentDidMount() { }
-
-  componentDidShow() { }
-
-  render() {
-    return (
-      <div className="workbench-page-main flex-box-column">
-        <div className="flex-1">
-          <WorkbenchPage {...this.props}/>
-        </div>
-      </div>
-    )
-  }
-}
-
diff --git a/src/pages/menu/menu.jsx b/src/pages/menu/menu.jsx
deleted file mode 100644
index 54f24d3..0000000
--- a/src/pages/menu/menu.jsx
+++ /dev/null
@@ -1,81 +0,0 @@
-/* eslint-disable */
-/**柯礼钦
- * 4/2/2020, 11:22:51 AM
- * doc comment for the file goes here
- */
-
-/** 菜单组件 */
-
-import React from 'react';
-import { Spin, Layout, Menu, Icon } from 'antd';
-import MenView from '../../components/common/MenuView';
-import { menus, getMenuListByPermission } from '../../menu';
-import fetch from '../../api/request';
-
-const { Sider } = Layout;
-
-function find(data, pathname) {
-  for (const { path, children } of data) {
-    if (path === pathname) return path;
-    if (children) {
-      const result = find(children, pathname);
-      if (result) return result;
-    }
-  }
-  return null;
-}
-
-function selected(data, pathname) {
-  if (!pathname || pathname === '/') return pathname;
-  return find(data, pathname) || selected(data, pathname.split('/').slice(0, -1).join('/'));
-}
-
-export default class MenuView extends React.Component {
-  constructor(props) {
-    super(props);
-    this.state = {
-      collapsed: true,
-      data: []
-    };
-  }
-
-  componentWillMount() {
-    // 获取从登录页面记录在缓存里的菜单数据
-    let menu = window.localStorage.getItem('menu') ? JSON.parse(window.localStorage.getItem('menu')) : [];
-    let permList = menu && menu.map(({ symbol }) => (symbol)).concat(menu.map(({ moduleSymbol }) => (moduleSymbol))).reduce((p, n) => {
-      if (p.indexOf(n) == -1) {
-        return p.concat(n)
-      } else {
-        return p
-      }
-    }, []);
-    // console.log(getMenuListByPermission(menus, permList) )
-    this.setState({ data: getMenuListByPermission(menus, permList) });
-  }
-  componentDidMount() { }
-
-  onCollapse = collapsed => {
-    this.setState({ collapsed });
-  }
-
-  render() {
-    const { data, collapsed } = this.state;
-    const pathname = selected(data, this.props.location.pathname);
-    return (
-      <Sider
-        onCollapse={this.onCollapse}
-        collapsed={collapsed}
-        breakpoint="lg"
-        collapsible={true}
-      >
-        <MenView
-          history={this.props.history}
-          pathname={pathname}
-          key={data.length}
-          menudata={data}
-        />
-      </Sider>
-    );
-  }
-
-}
diff --git a/src/routeDom/oaRouteDom.jsx b/src/routeDom/oaRouteDom.jsx
new file mode 100644
index 0000000..8533dee
--- /dev/null
+++ b/src/routeDom/oaRouteDom.jsx
@@ -0,0 +1,42 @@
+/* eslint-disable */
+/**liuwh
+ * 5/26/2020, 4:44:40 PM
+ * doc comment for the file goes here
+ */
+
+/** Happy Coding */
+import React, { ReactNode, ReactEventHandler, Component } from 'react';
+import { Switch, Route, Redirect } from 'react-router-dom';
+
+// 引进页面(pages)
+import Login from '../module/login/login';
+import Workbench from '../module/oa/index/workbench'; //首页--工作台
+import System from '../module/oa/index/System'; //首页--工作制度
+import Announcement from '../module/oa/index/Announcement'; //全部通知
+
+import DocumentEdit from '../module/oa/document/DocumentEdit'; //新建文档
+import DocumentDetail from '../module/oa/document/DocumentDetail'; //文档详情
+import BrowseLog from '../module/oa/logManage/browseLog'; //浏览日志
+import OperLog from '../module/oa/logManage/operLog'; //操作日志
+import Rawler from '../module/oa/logManage/Rawler'; //爬虫词条管理
+import Information from '../module/oa/personal/information'; //个人信息
+import UserManage from '../components/oa/basicConfig/UserManage'; //用户管理
+
+export default function OaRouteDom({ }) {
+  return (<Switch>
+    <Route path="/baseManage/user" component={UserManage} />
+    <Route path="/document/create/:id?" component={DocumentEdit} />
+    <Route path="/document/detail/:id" component={DocumentDetail} />
+    <Route path="/index/workbench/announcement" component={Announcement} />
+    <Route path="/index/rules" component={System} />
+    <Route path="/index" component={Workbench} />
+    <Route path="/logManage/browseLog" component={BrowseLog} />
+    <Route path="/logManage/operLog" component={OperLog} />
+    <Route path="/logManage/rawler" component={Rawler} />
+    <Route path="/personal/information" component={Information} />
+    <Route path="/login" component={Login} />
+    {/* <Route path="/" component={Workbench} /> */}
+    <Redirect from="/" to="/index" component={Workbench} />
+  </Switch>
+  )
+}
diff --git a/src/routeDom/userRouteDom.jsx b/src/routeDom/userRouteDom.jsx
new file mode 100644
index 0000000..c18a8c7
--- /dev/null
+++ b/src/routeDom/userRouteDom.jsx
@@ -0,0 +1,47 @@
+/* eslint-disable */
+/**liuwh
+ * 5/26/2020, 4:48:49 PM
+ * doc comment for the file goes here
+ */
+
+/** Happy Coding */
+import React, { ReactNode, ReactEventHandler, Component } from 'react';
+import { Switch, Route, Redirect } from 'react-router-dom';
+
+// 基础平台
+import UserManage from '../module/huge-base/UserManage'; //用户管理
+import UserDetail from '../module/huge-base/UserDetail'; //用户管理--用户详情
+import GroupManage from '../module/huge-base/GroupManage'; //组管理
+import GroupDetail from '../module/huge-base/GroupDetail'; //组管理--组详情
+import UnitManage from '../module/huge-base/UnitManage'; //组织管理--单位管理
+import DepartmentManage from '../module/huge-base/DepartmentManage'; //组织管理--部门管理
+import JobManage from '../module/huge-base/JobManage'; //组织管理--岗位管理
+import AppServiceManage from '../module/huge-base/AppServiceManage'; //资源管理--应用服务管理
+import AppServiceDetail from '../module/huge-base/AppServiceDetail'; //资源管理--应用服务管理详情
+import ModulesManage from '../module/huge-base/ModulesManage'; //资源管理--模块管理
+import FunctionManage from '../module/huge-base/FunctionManage'; //资源管理--功能管理
+import RoleManage from '../module/huge-base/RoleManage'; //权限管理--角色管理
+import RoleDetail from '../module/huge-base/RoleDetail'; //权限管理--角色管理详情
+import AuthorityManage from '../module/huge-base/AuthorityManage';
+
+export default function UserRouteDom({ }) {
+  return (
+    <Switch>
+      <Route path="/baseManage/user/Detail/:id/:flag" component={UserDetail} />
+      <Route path="/baseManage/user" component={UserManage} />
+      <Route path="/baseManage/group/Detail/:id/:flag" component={GroupDetail} />
+      <Route path="/baseManage/group" component={GroupManage} />
+      <Route path="/organizationMgt/unit" component={UnitManage} />
+      <Route path="/organizationMgt/department" component={DepartmentManage} />
+      <Route path="/organizationMgt/job" component={JobManage} />
+      <Route path="/resourceMgt/appService/Detail/:id/:flag" component={AppServiceDetail} />
+      <Route path="/resourceMgt/appService" component={AppServiceManage} />
+      <Route path="/resourceMgt/modules" component={ModulesManage} />
+      <Route path="/resourceMgt/function" component={FunctionManage} />
+      <Route path="/organizationMgt/role/Detail/:id/:flag" component={RoleDetail} />
+      <Route path="/authorityMgt/role" component={RoleManage} />
+      <Route path="/authorityMgt/authority" component={AuthorityManage} />
+      <Redirect from='/' to="/baseManage/user" component={UserManage} />
+    </Switch>
+  )
+}
diff --git a/src/style/reset.scss b/src/style/reset.scss
index 0758323..3ca5aea 100644
--- a/src/style/reset.scss
+++ b/src/style/reset.scss
@@ -19,13 +19,13 @@
   /*滚动条里面小方块*/
   border-radius: 2.5px;
   box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
-  background: #848484;
+  background: #ccc;
 }
 *::-webkit-scrollbar-track {
   /*滚动条里面轨道*/
-  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0 5px #fff;
   border-radius: 2.5px;
-  background: #ededed;
+  background: #fff;
 }
 
 .ant-layout {

--
Gitblit v1.8.0