king
2019-10-12 c7f79abded9ad2e29f297da4a04a641b96b61c5e
add-datamanage
22个文件已修改
11个文件已添加
1710 ■■■■ 已修改文件
config/webpack.config.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/action.scss 191 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/404/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.jsx 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.scss 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.scss 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/setupProxy.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action-type.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.scss 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/index.jsx 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/action/index.jsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/action/index.scss 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/search/index.jsx 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/search/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/table/index.jsx 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/datamanage/modules/table/index.scss 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/rolemanage/index.jsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/rolemanage/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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,
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",
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": "."
}
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
    })
  }
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;
  }
}
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;
}
src/components/404/index.scss
@@ -1,3 +1,4 @@
.box404 {
  max-height: calc(100vh - 110px);
  text-align: center;
}
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') { // 是否为debug模式,即可复制菜单参数
        this.props.resetDebug()
      }
      let param = sessionStorage.getItem('view_param') // 是否为打开新页面
      if (param) {
        // 通过url中menuid筛选出选中的主菜单
        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())
  }
}
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>
                  )
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页中为iframe时
  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;
  }
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 @@
    // 窗口在iframe与普通页面切换时,修改左侧菜单栏样式
    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) {
        // 查看新tab页需要组件是否加载
        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>
                  )
                })}
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 { // 去除标签页header与content之间的间隙
      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;
}
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'
src/router/index.js
@@ -58,7 +58,7 @@
              )
            })
          }
          <Redirect exact from="/" to="main"/>
          <Redirect exact from="/" to="login"/>
          <Route component= {NotFound}/>
        </Switch>
      </HashRouter>
src/setupProxy.js
New file
@@ -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': '/'
    }
  }))
}
src/store/action-type.js
@@ -11,4 +11,7 @@
export const TOGGLE_ISIFRAME = 'TOGGLE_ISIFRAME'
// 退出系统时参数重置
export const RESET_STATE = 'RESET_STATE'
export const RESET_STATE = 'RESET_STATE'
// 修改编辑模式
export const RESET_DEBUG = 'RESET_DEBUG'
src/store/action.js
@@ -37,4 +37,11 @@
  return {
    type: user.RESET_STATE
  }
}
// 退出系统时参数重置
export const resetDebug = () => {
  return {
    type: user.RESET_DEBUG
  }
}
src/store/reducer.js
@@ -4,7 +4,8 @@
  selectedMainMenu: '', // 已选主菜单
  tabviews: [], // 导航栏
  collapse: false, // 是否收起侧边栏导航
  isiframe: false // 是否为iframe窗口
  isiframe: false, // 是否为iframe窗口
  debug: false // 知否可以复制菜单参数
}
// 用户消息
@@ -40,6 +41,11 @@
          isiframe: false
        }
      }
    case Type.RESET_DEBUG:
      return {
        ...state,
        debug: true
      }
    default:
      return state
  }
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">
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;
src/tabviews/datamanage/index.jsx
New file
@@ -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>
    )
  }
}
src/tabviews/datamanage/index.scss
New file
@@ -0,0 +1,8 @@
.datamanage {
  min-height: calc(100vh - 94px);
  padding-top: 16px;
}
.ant-back-top {
  bottom: 30px;
  right: 30px;
}
src/tabviews/datamanage/modules/action/index.jsx
New file
@@ -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
src/tabviews/datamanage/modules/action/index.scss
New file
@@ -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);
  }
}
src/tabviews/datamanage/modules/search/index.jsx
New file
@@ -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)
src/tabviews/datamanage/modules/search/index.scss
New file
@@ -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;
  }
}
src/tabviews/datamanage/modules/table/index.jsx
New file
@@ -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>
    )
  }
}
src/tabviews/datamanage/modules/table/index.scss
New file
@@ -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;
    }
  }
}
src/tabviews/rolemanage/index.jsx
New file
@@ -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>
    )
  }
}
src/tabviews/rolemanage/index.scss
New file
@@ -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;
}
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
  }
}
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) { // 记住密码时账号密码存入localStorage
@@ -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 = (
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;
}