From c7f79abded9ad2e29f297da4a04a641b96b61c5e Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期六, 12 十月 2019 09:51:22 +0800
Subject: [PATCH] add-datamanage

---
 src/components/tabview/index.jsx                  |   38 +
 src/components/tabview/index.scss                 |   40 +
 package-lock.json                                 |   89 ++
 src/components/header/index.jsx                   |   33 
 src/components/sidemenu/index.scss                |   14 
 src/tabviews/datamanage/modules/search/index.scss |   14 
 src/tabviews/rolemanage/index.scss                |   11 
 src/store/action.js                               |    7 
 src/api/index.js                                  |   69 +-
 config/webpack.config.js                          |    2 
 src/tabviews/datamanage/index.jsx                 |  201 ++++++
 src/tabviews/commontable/index.jsx                |   17 
 src/tabviews/datamanage/modules/action/index.scss |   35 +
 src/utils/utils.js                                |   30 
 src/assets/css/main.scss                          |    9 
 src/index.js                                      |    1 
 src/assets/css/action.scss                        |  191 +++---
 src/tabviews/rolemanage/index.jsx                 |   97 +++
 src/store/reducer.js                              |    8 
 src/store/action-type.js                          |    5 
 src/router/index.js                               |    2 
 src/tabviews/datamanage/modules/action/index.jsx  |  189 ++++++
 src/tabviews/datamanage/modules/search/index.jsx  |  192 ++++++
 src/tabviews/datamanage/modules/table/index.jsx   |  155 +++++
 src/setupProxy.js                                 |   40 +
 src/tabviews/datamanage/modules/table/index.scss  |   79 ++
 src/tabviews/commontable/index.scss               |   14 
 src/components/404/index.scss                     |    1 
 src/views/login/index.scss                        |    8 
 package.json                                      |    5 
 src/tabviews/datamanage/index.scss                |    8 
 src/components/sidemenu/index.jsx                 |   76 +-
 src/views/login/index.jsx                         |   30 
 33 files changed, 1,454 insertions(+), 256 deletions(-)

diff --git a/config/webpack.config.js b/config/webpack.config.js
index 1b851c7..6591fda 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -378,6 +378,7 @@
                       },
                     },
                   ],
+                  // ['import', {libraryName: 'antd', style: true}],
                 ],
                 // This is a feature of `babel-loader` for webpack (not Babel itself).
                 // It enables caching results in ./node_modules/.cache/babel-loader/
@@ -402,6 +403,7 @@
                     require.resolve('babel-preset-react-app/dependencies'),
                     { helpers: true },
                   ],
+                  // ['import',{libraryName:'antd',style:true}],
                 ],
                 cacheDirectory: true,
                 cacheCompression: isEnvProduction,
diff --git a/package-lock.json b/package-lock.json
index a8b812f..c4e85ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2386,6 +2386,15 @@
         "object.assign": "4.1.0"
       }
     },
+    "babel-plugin-import": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-import/-/babel-plugin-import-1.11.0.tgz",
+      "integrity": "sha512-de9dWdU1YjmWRPYurlHRKD2hTd24z0bIQ0/JgyXqLMXML+TsvEkVhtqzOsNtu9MmCuvwBiTTTjZBbZXA1Xu7TQ==",
+      "requires": {
+        "@babel/helper-module-imports": "7.0.0",
+        "@babel/runtime": "7.4.3"
+      }
+    },
     "babel-plugin-istanbul": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
@@ -4996,9 +5005,9 @@
       "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
     },
     "eventemitter3": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
-      "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
+      "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg=="
     },
     "eventlistener": {
       "version": "0.0.1",
@@ -6632,24 +6641,64 @@
       "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q="
     },
     "http-proxy": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
-      "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+      "version": "1.18.0",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
+      "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
       "requires": {
-        "eventemitter3": "3.1.2",
+        "eventemitter3": "4.0.0",
         "follow-redirects": "1.5.10",
         "requires-port": "1.0.0"
       }
     },
     "http-proxy-middleware": {
-      "version": "0.19.1",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
-      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+      "version": "0.20.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.20.0.tgz",
+      "integrity": "sha512-dNJAk71nEJhPiAczQH9hGvE/MT9kEs+zn2Dh+Hi94PGZe1GluQirC7mw5rdREUtWx6qGS1Gu0bZd4qEAg+REgw==",
       "requires": {
-        "http-proxy": "1.17.0",
+        "http-proxy": "1.18.0",
         "is-glob": "4.0.1",
         "lodash": "4.17.15",
-        "micromatch": "3.1.10"
+        "micromatch": "4.0.2"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "requires": {
+            "fill-range": "7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "requires": {
+            "to-regex-range": "5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "requires": {
+            "braces": "3.0.2",
+            "picomatch": "2.0.7"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "requires": {
+            "is-number": "7.0.0"
+          }
+        }
       }
     },
     "http-signature": {
@@ -9679,6 +9728,11 @@
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+    },
+    "picomatch": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz",
+      "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA=="
     },
     "pify": {
       "version": "2.3.0",
@@ -14057,6 +14111,17 @@
             "locate-path": "3.0.0"
           }
         },
+        "http-proxy-middleware": {
+          "version": "0.19.1",
+          "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+          "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+          "requires": {
+            "http-proxy": "1.18.0",
+            "is-glob": "4.0.1",
+            "lodash": "4.17.15",
+            "micromatch": "3.1.10"
+          }
+        },
         "invert-kv": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
diff --git a/package.json b/package.json
index 1b8cbdc..18d63ef 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
     "babel-eslint": "10.0.2",
     "babel-jest": "^24.8.0",
     "babel-loader": "8.0.6",
+    "babel-plugin-import": "^1.11.0",
     "babel-plugin-named-asset-import": "^0.3.3",
     "babel-preset-react-app": "9.0.0",
     "camelcase": "^5.2.0",
@@ -30,6 +31,7 @@
     "file-loader": "3.0.1",
     "fs-extra": "7.0.1",
     "html-webpack-plugin": "4.0.0-beta.5",
+    "http-proxy-middleware": "^0.20.0",
     "identity-obj-proxy": "3.0.0",
     "immutable": "^4.0.0-rc.12",
     "is-wsl": "^1.1.0",
@@ -141,7 +143,8 @@
   "babel": {
     "presets": [
       "react-app"
-    ]
+    ],
+    "plugins": [["import", { "libraryName": "antd", "style": "css" }]]
   },
   "homepage": "."
 }
diff --git a/src/api/index.js b/src/api/index.js
index bdfc7bf..b494a97 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -1,6 +1,7 @@
 import axios from 'axios'
 import qs from 'qs'
 
+// axios.defaults.baseURL = 'http://qingqiumarket.cn'
 axios.defaults.crossDomain = true
 // axios.defaults.headers.common['token'] = 'token'
 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
@@ -29,9 +30,9 @@
 class Api {
   constructor() {
     if (process.env.NODE_ENV === 'production') {
-      axios.defaults.baseURL = document.location.origin + '/MKWMS'
+      axios.defaults.baseURL = document.location.origin
     } else {
-      axios.defaults.baseURL = 'http://127.0.0.1:8888'
+      // axios.defaults.baseURL = 'http://127.0.0.1:8888'
     }
   }
 
@@ -40,9 +41,9 @@
    */
   systemauth (appId, timestamp) {
     return axios({
-      // url: 'http://minkesoft.com/mksepc/webapi/dostar',
-      url: '/mksepc',
+      url: '/webapi/dostar',
       data: {
+        rduri: 'http://minkesoft.com/mksepc/webapi/dostar',
         func: 'sEmpowerCloud_Get_LinkUrl',
         userid: '',
         AppID: appId,
@@ -51,25 +52,12 @@
     })
   }
   
-  // /**
-  //  * @description 鐧诲綍绯荤粺
-  //  */
-  // loginsystem (username, password) {
-  //   return axios({
-  //     url: 'http://qingqiumarket.cn/MKWMS/zh-CN/Home/LoginAndRedirect',
-  //     data: {
-  //       Username: username,
-  //       Password: password
-  //     }
-  //   })
-  // }
-
   /**
    * @description 鐧诲綍绯荤粺
    */
   loginsystem (username, password) {
     return axios({
-      url: '/login',
+      url: '/zh-CN/Home/LoginAndRedirect',
       data: {
         Username: username,
         Password: password
@@ -82,7 +70,7 @@
    */
   logoutsystem () {
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
       data: {
         func: 'logout',
         userid: sessionStorage.getItem('UserID')
@@ -95,7 +83,7 @@
    */
   resetpassword (originpwd, newpwd) {
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
       data: {
         func: 'ResetPassword',
         userid: sessionStorage.getItem('UserID'),
@@ -110,10 +98,13 @@
    */
   getMainMenuData () {
     return axios({
-      url: '/dostar',
+      url: '/webapi/dostar',
       data: {
-        func: 'GetTopMenus',
-        userid: sessionStorage.getItem('UserID')
+        func: 'sPC_Get_MainMenu',
+        userid: sessionStorage.getItem('UserID'),
+        lang: localStorage.getItem('lang') || '',
+        SessionUid: sessionStorage.getItem('SessionUid') || '',
+        LoginUID: sessionStorage.getItem('LoginUID') || ''
       }
     })
   }
@@ -124,10 +115,13 @@
    */
   getSubMenuData (menuId) {
     return axios({
-      url: '/dostar',
+      url: '/webapi/dostar',
       data: {
-        func: 'GetSubMenus',
+        func: 'sPC_Get_FunMenu',
         userid: sessionStorage.getItem('UserID'),
+        lang: localStorage.getItem('lang') || '',
+        SessionUid: sessionStorage.getItem('SessionUid') || '',
+        LoginUID: sessionStorage.getItem('LoginUID') || '',
         ParentID: menuId
       }
     })
@@ -139,7 +133,7 @@
    */
   getMainConfigsData (MenuNo) {
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
       data: {
         func: 'GetMainConfigs',
         userid: sessionStorage.getItem('UserID'),
@@ -154,7 +148,7 @@
    */
   getMainTableData (MenuNo, pageIndex = 1, pageSize = 10, orderColumn = '', orderType = '', search) {
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
       data: {
         func: 'GetMainData',
         userid: sessionStorage.getItem('UserID'),
@@ -174,7 +168,7 @@
    */
   getModelFormData (MenuNo) {
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
       data: {
         func: 'getModelFormData',
         userid: sessionStorage.getItem('UserID'),
@@ -190,7 +184,24 @@
   setActionSubmit (param) {
     param.userid = sessionStorage.getItem('UserID')
     return axios({
-      url: '/dostar',
+      url: '/local/dostar',
+      data: param
+    })
+  }
+
+  /**
+   * @description 閫氱敤鎺ュ彛
+   * @param {Object} param 鏌ヨ鍙婃彁浜ゅ弬鏁�
+   */
+  commonInterface (param) {
+    param.userid = sessionStorage.getItem('UserID')
+    param.lang = localStorage.getItem('lang') || ''
+    param.SessionUid = sessionStorage.getItem('SessionUid') || ''
+    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
+    param.BID = param.BID || ''
+    param.debug = param.debug || ''
+    return axios({
+      url: '/webapi/dostar',
       data: param
     })
   }
diff --git a/src/assets/css/action.scss b/src/assets/css/action.scss
index 46d850f..d4ea94c 100644
--- a/src/assets/css/action.scss
+++ b/src/assets/css/action.scss
@@ -1,107 +1,116 @@
-.mk-btn:hover {
-  opacity: 0.8;
-}
+#root {
+  .mk-btn:hover {
+    opacity: 0.8;
+  }
 
-// 钃濊壊
-.mk-primary, .mk-primary:hover, .mk-primary:active, .mk-primary:focus {
-  color: #fff;
-  background-color: #1890ff;
-  border-color: #1890ff;
-}
+  // 钃濊壊
+  .mk-primary, .mk-primary:hover, .mk-primary:active, .mk-primary:focus {
+    color: #fff;
+    background-color: #1890ff;
+    border-color: #1890ff;
+  }
 
-.mk-border-primary, .mk-border-primary:hover, .mk-border-primary:active, .mk-border-primary:focus {
-  color: #1890ff;
-  background-color: #fff;
-  border-color: #1890ff;
-}
+  .mk-border-primary, .mk-border-primary:hover, .mk-border-primary:active, .mk-border-primary:focus {
+    color: #1890ff;
+    background-color: #fff;
+    border-color: #1890ff;
+  }
 
-// 榛樿涓庤櫄绾�
-.mk-default, .mk-default:hover, .mk-default:active, .mk-default:focus {
-  color: rgba(0, 0, 0, 0.65);
-  background-color: #fff;
-  border-color: #d9d9d9;
-}
+  // 榛樿涓庤櫄绾�
+  .mk-default, .mk-default:hover, .mk-default:active, .mk-default:focus {
+    color: rgba(0, 0, 0, 0.65);
+    background-color: #fff;
+    border-color: #d9d9d9;
+  }
 
-.mk-dashed, .mk-dashed:hover, .mk-dashed:active, .mk-dashed:focus {
-  color: rgba(0, 0, 0, 0.65);
-  background-color: #fff;
-  border-color: #d9d9d9;
-  border-style: dashed;
-}
+  .mk-dashed, .mk-dashed:hover, .mk-dashed:active, .mk-dashed:focus {
+    color: rgba(0, 0, 0, 0.65);
+    background-color: #fff;
+    border-color: #d9d9d9;
+    border-style: dashed;
+  }
 
-.mk-default:hover, .mk-dashed:hover {
-  color: #096dd9;
-  border-color: #096dd9;
-}
+  .mk-default:hover, .mk-dashed:hover {
+    color: #096dd9;
+    border-color: #096dd9;
+  }
 
-// 绾㈣壊
-.mk-danger, .mk-danger:hover, .mk-danger:active, .mk-danger:focus {
-  color: #fff;
-  background-color: #ff4d4f;
-  border-color: #ff4d4f;
-}
+  // 绾㈣壊
+  .mk-danger, .mk-danger:hover, .mk-danger:active, .mk-danger:focus {
+    color: #fff;
+    background-color: #ff4d4f;
+    border-color: #ff4d4f;
+  }
 
-.mk-border-danger, .mk-border-danger:hover, .mk-border-danger:active, .mk-border-danger:focus {
-  color: #ff4d4f;
-  background-color: #fff;
-  border-color: #ff4d4f;
-}
+  // 绾㈣壊
+  .mk-red, .mk-red:hover, .mk-red:active, .mk-red:focus {
+    color: #fff;
+    background-color: #ff4d4f;
+    border-color: #ff4d4f;
+  }
 
-// 缁胯壊
-.mk-green, .mk-green:hover, .mk-green:active, .mk-green:focus {
-  color: #FFF;
-  background-color: #26C281;
-  border-color: #26C281;
-}
+  .mk-border-danger, .mk-border-danger:hover, .mk-border-danger:active, .mk-border-danger:focus {
+    color: #ff4d4f;
+    background-color: #fff;
+    border-color: #ff4d4f;
+  }
 
-.mk-border-green, .mk-border-green:hover, .mk-border-green:active, .mk-border-green:focus {
-  color: #26C281;
-  background-color: #fff;
-  border-color: #26C281;
-}
+  // 缁胯壊
+  .mk-green, .mk-green:hover, .mk-green:active, .mk-green:focus {
+    color: #FFF;
+    background-color: #26C281;
+    border-color: #26C281;
+  }
 
-// 娣辩豢鑹�
-.mk-dgreen, .mk-dgreen:hover, .mk-dgreen:active, .mk-dgreen:focus {
-  color: #FFF;
-  background-color: #32c5d2;
-  border-color: #32c5d2;
-}
+  .mk-border-green, .mk-border-green:hover, .mk-border-green:active, .mk-border-green:focus {
+    color: #26C281;
+    background-color: #fff;
+    border-color: #26C281;
+  }
 
-.mk-border-dgreen, .mk-border-dgreen:hover, .mk-border-dgreen:active, .mk-border-dgreen:focus {
-  color: #32c5d2;
-  background-color: #fff;
-  border-color: #32c5d2;
-}
+  // 娣辩豢鑹�
+  .mk-dgreen, .mk-dgreen:hover, .mk-dgreen:active, .mk-dgreen:focus {
+    color: #FFF;
+    background-color: #32c5d2;
+    border-color: #32c5d2;
+  }
 
-// 绱壊
-.mk-purple, .mk-purple:hover, .mk-purple:active, .mk-purple:focus {
-  color: #fff;
-  background-color: #8E44AD;
-  border-color: #8E44AD;
-}
+  .mk-border-dgreen, .mk-border-dgreen:hover, .mk-border-dgreen:active, .mk-border-dgreen:focus {
+    color: #32c5d2;
+    background-color: #fff;
+    border-color: #32c5d2;
+  }
 
-.mk-border-purple, .mk-border-purple:hover, .mk-border-purple:active, .mk-border-purple:focus {
-  color: #8E44AD;
-  background-color: #fff;
-  border-color: #8E44AD;
-}
+  // 绱壊
+  .mk-purple, .mk-purple:hover, .mk-purple:active, .mk-purple:focus {
+    color: #fff;
+    background-color: #8E44AD;
+    border-color: #8E44AD;
+  }
 
-// 榛勮壊
-.mk-yellow, .mk-yellow:hover, .mk-yellow:active, .mk-yellow:focus {
-  color: #fff;
-  background-color: #c49f47;
-  border-color: #c49f47;
-}
+  .mk-border-purple, .mk-border-purple:hover, .mk-border-purple:active, .mk-border-purple:focus {
+    color: #8E44AD;
+    background-color: #fff;
+    border-color: #8E44AD;
+  }
 
-.mk-border-yellow, .mk-border-yellow:hover, .mk-border-yellow:active, .mk-border-yellow:focus {
-  color: #c49f47;
-  background-color: #fff;
-  border-color: #c49f47;
-}
+  // 榛勮壊
+  .mk-yellow, .mk-yellow:hover, .mk-yellow:active, .mk-yellow:focus {
+    color: #fff;
+    background-color: #c49f47;
+    border-color: #c49f47;
+  }
 
-// 鐏拌壊
-.mk-gray, .mk-gray:hover, .mk-gray:active, .mk-gray:focus {
-  color: #666;
-  background-color: #e1e5ec;
-  border-color: #e1e5ec;
-}
+  .mk-border-yellow, .mk-border-yellow:hover, .mk-border-yellow:active, .mk-border-yellow:focus {
+    color: #c49f47;
+    background-color: #fff;
+    border-color: #c49f47;
+  }
+
+  // 鐏拌壊
+  .mk-gray, .mk-gray:hover, .mk-gray:active, .mk-gray:focus {
+    color: #666;
+    background-color: #e1e5ec;
+    border-color: #e1e5ec;
+  }
+}
\ No newline at end of file
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 2f1db58..09d453b 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -49,11 +49,11 @@
   /*ios绂佹椤甸潰鍦ㄦ柊绐楀彛鎵撳紑*/
   -webkit-touch-callout: none;
 }
-.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
+.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item.ant-menu-item-selected {
   background-color: unset;
   color: unset;
 }
-.side-menu.ant-menu-dark .ant-menu-item-selected {
+.side-menu.ant-menu-dark .ant-menu-item.ant-menu-item-selected {
   background-color: unset;
   color: unset;
 }
@@ -79,3 +79,8 @@
   border: 1px solid rgba(0, 0, 0, 0.07);
   background: rgba(0, 0, 0, 0);
 }
+
+.ant-message {
+  top: 50px;
+  z-index: 1080;
+}
diff --git a/src/components/404/index.scss b/src/components/404/index.scss
index 06f7707..d853ab0 100644
--- a/src/components/404/index.scss
+++ b/src/components/404/index.scss
@@ -1,3 +1,4 @@
 .box404 {
   max-height: calc(100vh - 110px);
+  text-align: center;
 }
\ No newline at end of file
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 993a191..8673e4c 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -5,11 +5,12 @@
 import { is, fromJS } from 'immutable'
 import {Dropdown, Menu, Icon, Modal, message, Form } from 'antd'
 import md5 from 'md5'
-import {toggleCollapse, modifyMainMenu, resetState} from '@/store/action'
+import {toggleCollapse, modifyMainMenu, resetState, resetDebug} from '@/store/action'
 import Resetpwd from '@/components/resetpwd'
 import Api from '@/api'
 import zhCN from '@/locales/zh-CN/header.js'
 import enUS from '@/locales/en-US/header.js'
+import Utils from '@/utils/utils.js'
 import logourl from '../../assets/img/mlogo.png'
 import avatar from '../../assets/img/avatar.jpg'
 import './index.scss'
@@ -28,7 +29,8 @@
     menulist: null,
     visible: false,
     dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
-    confirmLoading: false
+    confirmLoading: false,
+    userName: localStorage.getItem('username')
   }
 
   handleCollapse = () => {
@@ -118,14 +120,20 @@
     // 鑾峰彇涓昏彍鍗�
     let result = await Api.getMainMenuData()
     if (result.status) {
-      this.setState({
-        menulist: result.data
-      })
+      let _avatar = Utils.getrealurl(result.HeadIcon) // 澶村儚
+      if (_avatar) {
+        avatar = _avatar
+      }
+
+      if (result.debug === 'true') { // 鏄惁涓篸ebug妯″紡锛屽嵆鍙鍒惰彍鍗曞弬鏁�
+        this.props.resetDebug()
+      }
+
       let param = sessionStorage.getItem('view_param') // 鏄惁涓烘墦寮�鏂伴〉闈�
       if (param) {
         // 閫氳繃url涓璵enuid绛涢�夊嚭閫変腑鐨勪富鑿滃崟
-        let id = param.split('&')[0]
-        let _menu = result.data.filter(item => item.MenuID === id)[0]
+        let menuId = param.split('&')[0]
+        let _menu = result.data.filter(item => item.MenuID === menuId)[0]
         if (!_menu) {
           sessionStorage.removeItem('view_param')
         }
@@ -133,6 +141,10 @@
       } else {
         this.props.modifyMainMenu(result.data[0])
       }
+
+      this.setState({
+        menulist: result.data
+      })
     }
   }
   
@@ -162,7 +174,7 @@
         {this.state.menulist && <ul className="header-menu">{
           this.state.menulist.map(item => {
             return (
-              <li key={item.id} onClick={() => {this.changeMenu(item)}} className={this.props.selectmenu.id === item.id ? 'active' : ''}>
+              <li key={item.MenuID} onClick={() => {this.changeMenu(item)}} className={this.props.selectmenu.MenuID === item.MenuID ? 'active' : ''}>
                 {item.MenuName}
               </li>
             )
@@ -172,7 +184,7 @@
           <div>
             <img src={avatar} alt=""/>
             <span>
-              admin <Icon type="down" />
+              {this.state.userName} <Icon type="down" />
             </span>
           </div>
         </Dropdown>
@@ -203,7 +215,8 @@
   return {
     toggleCollapse: (collapse) => dispatch(toggleCollapse(collapse)),
     modifyMainMenu: (selectmenu) => dispatch(modifyMainMenu(selectmenu)),
-    resetState: () => dispatch(resetState())
+    resetState: () => dispatch(resetState()),
+    resetDebug: () => dispatch(resetDebug())
   }
 }
 
diff --git a/src/components/sidemenu/index.jsx b/src/components/sidemenu/index.jsx
index 7c2449f..6d3366e 100644
--- a/src/components/sidemenu/index.jsx
+++ b/src/components/sidemenu/index.jsx
@@ -38,20 +38,30 @@
         tabindex = parseInt(param[2])
         sessionStorage.removeItem('view_param')
       }
+      let parentID = result.data[submenuindex] ? result.data[submenuindex].ParentID : '' // 灞曞紑浜岀骇鑿滃崟ID
 
       this.setState({
         subMenulist: result.data.map((item, i) => {
-          if (item.children) {
-            item.children = item.children.map((child, n) => {
+          if (item.FunMenu) {
+            item.children = item.FunMenu.map((child, n) => {
               let _msg = window.btoa(menu.MenuID + '&' + i + '&' + n + '&' + msg) // 寰呭畬鍠�
               child.src = '#/main/' + _msg
+              if (child.LinkUrl === 'CommonTable') {
+                child.type = 'CommonTable'
+              } else if (child.LinkUrl === 'DataManage') {
+                child.type = 'DataManage'
+              } else if (child.LinkUrl === 'bda/rdt?pageno=rolemenus&MenuNo=RoleMenuM') {
+                child.type = 'RoleManage'
+              } else if (child.LinkUrl.split('?')[0] === 'Main/Index' || child.LinkUrl.split('?')[0] === 'bda/rdt') {
+                child.type = 'iframe'
+              }
               return child
             })
           }
           return item
         }),
-        rootSubmenuKeys: result.data.map(item => item.id),
-        openKeys: this.props.collapse ? [] : [result.data[submenuindex].id]
+        rootSubmenuKeys: result.data.map(item => item.ParentID),
+        openKeys: (this.props.collapse || !parentID) ? [] : [parentID]
       })
 
       if (tabindex !== null) {
@@ -64,15 +74,23 @@
 
   changemenu(e) {
     let menu = JSON.parse(e.target.dataset.item)
-    let tabs = JSON.parse(JSON.stringify(this.props.tabviews))
-    tabs = tabs.filter(tab => {
-      tab.selected = false
-      return tab.MenuID !== menu.MenuID
-    })
-    menu.selected = true
-    tabs.push(menu)
-    this.props.modifyTabview(tabs)
-    e.preventDefault()
+    if (menu.Ot === 'NewPage') {
+      window.open(menu.src)
+    } else if (menu.Ot === 'blank') {
+      menu.selected = true
+      this.props.modifyTabview([menu])
+      e.preventDefault()
+    } else {
+      let tabs = JSON.parse(JSON.stringify(this.props.tabviews))
+      tabs = tabs.filter(tab => {
+        tab.selected = false
+        return tab.MenuID !== menu.MenuID
+      })
+      menu.selected = true
+      tabs.push(menu)
+      this.props.modifyTabview(tabs)
+      e.preventDefault()
+    }
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
@@ -96,30 +114,6 @@
     }
   }
 
-  // componentDidMount () {
-  //   this.props.modifyTabview([{
-  //     Action: "Index",
-  //     Deleted: "0",
-  //     IsButton: "0",
-  //     LinkUrl: "Main/Index?MenuNo=SRMPurchaseOrderM",
-  //     MenuID: "MM02130020118001000170",
-  //     MenuName: "閲囪喘鍗曠鐞�",
-  //     MenuNo: "SRMPurchaseOrderM",
-  //     Ot: "",
-  //     ParentID: "MM021300201180010",
-  //     Remark: "",
-  //     Sort: "100",
-  //     icon: "Content/Upload/2018-07-02/2018070216084721656911_199046432321408044.png",
-  //     id: "MM02130020118001000170",
-  //     pid: "MM021300201180010",
-  //     sIcon: "Content/Upload/2018-07-02/2018070216084721656911_199046432321408044.png",
-  //     selected: true,
-  //     src: "#/main/MCYwJjAmVTAwMDAwMDAwMSZudWxs",
-  //     text: "閲囪喘鍗曠鐞�",
-  //     url: null
-  //   }])
-  // }
-
   onOpenChange = openKeys => {
     const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1)
     if (this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
@@ -138,17 +132,17 @@
           {this.state.subMenulist.map(item => {
             return (
               <SubMenu
-                key={item.id}
+                key={item.ParentID}
                 title={
                   <span>
-                    {item.icon ? <Icon type={item.icon} /> : <Icon type="folder" />}
-                    <span>{item.MenuName}</span>
+                    {item.IconP ? <Icon type={item.IconP} /> : <Icon type="folder" />}
+                    <span>{item.MenuNameP}</span>
                   </span>
                 }
               >
                 {item.children.map(cell => {
                   return (
-                    <Menu.Item key={cell.id}>
+                    <Menu.Item key={cell.MenuID}>
                       <a href={cell.src} id={cell.MenuID} data-item={JSON.stringify(cell)} onClick={this.changemenu.bind(this)}>{cell.MenuName}</a>
                     </Menu.Item>
                   )
diff --git a/src/components/sidemenu/index.scss b/src/components/sidemenu/index.scss
index 7dc3e0e..cc53193 100644
--- a/src/components/sidemenu/index.scss
+++ b/src/components/sidemenu/index.scss
@@ -14,16 +14,22 @@
       padding-left: 48px;
     }
   }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item { // 閲嶇疆涓夌骇鑿滃崟琛岄珮
+    height: 30px;
+    line-height: 30px;
+  }
+  .ant-menu-inline .ant-menu-item {
+    font-size: 1.5rem;
+  }
 }
-.side-menu.iframe {
-  // height: 100%;
+.side-menu.iframe { // tab椤典腑涓篿frame鏃�
   max-height: 100vh;
   overflow-y: scroll;
   &::-webkit-scrollbar {
     display: none;
   }
 }
-.side-menu.side-menu-collapsed {
+.side-menu.side-menu-collapsed { // 宸︿晶鑿滃崟鍚堝苟鏃�
   flex: 0 0 80px;
   width: 80px;
 }
@@ -37,6 +43,8 @@
 
 .ant-menu-vertical .ant-menu-item {
   cursor: default;
+  height: 30px;
+  line-height: 30px;
   a {
     cursor: pointer;
   }
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 3699fc6..1fa9c17 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -2,12 +2,14 @@
 import PropTypes from 'prop-types'
 import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
-import {Tabs, Icon, ConfigProvider} from 'antd'
+import {Tabs, Icon, Button, ConfigProvider, message} from 'antd'
 import {modifyTabview, toggleIsiframe} from '@/store/action'
 import asyncComponent from '@/utils/asyncComponent'
 import NotFount from '@/components/404'
 import enUS from 'antd/es/locale/en_US'
 import zhCN from 'antd/es/locale/zh_CN'
+import mzhCN from '@/locales/zh-CN/main.js'
+import menUS from '@/locales/en-US/main.js'
 import moment from 'moment'
 import 'moment/locale/zh-cn'
 import './index.scss'
@@ -24,6 +26,7 @@
   state = {
     selectedTabId: '', // 褰撳墠閫変腑tab椤甸潰
     iFrameHeight: 0,
+    dict: (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') ? mzhCN : menUS,
     locale: (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS
   }
 
@@ -55,9 +58,13 @@
 
   selectcomponent (view) {
     // 鏍规嵁tab椤典腑鑿滃崟淇℃伅锛岄�夋嫨鎵�闇�鐨勭粍浠�
-    if (view.Remark === 'CommonTable') {
+    if (view.type === 'CommonTable') {
       return (<Comps.CommonTable MenuNo={view.MenuNo} key={view.MenuID}/>)
-    } else if (view.LinkUrl.split('?')[0] === 'Main/Index') {
+    } else if (view.type === 'DataManage') {
+      return (<Comps.DataManage MenuNo={view.MenuNo} key={view.MenuID}/>)
+    } else if (view.type === 'RoleManage') {
+      return (<Comps.RoleManage MenuNo={view.MenuNo} key={view.MenuID}/>)
+    } else if (view.type === 'iframe') {
       return (<Comps.Iframe key={view.MenuID} title={view.MenuName} url={'http://qingqiumarket.cn/MKWMS/zh-CN/' + view.LinkUrl}/>)
     } else {
       return (<NotFount key={view.MenuID} />)
@@ -68,9 +75,7 @@
     // 绐楀彛鍦╥frame涓庢櫘閫氶〉闈㈠垏鎹㈡椂锛屼慨鏀瑰乏渚ц彍鍗曟爮鏍峰紡
     if (!view) return
     let _isiframe = this.props.isiframe
-    if (view && view.Remark === 'CommonTable') {
-      _isiframe = false
-    } else if (view && view.LinkUrl.split('?')[0] === 'Main/Index') {
+    if (view && view.type === 'iframe') {
       _isiframe = true
     } else {
       _isiframe = false
@@ -79,6 +84,18 @@
     if (_isiframe !== this.props.isiframe) {
       this.props.toggleIsiframe(_isiframe)
     }
+  }
+
+  copyMenuNo = (e) => {
+    e.stopPropagation()
+    let oInput = document.createElement('input')
+    oInput.value = e.target.dataset.menuno || ''
+    document.body.appendChild(oInput)
+    oInput.select()
+    document.execCommand('Copy')
+    oInput.className = 'oInput'
+    oInput.style.display='none'
+    message.success(this.state.dict['main.copy.success'])
   }
 
   UNSAFE_componentWillMount () {
@@ -95,10 +112,14 @@
       if (nextProps.tabviews.length > this.props.tabviews.length) {
         // 鏌ョ湅鏂皌ab椤甸渶瑕佺粍浠舵槸鍚﹀姞杞�
         let newtab = nextProps.tabviews[nextProps.tabviews.length - 1]
-        if (!Comps.CommonTable && newtab.Remark === 'CommonTable') {
+        if (!Comps.CommonTable && newtab.type === 'CommonTable') {
           Comps.CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
-        } else if (!Comps.Iframe && newtab.LinkUrl.split('?')[0] === 'Main/Index') {
+        } else if (!Comps.Iframe && newtab.type === 'iframe') {
           Comps.Iframe = asyncComponent(() => import('@/tabviews/iframe'))
+        } else if (!Comps.DataManage && newtab.type === 'DataManage') {
+          Comps.DataManage = asyncComponent(() => import('@/tabviews/datamanage'))
+        } else if (!Comps.DataManage && newtab.type === 'RoleManage') {
+          Comps.RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
         }
       }
 
@@ -138,6 +159,7 @@
                       key={view.MenuID}
                     >
                       {this.selectcomponent(view)}
+                      <Button className={'main-copy ' + (view.type === 'iframe' ? 'ifr-copy' : '')} icon="copy" data-menuno={view.MenuNo} onClick={this.copyMenuNo} shape="circle" />
                     </Tabs.TabPane>
                   )
                 })}
diff --git a/src/components/tabview/index.scss b/src/components/tabview/index.scss
index 25ec811..a506fe2 100644
--- a/src/components/tabview/index.scss
+++ b/src/components/tabview/index.scss
@@ -5,9 +5,12 @@
   .content-header {
     width: 100%;
     height: 100%;
-    // .ant-tabs .ant-tabs-top-content.ant-tabs-content-animated {
-    //   transition: margin-left 0s cubic-bezier(0.645, 0.045, 0.355, 1);
-    // }
+    .ant-tabs .ant-tabs-top-content.ant-tabs-content-animated {
+      transition: margin-left 0s cubic-bezier(0.645, 0.045, 0.355, 1);
+    }
+    .ant-tabs-bar { // 鍘婚櫎鏍囩椤礹eader涓巆ontent涔嬮棿鐨勯棿闅�
+      margin-bottom: 0;
+    }
     .ant-tabs-tab {
       padding: 18px 16px 6px;
       cursor: default;
@@ -28,9 +31,40 @@
       height: calc(100vh - 115px);
       overflow-y: scroll;
       border: 0;
+      margin-top: 16px;
     }
+  }
+  .main-copy {
+    position: fixed;
+    z-index: 2;
+    bottom: 75px;
+    right: 30px;
+    width: 40px;
+    height: 40px;
+    i {
+      font-size: 18px;
+    }
+  }
+  .main-copy.ifr-copy {
+    bottom: 65px;
+    right: 40px;
+    width: 30px;
+    height: 32px;
+    border: 2px solid #687991;
+    opacity: 0.6;
+    i {
+      font-size: 14px;
+      color: #687991;
+    }
+  }
+  .main-copy.ifr-copy:hover {
+    opacity: 1;
   }
 }
 .content-box.collapsed {
   max-width: calc(100% - 80px);
+}
+.ant-message {
+  top: 50px;
+  z-index: 1080;
 }
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index e13361a..e6799be 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,7 +4,6 @@
 import {Provider} from 'react-redux'
 import store from '@/store'
 import * as serviceWorker from './serviceWorker'
-import 'antd/dist/antd.css'
 import '@/assets/css/main.scss'
 import '@/assets/css/action.scss'
 
diff --git a/src/router/index.js b/src/router/index.js
index d24638a..a28c284 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -58,7 +58,7 @@
               )
             })
           }
-          <Redirect exact from="/" to="main"/>
+          <Redirect exact from="/" to="login"/>
           <Route component= {NotFound}/>
         </Switch>
       </HashRouter>
diff --git a/src/setupProxy.js b/src/setupProxy.js
new file mode 100644
index 0000000..f358dbc
--- /dev/null
+++ b/src/setupProxy.js
@@ -0,0 +1,40 @@
+const proxy = require('http-proxy-middleware')
+
+module.exports = function(app) {
+  app.use(proxy('/webapi', { 
+    target: 'http://qingqiumarket.cn/MKWMS/webapi',
+    secure: false,
+    changeOrigin: true,
+    pathRewrite: {
+    '^/webapi': '/'
+    }
+    // cookieDomainRewrite: "http://localhost:3000"
+  }))
+  
+  app.use(proxy('/zh-CN', { // 鐧诲綍鎺ュ彛
+    target: 'http://qingqiumarket.cn/MKWMS/zh-CN',
+    secure: false,
+    changeOrigin: true,
+    pathRewrite: {
+    '^/zh-CN': '/'
+    }
+  }))
+
+  app.use(proxy('/mksepc', { 
+    target: 'http://minkesoft.com/mksepc',
+    secure: false,
+    changeOrigin: true,
+    pathRewrite: {
+    '^/mksepc': '/'
+    }
+  }))
+
+  app.use(proxy('/local', { 
+    target: 'http://127.0.0.1:8888',
+    secure: false,
+    changeOrigin: true,
+    pathRewrite: {
+    '^/local': '/'
+    }
+  }))
+}
\ No newline at end of file
diff --git a/src/store/action-type.js b/src/store/action-type.js
index 6d1782c..83e8c0e 100644
--- a/src/store/action-type.js
+++ b/src/store/action-type.js
@@ -11,4 +11,7 @@
 export const TOGGLE_ISIFRAME = 'TOGGLE_ISIFRAME'
 
 // 閫�鍑虹郴缁熸椂鍙傛暟閲嶇疆
-export const RESET_STATE = 'RESET_STATE'
\ No newline at end of file
+export const RESET_STATE = 'RESET_STATE'
+
+// 淇敼缂栬緫妯″紡
+export const RESET_DEBUG = 'RESET_DEBUG'
\ No newline at end of file
diff --git a/src/store/action.js b/src/store/action.js
index 7f753ac..2f9efce 100644
--- a/src/store/action.js
+++ b/src/store/action.js
@@ -37,4 +37,11 @@
   return {
     type: user.RESET_STATE
   }
+}
+
+// 閫�鍑虹郴缁熸椂鍙傛暟閲嶇疆
+export const resetDebug = () => {
+  return {
+    type: user.RESET_DEBUG
+  }
 }
\ No newline at end of file
diff --git a/src/store/reducer.js b/src/store/reducer.js
index b38d113..7ef0bcf 100644
--- a/src/store/reducer.js
+++ b/src/store/reducer.js
@@ -4,7 +4,8 @@
   selectedMainMenu: '', // 宸查�変富鑿滃崟
   tabviews: [], // 瀵艰埅鏍�
   collapse: false, // 鏄惁鏀惰捣渚ц竟鏍忓鑸�
-  isiframe: false // 鏄惁涓篿frame绐楀彛
+  isiframe: false, // 鏄惁涓篿frame绐楀彛
+  debug: false // 鐭ュ惁鍙互澶嶅埗鑿滃崟鍙傛暟
 }
 
 // 鐢ㄦ埛娑堟伅
@@ -40,6 +41,11 @@
           isiframe: false
         }
       }
+    case Type.RESET_DEBUG:
+      return {
+        ...state,
+        debug: true
+      }
     default:
       return state
   }
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index a308e33..f9a9948 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { BackTop, Button, message } from 'antd'
+import { BackTop } from 'antd'
 import Api from '@/api'
 import MainSearch from '@/components/mainSearch'
 import MainAction from '@/components/mainAction'
@@ -17,7 +17,7 @@
   }
 
   state = {
-    dict: (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     searchlist: null,
     actions: null,
     columns: null,
@@ -135,18 +135,6 @@
     return data
   }
 
-  copyMenuNo = (e) => {
-    e.stopPropagation()
-    let oInput = document.createElement('input')
-    oInput.value = this.props.MenuNo
-    document.body.appendChild(oInput)
-    oInput.select()
-    document.execCommand('Copy')
-    oInput.className = 'oInput'
-    oInput.style.display='none'
-    message.success(this.state.dict['main.copy.success'])
-  }
-
   UNSAFE_componentWillMount () {
     // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
     this.loadconfig()
@@ -192,7 +180,6 @@
             dict={this.state.dict}
           />
         }
-        <Button className="main-copy" icon="copy" onClick={this.copyMenuNo} shape="circle" />
         <BackTop>
           <div className="ant-back-top">
             <div className="ant-back-top-content">
diff --git a/src/tabviews/commontable/index.scss b/src/tabviews/commontable/index.scss
index 14b928d..6e289a3 100644
--- a/src/tabviews/commontable/index.scss
+++ b/src/tabviews/commontable/index.scss
@@ -1,16 +1,6 @@
 .commontable {
-  min-height: calc(100vh - 110px);
-  .main-copy {
-    position: fixed;
-    z-index: 2;
-    bottom: 75px;
-    right: 30px;
-    width: 40px;
-    height: 40px;
-    i {
-      font-size: 18px;
-    }
-  }
+  min-height: calc(100vh - 94px);
+  padding-top: 16px;
 }
 .ant-back-top {
   bottom: 30px;
diff --git a/src/tabviews/datamanage/index.jsx b/src/tabviews/datamanage/index.jsx
new file mode 100644
index 0000000..c61ee55
--- /dev/null
+++ b/src/tabviews/datamanage/index.jsx
@@ -0,0 +1,201 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { BackTop, notification } from 'antd'
+import Api from '@/api'
+import DataSearch from './modules/search'
+import DataAction from './modules/action'
+import DataTable from './modules/table'
+import Loading from '@/components/loading'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import './index.scss'
+
+export default class DataManage extends Component {
+  static propTpyes = {
+    MenuNo: PropTypes.string // 鏍囩椤垫暟缁�
+  }
+
+  state = {
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 鏁版嵁瀛楀吀
+    searchlist: null, // 鎼滅储鏉′欢
+    searchparam: null, // 鎼滅储鍙傛暟
+    actions: null, // 鎸夐挳
+    columns: null, // 鏄剧ず鍒�
+    selectable: false, // 琛ㄦ牸鏄惁鍙��
+    datafunc: null, // 鑾峰彇鏁版嵁鍙婃樉绀哄垪鐨勫瓨鍌ㄨ繃绋嬪悕绉�
+    data: null,
+    total: 0,
+    loading: true,
+    param: {
+      pageIndex: 1,
+      pageSize: 10,
+      orderColumn: '',
+      orderType: '',
+      search: ''
+    }
+  }
+
+  async loadconfig () {
+    let param = {
+      func: 's_Get_Page_wheproc',
+      MenuNo: this.props.MenuNo
+    }
+    let result = await Api.commonInterface(param)
+    if (result.status) {
+      let newconfig = {}
+      if (result.sWheredata && result.sWheredata.length > 0) {
+        newconfig.searchlist = result.sWheredata
+      }
+      if (result.sMenusdata && result.sMenusdata.length > 0) {
+        newconfig.actions = result.sMenusdata
+      }
+      newconfig.selectable = result.CheckBox === 'true'
+      newconfig.datafunc = result.sWhereAction
+      this.setState(newconfig)
+    } else {
+      notification.warning({
+        top: 92,
+        message: result.message
+      })
+    }
+  }
+
+  async loadDbdata (searches, pageIndex = 1, pageSize = 10, orderColumn = '', orderType = '') {
+    let param = {
+      func: this.state.datafunc,
+      MenuNo: this.props.MenuNo,
+      PageSize: pageSize,
+      PageIndex: pageIndex,
+      SortName: orderColumn,
+      SortOrder: orderType,
+      ...searches
+    }
+    let result = await Api.commonInterface(param)
+    if (result.status) {
+      result.sGriddata.length = 4
+      this.setState({
+        columns: result.sGriddata,
+        data: result.data.map((item, index) => {
+          item.key = index
+          return item
+        }),
+        total: result.Total,
+        searchparam: searches,
+        loading: false
+      })
+    } else {
+      notification.warning({
+        top: 92,
+        message: result.message
+      })
+      this.setState({
+        searchparam: searches,
+        loading: false
+      })
+    }
+  }
+
+  refreshbysearch = (searches, type) => {
+    // 鎼滅储鏉′欢鍙樺寲
+    if (type === 'reset') {
+      this.setState({
+        columns: null,
+        data: null,
+        total: 0
+      })
+    } else {
+      this.loadDbdata(searches)
+      this.setState({
+        loading: true,
+        columns: null
+      })
+    }
+  }
+
+  refreshbytable = (pagination, filters, sorter) => {
+    // 琛ㄦ牸鏌ヨ鏉′欢淇敼
+    if (sorter.order) {
+      let _chg = {
+        ascend: 'asc',
+        descend: 'desc'
+      }
+      sorter.order = _chg[sorter.order]
+    }
+    this.loadDbdata(this.state.searchparam, pagination.current, pagination.pageSize, sorter.field, sorter.order)
+    this.setState({
+      loading: true
+    })
+  }
+
+  refreshbyaction = () => {
+    // 鎸夐挳鎿嶄綔鍚庡埛鏂拌〃鏍�,閲嶇疆椤电爜鍙婇�夋嫨椤�
+    this.refs.dataTable.resetTable()
+    this.loadDbdata(this.state.searchparam)
+    this.setState({
+      loading: true
+    })
+  }
+
+  gettableselected = () => {
+    // 鑾峰彇琛ㄦ牸閫夋嫨椤�
+    let data = []
+    this.refs.dataTable.state.selectedRowKeys.forEach(item => {
+      data.push(this.refs.dataTable.props.data[item])
+    })
+    return data
+  }
+
+  UNSAFE_componentWillMount () {
+    // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
+    this.loadconfig()
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  render() {
+    return (
+      <div className="datamanage">
+        {!this.state.searchlist && <Loading />}
+        {this.state.searchlist &&
+          <DataSearch
+            refreshdata={this.refreshbysearch}
+            searchlist={this.state.searchlist}
+            dict={this.state.dict}
+          />
+        }
+        {this.state.actions &&
+          <DataAction
+            MenuNo={this.props.MenuNo}
+            refreshdata={this.refreshbyaction}
+            gettableselected={this.gettableselected}
+            actions={this.state.actions}
+            dict={this.state.dict}
+          />
+        }
+        {this.state.columns &&
+          <DataTable
+            ref="dataTable"
+            MenuNo={this.props.MenuNo}
+            refreshdata={this.refreshbytable}
+            columns={this.state.columns}
+            data={this.state.data}
+            selectable={this.state.selectable}
+            total={this.state.total}
+            loading={this.state.loading}
+            dict={this.state.dict}
+          />
+        }
+        <BackTop>
+          <div className="ant-back-top">
+            <div className="ant-back-top-content">
+              <div className="ant-back-top-icon"></div>
+            </div>
+          </div>
+        </BackTop>
+      </div>
+    )
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/datamanage/index.scss b/src/tabviews/datamanage/index.scss
new file mode 100644
index 0000000..f23de89
--- /dev/null
+++ b/src/tabviews/datamanage/index.scss
@@ -0,0 +1,8 @@
+.datamanage {
+  min-height: calc(100vh - 94px);
+  padding-top: 16px;
+}
+.ant-back-top {
+  bottom: 30px;
+  right: 30px;
+}
\ No newline at end of file
diff --git a/src/tabviews/datamanage/modules/action/index.jsx b/src/tabviews/datamanage/modules/action/index.jsx
new file mode 100644
index 0000000..bcfedc3
--- /dev/null
+++ b/src/tabviews/datamanage/modules/action/index.jsx
@@ -0,0 +1,189 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+// import { is, fromJS } from 'immutable'
+import { Button, Affix, Modal, notification } from 'antd'
+import MutilForm from '@/components/mutilform'
+import Api from '@/api'
+import './index.scss'
+
+const { confirm } = Modal
+
+class MainAction extends Component {
+  static propTpyes = {
+    MenuNo: PropTypes.string,
+    actions: PropTypes.array, // 鎼滅储鏉′欢鍒楄〃
+    dict: PropTypes.object // 瀛楀吀椤�
+  }
+
+  state = {
+    visible: false,
+    formdata: null,
+    tabledata: null,
+    confirmLoading: false,
+    execAction: null
+  }
+  
+  refreshdata = () => {
+    this.props.refreshdata()
+  }
+  actionTrigger = (item) => {
+    let _this = this
+    let data = this.props.gettableselected() || []
+    if (item.Ot === 'required' && data.length === 0) {
+      // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
+      notification.warning({
+        top: 92,
+        message: this.props.dict['main.action.confirm.selectline']
+      })
+      return
+    } else if (item.Ot === 'pop' && data.length !== 1) {
+      if (data.length === 0) {
+        // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
+        notification.warning({
+          top: 92,
+          message: this.props.dict['main.action.confirm.selectline']
+        })
+        return
+      } else {
+        // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
+        notification.warning({
+          top: 92,
+          message: this.props.dict['main.action.confirm.selectSingleLine']
+        })
+        return
+      }
+    }
+
+    if (item.Action === 'Prompt' || item.Action === 'Delete') {
+      confirm({
+        title: this.props.dict['main.action.confirm.tip'],
+        onOk() {
+          return Api.setActionSubmit({
+            func: 'SetActionSubmitSuccess'
+            // func: 'SetActionSubmitError'
+          }).then((res) => {
+            if (res.status) {
+              notification.success({
+                top: 92,
+                message: _this.props.dict['main.action.confirm.success']
+                // duration: 0
+                // description:
+              })
+              _this.refreshdata()
+            } else {
+              notification.error({
+                top: 92,
+                message: res.message
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (item.Action === 'Update') {
+      Api.getModelFormData(item.MenuID).then(res => {
+        if (res.status) {
+          this.setState({
+            formdata: res.data.map(input => {
+              let validate = input.Validate && JSON.parse(input.Validate)
+              input.DynOptions = JSON.parse(input.DynOptions)
+              input.required = (validate && validate.required) || false
+              return input
+            }),
+            visible: true,
+            execAction: item,
+            tabledata: data[0]
+          })
+        }
+      })
+    }
+  }
+
+  getModels = () => {
+    return (
+      <Modal
+        wrapClassName='action-modal'
+        title={(this.state.execAction && this.state.execAction.MenuName) || ''}
+        visible={this.state.visible}
+        width={(this.state.execAction && +this.state.execAction.PopWidth) || 520}
+        onOk={this.handleOk}
+        confirmLoading={this.state.confirmLoading}
+        onCancel={this.handleCancel}
+      >
+        {this.state.formdata &&
+          <MutilForm
+            dict={this.props.dict}
+            formlist={this.state.formdata}
+            data={this.state.tabledata}
+            wrappedComponentRef={(inst) => this.formRef = inst}
+          />}
+      </Modal>
+    )
+  }
+
+  handleOk = () => {
+    this.formRef.handleConfirm().then(res => {
+      this.setState({
+        confirmLoading: true
+      })
+      console.log(res)
+      Api.setActionSubmit({
+        func: 'SetActionSubmitSuccess'
+      }).then((res) => {
+        if (res.status) {
+          notification.success({
+            top: 92,
+            message: this.props.dict['main.action.confirm.success']
+          })
+          this.setState({
+            confirmLoading: false,
+            visible: false
+          })
+        } else {
+          notification.error({
+            top: 92,
+            message: res.message
+          })
+        }
+      })
+    }, () => {})
+  }
+
+  handleCancel = () => {
+    this.setState({
+      visible: false
+    })
+    this.formRef.handleReset()
+  }
+
+  UNSAFE_componentWillMount () {
+
+  }
+
+  // shouldComponentUpdate (nextProps, nextState) {
+  //   console.log(!is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)))
+  //   return true
+  // }
+
+  render() {
+    return (
+      <Affix offsetTop={48}>
+        <div className="button-list" id={this.props.MenuNo + 'mainaction'}>
+          {this.props.actions.map((item, index) => {
+            return (
+              <Button
+                className={'mk-btn ' + item.CssClass + ' mk-' + item.CssClass}
+                icon={item.Icon}
+                key={'action' + index}
+                onClick={() => {this.actionTrigger(item)}}
+              >{item.MenuName}</Button>
+            )
+          })}
+          {this.getModels()}
+        </div>
+      </Affix>
+    )
+  }
+}
+
+export default MainAction
\ No newline at end of file
diff --git a/src/tabviews/datamanage/modules/action/index.scss b/src/tabviews/datamanage/modules/action/index.scss
new file mode 100644
index 0000000..215e88d
--- /dev/null
+++ b/src/tabviews/datamanage/modules/action/index.scss
@@ -0,0 +1,35 @@
+.button-list {
+  padding: 10px 20px 5px;
+  background: #ffffff;
+  button {
+    margin-right: 15px;
+    margin-bottom: 10px;
+  }
+}
+// 璁剧疆妯℃�佹鏍峰紡锛岃瀹氭渶澶ф渶灏忛珮搴︼紝閲嶇疆婊氬姩鏉�
+.action-modal {
+  .ant-modal {
+    max-width: 95vw;
+  }
+  .ant-modal-body {
+    max-height: calc(100vh - 235px);
+    min-height: 150px;
+    overflow-y: auto;
+    padding-bottom: 35px;
+  }
+  .ant-modal-body::-webkit-scrollbar {
+    width: 10px;
+    height: 10px;
+  }
+  .ant-modal-body::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+    background: rgba(0, 0, 0, 0.13);
+  }
+  .ant-modal-body::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    border: 1px solid rgba(0, 0, 0, 0.07);
+    background: rgba(0, 0, 0, 0);
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/datamanage/modules/search/index.jsx b/src/tabviews/datamanage/modules/search/index.jsx
new file mode 100644
index 0000000..7d288db
--- /dev/null
+++ b/src/tabviews/datamanage/modules/search/index.jsx
@@ -0,0 +1,192 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Button, Select, DatePicker, notification } from 'antd'
+import moment from 'moment'
+import './index.scss'
+
+const {MonthPicker, WeekPicker} = DatePicker
+const dateFormat = 'YYYY-MM-DD'
+const weekFormat = 'YYYYMMDD'
+const monthFormat = 'YYYY-MM'
+
+class MainSearch extends Component {
+  static propTpyes = {
+    searchlist: PropTypes.array, // 鎼滅储鏉′欢鍒楄〃
+    dict: PropTypes.object // 瀛楀吀椤�
+  }
+
+  state = {
+    formats: null, // 浜嬩欢鏍¢獙瑙勫垯
+    match: null // 鎼滅储鏉′欢鍖归厤瑙勫垯
+  }
+
+  UNSAFE_componentWillMount () {
+    let formats = {}
+    let match = {}
+    this.props.searchlist.forEach(item => {
+      if (item.Type === 'date') {
+        // formats[item.FieldName] = dateFormat
+        formats[item.FieldName] = weekFormat
+      } else if (item.ID === 'WHE1400200905') {
+        formats[item.FieldName] = monthFormat
+      }
+      match[item.FieldName] = item.Op
+    })
+    this.setState({
+      formats: formats,
+      match: match
+    })
+  }
+
+  getFields() {
+    const { getFieldDecorator } = this.props.form
+    const fields = []
+    this.props.searchlist.forEach((item, index) => {
+      if (item.Type === 'text' || item.Type === 'string') { // 鏂囨湰鎼滅储
+        fields.push(
+          <Col span={6} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.FieldName, {initialValue: item.InitVal })(<Input placeholder="" autoComplete="off" />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.Type === 'select') { // 涓嬫媺鎼滅储
+        fields.push(
+          <Col span={6} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.FieldName, {initialValue: item.FromField[0].id })(
+                <Select
+                  showSearch
+                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                >
+                  {item.FromField.map(option =>
+                    <Select.Option id={option.id} title={option.text} key={option.id} value={option.id}>{option.text}</Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.Type === 'date') { // 鏃堕棿鎼滅储
+        if (item.ID === 'WHE14002009024') {
+          fields.push(
+            <Col span={6} key={index}>
+              <Form.Item label={item.label}>
+                {getFieldDecorator(item.FieldName, {initialValue: moment('2019-09-14', dateFormat) })(
+                  <DatePicker format={dateFormat} />
+                )}
+              </Form.Item>
+            </Col>
+          )
+        } else if (item.ID === 'WHE1400200905') {
+          fields.push(
+            <Col span={6} key={index}>
+              <Form.Item label={item.label}>
+                {getFieldDecorator(item.FieldName, {initialValue: moment('2019-09', monthFormat) })(
+                  <MonthPicker format={monthFormat} />
+                )}
+              </Form.Item>
+            </Col>
+          )
+        } else if (item.ID === 'WHE1400200902') {
+          fields.push(
+            <Col span={6} key={index}>
+              <Form.Item label={item.label}>
+                {getFieldDecorator(item.FieldName, {initialValue: moment('20190906', weekFormat) })(
+                  <WeekPicker />
+                )}
+              </Form.Item>
+            </Col>
+          )
+        }
+      }
+    })
+
+    if (this.props.searchlist.length >= 4) { // 娣诲姞鎼滅储銆侀噸缃寜閽�
+      fields.push(
+        <Col span={this.props.searchlist.length % 4 ? 6 : 24} style={{ textAlign: 'right' }} key="actions">
+          <Button type="primary" htmlType="submit">
+            {this.props.dict['main.search']}
+          </Button>
+          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
+            {this.props.dict['main.reset']}
+          </Button>
+        </Col>
+      )
+    } else {
+      fields.push(
+        <Col span={6} style={{ paddingTop: '4px' }} key="actions">
+          <Button type="primary" htmlType="submit">
+            {this.props.dict['main.search']}
+          </Button>
+          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
+            {this.props.dict['main.reset']}
+          </Button>
+        </Col>
+      )
+    }
+    
+    return fields
+  }
+
+  handleSearch = (e) => {
+    // 鍥炶溅鎴栫偣鍑绘悳绱�
+    e.preventDefault()
+    this.props.form.validateFields((err, values) => {
+      this.getFieldsValues(values)
+    })
+  }
+
+  handleReset = () => {
+    // 閲嶇疆鎼滅储鏉′欢锛岄�氱煡椤甸潰鍒锋柊
+    this.props.form.resetFields()
+    this.props.refreshdata('', 'reset')
+  }
+
+  getFieldsValues = (searches) => {
+    // 鑾峰彇鎼滅储鏉′欢鍊�
+    let search = {}
+    Object.keys(searches).forEach(key => {
+      let val = searches[key] || ''
+      if (searches[key] && typeof(searches[key]) === 'object') {
+        if (this.state.formats[key] === weekFormat) {
+          val = moment(searches[key]).startOf('week').format(this.state.formats[key]) + ' ' + moment(searches[key]).endOf('week').format(this.state.formats[key])
+        } else {
+          val = moment(searches[key]).format(this.state.formats[key])
+        }
+      }
+      search[key] = val
+    })
+    let valid = true // 鏍¢獙蹇呭~椤�
+    this.props.searchlist.forEach(item => {
+      let required = false
+      if (item.Validate && item.Validate !== '{}') {
+        try {
+          required = !!JSON.parse(item.Validate).required
+        } catch (e) {
+          console.error('Validate Field parse error')
+        }
+      }
+      if (required && !search[item.FieldName]) {
+        valid = false
+        notification.warning({
+          top: 92,
+          message: this.props.dict['main.form.required.input'] + item.label
+        })
+      }
+    })
+    if (valid) {
+      this.props.refreshdata(search)
+    }
+  }
+
+  render() {
+    return (
+      <Form className="ant-advanced-search-form main-search" onSubmit={this.handleSearch}>
+        <Row gutter={24}>{this.getFields()}</Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(MainSearch)
\ No newline at end of file
diff --git a/src/tabviews/datamanage/modules/search/index.scss b/src/tabviews/datamanage/modules/search/index.scss
new file mode 100644
index 0000000..34418e4
--- /dev/null
+++ b/src/tabviews/datamanage/modules/search/index.scss
@@ -0,0 +1,14 @@
+.ant-advanced-search-form.main-search {
+  padding: 0px 24px 20px;
+  border-bottom: 1px solid #d9d9d9;
+  .ant-form-item {
+    display: flex;
+    margin-bottom: 10px;
+  }
+  .ant-form-item-control-wrapper {
+    flex: 1;
+  }
+  .ant-form-item-label {
+    width: 100px;
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/datamanage/modules/table/index.jsx b/src/tabviews/datamanage/modules/table/index.jsx
new file mode 100644
index 0000000..4817382
--- /dev/null
+++ b/src/tabviews/datamanage/modules/table/index.jsx
@@ -0,0 +1,155 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+// import { is, fromJS } from 'immutable'
+import { Table, message, Affix } from 'antd'
+import './index.scss'
+
+export default class MainTable extends Component {
+  static propTpyes = {
+    MenuNo: PropTypes.string, // 鑿滃崟鍙傛暟
+    loading: PropTypes.bool,
+    total: PropTypes.number,
+    selectable: PropTypes.bool,
+    dict: PropTypes.object, // 瀛楀吀椤�
+    columns: PropTypes.array, // 琛ㄦ牸鍒�
+    data: PropTypes.oneOfType([
+      PropTypes.object,
+      PropTypes.array
+    ])
+  }
+
+  state = {
+    fixed: false, // 琛ㄦ牸澶撮儴鏄惁鍥哄畾浜庨〉闈笂鏂�
+    selectedRowKeys: [],
+    pageIndex: 1,
+    pageSize: 10,
+    columns: this.props.columns.map((item, index) => {
+      let _width = parseInt(item.Width) || 50
+      return {
+        align: item.Align,
+        dataIndex: item.FieldName,
+        title: item.Label,
+        sorter: item.IsSort === 'true',
+        width: _width,
+        render: (text, record) => (
+          <div style={{ wordWrap: 'break-word', wordBreak: 'break-word', minWidth: _width + 'px' }}>
+            {item.Type === 'image' ? text : text}
+          </div>
+        )
+        // onHeaderCell: () => ({style:{textAlign: 'center'}})
+      }
+    })
+  }
+
+  copycontent = (e, content) => {
+    // 琛ㄦ牸涓唴瀹瑰鍒�
+    e.stopPropagation()
+    let oInput = document.createElement('input')
+    oInput.value = content
+    document.body.appendChild(oInput)
+    oInput.select()
+    document.execCommand('Copy')
+    oInput.className = 'oInput'
+    oInput.style.display='none'
+    message.success(this.props.dict['main.copy.success'])
+  }
+
+  onSelectChange = selectedRowKeys => {
+    this.setState({ selectedRowKeys })
+  }
+
+  changeRow = (record, index) => {
+    // 鐐瑰嚮鏁磋锛岃Е鍙戝垏鎹紝鍒ゆ柇鏄惁鍙�夛紝鍗曢�夋垨澶氶�夛紝杩涜瀵瑰簲鎿嶄綔
+    if (!this.props.select || !this.props.select.selectable) return
+
+    let newkeys = JSON.parse(JSON.stringify(this.state.selectedRowKeys))
+    let _re = newkeys.includes(index)
+
+    if (this.props.select.selectType === 'radio') {
+      this.setState({ selectedRowKeys: [index] })
+    } else {
+      if (_re) {
+        newkeys = newkeys.filter(item => item !== index)
+      } else {
+        newkeys.push(index)
+      }
+      this.setState({ selectedRowKeys: newkeys })
+    }
+  }
+
+  changeTable = (pagination, filters, sorter) => {
+    this.setState({
+      pageIndex: pagination.current,
+      pageSize: pagination.pageSize,
+      selectedRowKeys: []
+    })
+    this.props.refreshdata(pagination, filters, sorter)
+  }
+
+  resetTable = () => {
+    this.setState({
+      pageIndex: 1,
+      selectedRowKeys: []
+    })
+  }
+
+  componentDidMount () {
+    let boxwidth = document.body.clientWidth - 275
+    let columnsWidth = this.props.selectable ? 60 : 0
+    this.state.columns.forEach(column => {
+      columnsWidth += column.width
+    })
+    if (boxwidth > columnsWidth) {
+      this.setState({
+        fixed: true
+      })
+    }
+  }
+
+  render() {
+    let { selectedRowKeys } = this.state
+    let rowSelection = null
+    if (this.props.selectable) {
+      rowSelection = {
+        selectedRowKeys,
+        type: 'checkbox',
+        onChange: this.onSelectChange
+      }
+    }
+    return (
+      <div className="main-table">
+        {this.state.fixed && <Affix offsetTop={105} className="fix-header">
+          <Table
+            bordered={true}
+            rowSelection={rowSelection}
+            size="middle"
+            columns={this.state.columns}
+          />
+        </Affix>}
+        <Table
+          bordered={true}
+          rowSelection={rowSelection}
+          size="middle"
+          columns={this.state.columns}
+          dataSource={this.props.data ? this.props.data : []}
+          loading={this.props.loading}
+          scroll={{ x: '100%', y: false }}
+          onRow={(record, index) => {
+            return {
+              onClick: () => {this.changeRow(record, index)}
+            }
+          }}
+          onChange={this.changeTable}
+          pagination={{
+            current: this.state.pageIndex,
+            pageSize: this.state.pageSize,
+            pageSizeOptions: ['10', '25', '50', '100', '500', '1000'],
+            showSizeChanger: true,
+            total: this.props.total,
+            showTotal: (total, range) => `${range[0]}-${range[1]} ${this.props.dict['main.pagination.of']} ${total} ${this.props.dict['main.pagination.items']}`
+          }}
+        />
+      </div>
+    )
+  }
+}
diff --git a/src/tabviews/datamanage/modules/table/index.scss b/src/tabviews/datamanage/modules/table/index.scss
new file mode 100644
index 0000000..fb65cc0
--- /dev/null
+++ b/src/tabviews/datamanage/modules/table/index.scss
@@ -0,0 +1,79 @@
+.main-table {
+  padding: 0 20px 110px;
+  table {
+    max-width: 100%;
+    width: 100%;
+    .ant-table-column-title {
+      white-space: nowrap;
+    }
+    .ant-table-selection-column {
+      width: 60px;
+      min-width: 60px;
+      max-width: 60px;
+    }
+    .ant-table-tbody > tr.ant-table-row-selected td {
+      background-color: #c4ebfd;
+    }
+  }
+  .ant-table-body {
+    overflow-x: auto!important;
+    min-height: 90px;
+    border: 1px solid #e8e8e8;
+    border-radius: 4px;
+    border-top: none;
+    border-bottom: none;
+    table {
+      border-left: 0;
+      .ant-table-thead > tr > th:last-child {
+        border-right: 0;
+      }
+      .ant-table-tbody > tr > td:last-child {
+        border-right: 0;
+      }
+      .ant-table-tbody > tr:nth-of-type(even) {
+        background-color: #fbfcfd;
+      }
+    }
+  }
+  .ant-table-body::-webkit-scrollbar {
+    width: 8px;
+    height: 10px;
+  }
+  ::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+    background: rgba(0, 0, 0, 0.13);
+  }
+  ::-webkit-scrollbar-track {/*婊氬姩鏉¢噷闈㈣建閬�*/
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    border: 1px solid rgba(0, 0, 0, 0.07);
+    background: rgba(0, 0, 0, 0);
+  }
+  .fix-header {
+    .ant-table-body {
+      min-height: unset
+    }
+    .ant-table-placeholder {
+      display: none;
+    }
+    .ant-table-wrapper {
+      display: none;
+    }
+    .ant-affix .ant-table-wrapper {
+      display: block;
+    }
+    .ant-table-column-sorter, .anticon-filter {
+      display: none;
+    }
+    .ant-table-middle > .ant-table-content > .ant-table-body > table > .ant-table-thead > tr > th {
+      padding: 12px 9px;
+    }
+    .ant-table-thead > tr > th.ant-table-column-has-actions.ant-table-column-has-sorters {
+      cursor: default;
+    }
+    .ant-table-thead > tr > th.ant-table-column-has-actions.ant-table-column-has-sorters:hover {
+      background: #fafafa;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/rolemanage/index.jsx b/src/tabviews/rolemanage/index.jsx
new file mode 100644
index 0000000..a4232a7
--- /dev/null
+++ b/src/tabviews/rolemanage/index.jsx
@@ -0,0 +1,97 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { BackTop, Card, Col, Row } from 'antd'
+import Api from '@/api'
+import Loading from '@/components/loading'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import './index.scss'
+
+export default class RoleManage extends Component {
+  static propTpyes = {
+    MenuNo: PropTypes.string // 鏍囩椤垫暟缁�
+  }
+
+  state = {
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    searchlist: null,
+    actions: null,
+    columns: null,
+    select: null,
+    data: null,
+    total: 0,
+    loading: true,
+    param: {
+      pageIndex: 1,
+      pageSize: 10,
+      orderColumn: '',
+      orderType: '',
+      search: ''
+    },
+    fixed: {}
+  }
+
+  async loadconfig () {
+    let param = {
+      func: 'sPC_Get_TreePage',
+      MenuNo: this.props.MenuNo
+    }
+    let result = await Api.commonInterface(param)
+    if (result.status) {
+      
+    }
+  }
+
+  async loadmaindata (pageIndex = 1, pageSize = 10, orderColumn = '', orderType = '', search = '') {
+    // 鑾峰彇鍒楄〃鏁版嵁
+    let result = await Api.getMainTableData(this.props.MenuNo, pageIndex, pageSize, orderColumn, orderType, search)
+    if (result.status) {
+      this.setState({
+        data: result.data.map((item, index) => {
+          item.key = index
+          item.rows = item.mkrows
+          return item
+        }),
+        total: result.total,
+        loading: false
+      })
+    }
+  }
+
+  UNSAFE_componentWillMount () {
+    // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
+    this.loadconfig()
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  render() {
+    return (
+      <div className="rolemanage">
+        {!this.state.searchlist && <Loading />}
+        <Row gutter={16}>
+          <Col span={6}>
+            <Card title="Card title" bordered={false}>
+              Card content
+            </Card>
+          </Col>
+          <Col span={18}>
+            <Card title="Card title" bordered={false}>
+              Card content
+            </Card>
+          </Col>
+        </Row>
+        <BackTop>
+          <div className="ant-back-top">
+            <div className="ant-back-top-content">
+              <div className="ant-back-top-icon"></div>
+            </div>
+          </div>
+        </BackTop>
+      </div>
+    )
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/rolemanage/index.scss b/src/tabviews/rolemanage/index.scss
new file mode 100644
index 0000000..7e500b3
--- /dev/null
+++ b/src/tabviews/rolemanage/index.scss
@@ -0,0 +1,11 @@
+.rolemanage {
+  min-height: calc(100vh - 94px);
+  height: 100%;
+  position: relative;
+  background: #fafafa;
+  padding: 15px;
+}
+.ant-back-top {
+  bottom: 30px;
+  right: 30px;
+}
\ No newline at end of file
diff --git a/src/utils/utils.js b/src/utils/utils.js
index a126695..b3d01e5 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -33,20 +33,6 @@
    * @description 鎷兼帴鎼滅储鏉′欢
    * @param {Array}   searches     鎼滅储鏉′欢
    * @return {String}  searchText  鎷兼帴缁撴灉
-   * ---杩囨护鏉′欢锛堟湭浣跨敤锛�---
-   * greaterorequal: ' >= '
-   * lessorequal: ' <= '
-   * like: ' LIKE '
-   * less: ' < '
-   * greater: ' > '
-   * equal: ' = '
-   * notlike: ' notlike '
-   * in: ' in '
-   * notin: ' notin '
-   * leftlike/startwith
-   * rightlike/endwith
-   * rightnotlike/endnotwith
-   * leftnotlike/startnotwith
    */
   static jointsearchkey (searches) {
     if (!searches || searches.length === 0) return ''
@@ -75,4 +61,20 @@
     })
     return searchText
   }
+
+  /**
+   * @description 鑾峰彇鍥剧墖鐪熷疄璺緞
+   * @return {String}    url 鍥剧墖璺緞
+   */
+  static getrealurl (url) {
+    if (!url) return ''
+    let baseurl = ''
+    if (process.env.NODE_ENV === 'production') {
+      baseurl = document.location.origin + '/'
+    } else {
+      baseurl = 'http://qingqiumarket.cn/MKWMS/'
+    }
+    let realurl = url.match(/^http/) || url.match(/^\/\//) ? url : baseurl + url
+    return realurl
+  }
 }
\ No newline at end of file
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index cdc7aff..cc52bf1 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -6,6 +6,7 @@
 import zhCN from '@/locales/zh-CN/login.js'
 import enUS from '@/locales/en-US/login.js'
 import options from '@/store/options.js'
+import Utils from '@/utils/utils.js'
 import logourl from '../../assets/img/login-logo.png'
 import './index.scss'
 
@@ -52,7 +53,6 @@
     // md5瀵嗙爜鍔犲瘑
     const salt = 'minkesoft'
     return md5(md5(pwd + salt))
-    // return pwd
   }
 
   handleSubmit = e => {
@@ -79,11 +79,13 @@
 
   async loginsubmit (param) {
     // 鐧诲綍鎻愪氦
-    let password = this.md5Password(param.password)
+    // let password = this.md5Password(param.password)
+    let password = param.password
     let result = await Api.loginsystem(param.username, password)
-    if (result.status) {
-    // if (!result.IsError) {
-      sessionStorage.setItem('UserID', result.userid)
+    if (!result.IsError) {
+      sessionStorage.setItem('UserID', result.userid || 'U000000001')
+      sessionStorage.setItem('SessionUid', Utils.getuuid())
+      sessionStorage.setItem('LoginUID', '')
       localStorage.setItem('lang', this.state.selectedlang.value)
 
       if (param.remember) { // 璁颁綇瀵嗙爜鏃惰处鍙峰瘑鐮佸瓨鍏ocalStorage
@@ -101,8 +103,7 @@
         this.props.history.replace('/main')
       }
     } else {
-      message.warning(result.message)
-      // message.warning(result.Message)
+      message.warning(result.Message)
       this.setState({
         isDisabled: false
       })
@@ -111,9 +112,9 @@
 
   UNSAFE_componentWillMount () {
     let timeStamp = new Date().getTime()
-    // let str = md5('MK19' + options.AppId + timeStamp)
+    let str = md5('MK19' + options.AppId + timeStamp)
     Api.systemauth(options.AppId, timeStamp).then(res => {
-      if (res.status) {
+      if (res.status && res.EPC === str) {
         let box = []
         for (let i = 0; i < 15; i++) {
           let s = 'mksoft' + moment().add(i, 'days').format('YYYYMMDD')
@@ -131,8 +132,10 @@
           auth: false
         })
       }
-      // console.log(str)
     })
+
+    // console.log(options)
+    // localStorage.setItem('AuthCode', [md5('mksoft' + moment().format('YYYYMMDD'))])
 
     let authCode = localStorage.getItem('AuthCode')
     let _s = md5('mksoft' + moment().format('YYYYMMDD'))
@@ -143,6 +146,13 @@
     }
   }
 
+  componentDidMount () {
+    const input = document.getElementById('username')
+    if (input) {
+      input.focus()
+    }
+  }
+
   render () {
     const { getFieldDecorator } = this.props.form
     const menu = (
diff --git a/src/views/login/index.scss b/src/views/login/index.scss
index 12e12c5..c9fcb08 100644
--- a/src/views/login/index.scss
+++ b/src/views/login/index.scss
@@ -24,13 +24,15 @@
       margin-right: 20%;
       padding: 15px;
       background: #ffffff;
-      width: 300px;
+      width: 18vw;
+      min-width: 300px;
       border-radius: 5px;
 
       h4 {
         font-size: 18px;
         font-weight: bold;
         color: #0A95CB;
+        margin-bottom: 3vh;
       }
       .minline {
         margin-bottom: 10px;
@@ -62,4 +64,8 @@
     background-color: #40a9ff;
     border-color: #40a9ff;
   }
+}
+.ant-message {
+  top: 50px;
+  z-index: 1080;
 }
\ No newline at end of file

--
Gitblit v1.8.0