wuxiang 2 years ago
parent
commit
00af8402e4
69 changed files with 5977 additions and 169 deletions
  1. 62 10
      package-lock.json
  2. 5 0
      package.json
  3. 106 0
      src/api/Controller/DictionaryController.js
  4. 61 0
      src/api/Controller/SysDataPermController.js
  5. 49 0
      src/api/Controller/SysDeptController.js
  6. 21 0
      src/api/Controller/SysPostController.js
  7. 25 0
      src/api/Controller/SysUserController.js
  8. 252 0
      src/api/Controller/SystemController.js
  9. 41 0
      src/api/FlowController/FlowCategoryController.js
  10. 15 0
      src/api/FlowController/FlowDictionaryController.js
  11. 49 0
      src/api/FlowController/FlowEntryController.js
  12. 21 0
      src/api/FlowController/FlowEntryVariableController.js
  13. 135 0
      src/api/FlowController/FlowOperationController.js
  14. 45 0
      src/api/OnlineDBTableController/OnlineTable.js
  15. 53 0
      src/api/OnlineFormController/OnlineColumnController.js
  16. 22 0
      src/api/OnlineFormController/OnlineDataModelController.js
  17. 25 0
      src/api/OnlineFormController/OnlineDatasourceController.js
  18. 25 0
      src/api/OnlineFormController/OnlineDatasourceRelationController.js
  19. 13 0
      src/api/OnlineFormController/OnlineDblinkController.js
  20. 25 0
      src/api/OnlineFormController/OnlineDictController.js
  21. 29 0
      src/api/OnlineFormController/OnlineFormController.js
  22. 45 0
      src/api/OnlineFormController/OnlineOperation.js
  23. 61 0
      src/api/OnlineFormController/OnlinePageController.js
  24. 25 0
      src/api/OnlineFormController/OnlineRuleController.js
  25. 25 0
      src/api/OnlineFormController/OnlineTableController.js
  26. 21 0
      src/api/OnlineFormController/OnlineVirtualColumnController.js
  27. 17 0
      src/api/fireController.js
  28. 13 0
      src/api/flowController.js
  29. 15 0
      src/api/index.js
  30. 29 0
      src/api/onlineController.js
  31. BIN
      src/assets/image/map-bg.jpg
  32. BIN
      src/assets/image/map-bg.png
  33. 305 0
      src/components/DateRange/index.vue
  34. 77 0
      src/components/Dialog/index.js
  35. 134 0
      src/components/FilterBox/index.vue
  36. 44 0
      src/components/Hamburger/index.vue
  37. 280 0
      src/components/IconSelect/icon.json
  38. 104 0
      src/components/IconSelect/index.vue
  39. 226 0
      src/components/InputNumberRange/index.vue
  40. 44 0
      src/components/Progress/index.vue
  41. 132 0
      src/components/RichEditor/index.vue
  42. 119 0
      src/components/TableProgressColumn/index.vue
  43. 290 0
      src/components/TreeSelect/index.vue
  44. 5 0
      src/core/config/development.js
  45. 18 0
      src/core/config/index.js
  46. 5 0
      src/core/config/production.js
  47. 14 0
      src/core/directive/sortable.js
  48. 60 0
      src/core/directive/sortableData.js
  49. 203 0
      src/core/http/index.js
  50. 75 0
      src/core/http/request.js
  51. 27 0
      src/core/http/requestUrl.js
  52. 114 0
      src/core/mixins/global.js
  53. 298 0
      src/core/mixins/index.js
  54. 13 13
      src/main.js
  55. 7 1
      src/router/index.js
  56. 193 0
      src/staticDict/flowStaticDict.js
  57. 201 0
      src/staticDict/index.js
  58. 566 0
      src/staticDict/onlineStaticDict.js
  59. 5 30
      src/store/getters.js
  60. 7 5
      src/store/index.js
  61. 5 110
      src/store/modules/app.js
  62. 33 0
      src/store/modules/user.js
  63. 36 0
      src/store/modules/utils/index.js
  64. 56 0
      src/utils/chartOption.js
  65. 442 0
      src/utils/index.js
  66. 33 0
      src/utils/validate.js
  67. 322 0
      src/utils/widget.js
  68. 146 0
      src/views/login/index.vue
  69. 8 0
      src/views/situation/index.vue

+ 62 - 10
package-lock.json

@@ -2799,8 +2799,7 @@
         "asynckit": {
             "version": "0.4.0",
             "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
-            "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-            "dev": true
+            "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
         },
         "atob": {
             "version": "2.1.2",
@@ -2859,6 +2858,28 @@
             "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
             "dev": true
         },
+        "axios": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz",
+            "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+            "requires": {
+                "follow-redirects": "^1.15.0",
+                "form-data": "^4.0.0",
+                "proxy-from-env": "^1.1.0"
+            },
+            "dependencies": {
+                "form-data": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
+                    "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+                    "requires": {
+                        "asynckit": "^0.4.0",
+                        "combined-stream": "^1.0.8",
+                        "mime-types": "^2.1.12"
+                    }
+                }
+            }
+        },
         "babel-eslint": {
             "version": "10.1.0",
             "resolved": "https://registry.npmmirror.com/babel-eslint/-/babel-eslint-10.1.0.tgz",
@@ -3155,6 +3176,11 @@
             "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
             "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
         },
+        "bignumber.js": {
+            "version": "9.1.1",
+            "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.1.1.tgz",
+            "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig=="
+        },
         "binary-extensions": {
             "version": "2.2.0",
             "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -4041,7 +4067,6 @@
             "version": "1.0.8",
             "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
             "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-            "dev": true,
             "requires": {
                 "delayed-stream": "~1.0.0"
             }
@@ -4933,8 +4958,7 @@
         "delayed-stream": {
             "version": "1.0.0",
             "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
-            "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-            "dev": true
+            "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
         },
         "depd": {
             "version": "2.0.0",
@@ -6114,8 +6138,7 @@
         "follow-redirects": {
             "version": "1.15.2",
             "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
-            "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-            "dev": true
+            "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
         },
         "for-each": {
             "version": "0.3.3",
@@ -7575,6 +7598,11 @@
             "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
             "dev": true
         },
+        "jquery": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.7.0.tgz",
+            "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ=="
+        },
         "js-base64": {
             "version": "2.6.4",
             "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz",
@@ -7609,12 +7637,25 @@
             "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
             "dev": true
         },
+        "jsencrypt": {
+            "version": "3.3.2",
+            "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz",
+            "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
+        },
         "jsesc": {
             "version": "2.5.2",
             "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",
             "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
             "dev": true
         },
+        "json-bigint": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz",
+            "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+            "requires": {
+                "bignumber.js": "^9.0.0"
+            }
+        },
         "json-parse-better-errors": {
             "version": "1.0.2",
             "resolved": "https://registry.npmmirror.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -7710,6 +7751,14 @@
                 "launch-editor": "^2.6.0"
             }
         },
+        "layui-layer": {
+            "version": "1.0.9",
+            "resolved": "https://registry.npmmirror.com/layui-layer/-/layui-layer-1.0.9.tgz",
+            "integrity": "sha512-CzPVtG0D4IvmISUyLTzzbz2Uxfaoqch+87lHqVmO53ie8ZKOfOkENbBl7ssiLna1lAnv4M1SycmH62NbtndtDQ==",
+            "requires": {
+                "jquery": "^3.1.1"
+            }
+        },
         "levn": {
             "version": "0.3.0",
             "resolved": "https://registry.npmmirror.com/levn/-/levn-0.3.0.tgz",
@@ -8034,14 +8083,12 @@
         "mime-db": {
             "version": "1.52.0",
             "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
-            "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-            "dev": true
+            "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
         },
         "mime-types": {
             "version": "2.1.35",
             "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
             "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-            "dev": true,
             "requires": {
                 "mime-db": "1.52.0"
             }
@@ -10181,6 +10228,11 @@
                 "ipaddr.js": "1.9.1"
             }
         },
+        "proxy-from-env": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+            "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+        },
         "prr": {
             "version": "1.0.1",
             "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",

+ 5 - 0
package.json

@@ -10,11 +10,16 @@
     "main": "background.js",
     "dependencies": {
         "@jiaminghi/data-view": "^2.10.0",
+        "axios": "^1.4.0",
         "cesium": "1.93",
         "copy-webpack-plugin": "5.0",
         "core-js": "^3.6.5",
         "echarts": "^4.9.0",
         "element-ui": "^2.15.13",
+        "jquery": "^3.7.0",
+        "jsencrypt": "^3.3.2",
+        "json-bigint": "^1.0.0",
+        "layui-layer": "^1.0.9",
         "vue": "^2.6.11",
         "vue-native-websocket": "^2.0.15",
         "vue-router": "^3.5.2",

+ 106 - 0
src/api/Controller/DictionaryController.js

@@ -0,0 +1,106 @@
+import * as staticDict from '@/staticDict'
+
+export default class DictionaryController {
+  static dictSysRole (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/upms/sysRole/listDict', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('角色字典');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictSysUserStatus () {
+    return new Promise((resolve) => {
+      resolve(staticDict.SysUserStatus);
+    });
+  }
+  static dictSysUserType () {
+    return new Promise((resolve) => {
+      resolve(staticDict.SysUserType);
+    });
+  }
+  static dictSysDept (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/upms/sysDept/listDict', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('部门字典');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictSysDeptByParentId (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/upms/sysDept/listDictByParentId', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('部门字典');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictAreaCode (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/app/areaCode/listDict', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('行政区划');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictAreaCodeByParentId (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/app/areaCode/listDictByParentId', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('行政区划');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictAddAreaCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('', 'post', params, axiosOption, httpOption);
+  }
+  static dictDeleteAreaCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('', 'post', params, axiosOption, httpOption);
+  }
+  static dictUpdateAreaCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('', 'post', params, axiosOption, httpOption);
+  }
+  static dictReloadAreaCodeCachedData (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('', 'get', params, axiosOption, httpOption);
+  }
+  static dictSysDataPermType () {
+    return new Promise((resolve) => {
+      resolve(staticDict.SysDataPermType);
+    });
+  }
+  static dictDeptPost (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('admin/upms/sysDept/listSysDeptPostWithRelation', 'get', params, axiosOption, httpOption).then(res => {
+        resolve(res.data);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+  static dictSysPost (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/upms/sysPost/listDict', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase('岗位字典');
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+}

+ 61 - 0
src/api/Controller/SysDataPermController.js

@@ -0,0 +1,61 @@
+export default class SysDataPermController {
+  /**
+   * @param params    {dataPermId, dataPermName, deptIdListString}
+   */
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/add', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId, dataPermName, deptIdListString}
+   */
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/update', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId}
+   */
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermName}
+   */
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/list', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId}
+   */
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/view', 'get', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId, searchString}
+   */
+  static listDataPermUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/listDataPermUser', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId, userIdListString}
+   */
+  static addDataPermUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/addDataPermUser', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {dataPermId, userId}
+   */
+  static deleteDataPermUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/deleteDataPermUser', 'post', params, axiosOption, httpOption);
+  }
+
+  static listNotInDataPermUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDataPerm/listNotInDataPermUser', 'post', params, axiosOption, httpOption);
+  }
+}

+ 49 - 0
src/api/Controller/SysDeptController.js

@@ -0,0 +1,49 @@
+export default class SysDeptController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('admin/upms/sysDept/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static listNotInSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/listNotInSysDeptPost', 'post', params, axiosOption, httpOption);
+  }
+
+  static listSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/listSysDeptPost', 'post', params, axiosOption, httpOption);
+  }
+
+  static addSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/addSysDeptPost', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/updateSysDeptPost', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/deleteSysDeptPost', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewSysDeptPost (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/viewSysDeptPost', 'get', params, axiosOption, httpOption);
+  }
+}

+ 21 - 0
src/api/Controller/SysPostController.js

@@ -0,0 +1,21 @@
+export default class SysPostController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/upms/sysPost/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/upms/sysPost/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/upms/sysPost/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/upms/sysPost/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/upms/sysPost/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 25 - 0
src/api/Controller/SysUserController.js

@@ -0,0 +1,25 @@
+export default class SysUserController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('admin/upms/sysUser/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 252 - 0
src/api/Controller/SystemController.js

@@ -0,0 +1,252 @@
+export default class SystemController {
+  static login (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/login/doLogin', 'post', params, axiosOption, httpOption);
+  }
+
+  static logout (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/login/doLogout', 'post', params, axiosOption, httpOption);
+  }
+
+  static changePassword (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/login/changePassword', 'post', params, axiosOption, httpOption);
+  }
+
+  static getLoginInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/login/getLoginInfo', 'get', params, axiosOption, httpOption);
+  }
+
+  static getDictList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDict/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static getRoleList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static getRole (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static deleteRole (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static addRole (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateRole (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static getUserList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static getUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static resetUserPassword (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/resetPassword', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static addUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static addDepartment (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteDepartment (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateDepartment (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static getDepartmentList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysDept/list', 'post', params, axiosOption, httpOption);
+  }
+
+  // 菜单接口
+  static getMenuPermList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/list', 'post', params, axiosOption, httpOption);
+  }
+  static addMenu (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/add', 'post', params, axiosOption, httpOption);
+  }
+  
+  static updateMenu (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/update', 'post', params, axiosOption, httpOption);
+  }
+  static deleteMenu (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewMenu (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/view', 'get', params, axiosOption, httpOption);
+  }
+  // 权限字接口
+  static getPermCodeList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static addPermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updatePermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static deletePermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewPermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/view', 'get', params, axiosOption, httpOption);
+  }
+
+  // 权限资源接口
+  static getAllPermList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermModule/listAll', 'post', params, axiosOption, httpOption);
+  }
+
+  static getPermGroupList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermModule/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static addPermGroup (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermModule/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updatePermGroup (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermModule/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static deletePermGroup (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermModule/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static getPermList (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewPerm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static addPerm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updatePerm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static deletePerm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/delete', 'post', params, axiosOption, httpOption);
+  }
+  /**
+   * @param params    {roleId, searchString}
+   */
+  static listRoleUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/listUserRole', 'post', params, axiosOption, httpOption);
+  }
+
+  static listNotInUserRole (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/listNotInUserRole', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {roleId, userIdListString}
+   */
+  static addRoleUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/addUserRole', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params    {roleId, userId}
+   */
+  static deleteRoleUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/deleteUserRole', 'post', params, axiosOption, httpOption);
+  }
+
+  /**
+   * @param params {}
+   */
+  static queryRoleByPermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/listAllRolesByPermCode', 'post', params, axiosOption, httpOption);
+  }
+  // 权限查询
+  static listSysPermWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/listSysPermWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysPermCodeWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/listSysPermCodeWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysMenuWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysUser/listSysMenuWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysPermByRoleIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/listSysPermWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysPermCodeByRoleIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysRole/listSysPermCodeWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listMenuPermCode (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/listMenuPerm', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysPermByMenuIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/listSysPermWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysUserByMenuIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysMenu/listSysUserWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysUserByPermCodeIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/listSysUserWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysRoleByPermCodeIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPermCode/listSysRoleWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysUserByPermIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/listSysUserWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysRoleByPermIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/listSysRoleWithDetail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSysMenuByPermIdWithDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/sysPerm/listSysMenuWithDetail', 'get', params, axiosOption, httpOption);
+  }
+  // 在线用户
+  static listSysLoginUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/loginUser/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteSysLoginUser (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/upms/loginUser/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 41 - 0
src/api/FlowController/FlowCategoryController.js

@@ -0,0 +1,41 @@
+export default class FlowCategoryController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static publish (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowCategory/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static subscribe (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/flow/flowCategoryUser/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static unsubscribe (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/flow/flowCategoryUser/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static user (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/flow/flowCategoryUser/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static getApp (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('admin/flow/flowCategory/getApp', 'get', params, axiosOption, httpOption);
+  }
+}

+ 15 - 0
src/api/FlowController/FlowDictionaryController.js

@@ -0,0 +1,15 @@
+import * as staticDict from '@/staticDict';
+
+export default class FlowDictionaryController {
+  static dictFlowCategory (sender, params, axiosOption, httpOption) {
+    return new Promise((resolve, reject) => {
+      sender.doUrl('/admin/flow/flowCategory/listDict', 'get', params, axiosOption, httpOption).then(res => {
+        let dictData = new staticDict.DictionaryBase();
+        dictData.setList(res.data);
+        resolve(dictData);
+      }).catch(err => {
+        reject(err);
+      });
+    });
+  }
+}

+ 49 - 0
src/api/FlowController/FlowEntryController.js

@@ -0,0 +1,49 @@
+export default class FlowEntryController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static publish (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/publish', 'post', params, axiosOption, httpOption);
+  }
+
+  static listFlowEntryPublish (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/listFlowEntryPublish', 'get', params, axiosOption, httpOption);
+  }
+
+  static updateMainVersion (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/updateMainVersion', 'post', params, axiosOption, httpOption);
+  }
+
+  static suspendFlowEntryPublish (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/suspendFlowEntryPublish', 'post', params, axiosOption, httpOption);
+  }
+
+  static activateFlowEntryPublish (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/activateFlowEntryPublish', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewDict (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/viewDict', 'get', params, axiosOption, httpOption);
+  }
+
+  static listDict (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntry/listDict', 'get', params, axiosOption, httpOption);
+  }
+}

+ 21 - 0
src/api/FlowController/FlowEntryVariableController.js

@@ -0,0 +1,21 @@
+export default class FlowEntryVariableController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntryVariable/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntryVariable/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntryVariable/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntryVariable/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowEntryVariable/view', 'get', params, axiosOption, httpOption);
+  }
+}

+ 135 - 0
src/api/FlowController/FlowOperationController.js

@@ -0,0 +1,135 @@
+export default class FlowOperationController {
+  // 启动流程实例并且提交表单信息
+  static startAndTakeUserTask (sender, params, axiosOption, httpOption) {
+    let url = '/admin/flow/flowOnlineOperation/startAndTakeUserTask';
+    if (axiosOption && axiosOption.processDefinitionKey) {
+      url += '/' + axiosOption.processDefinitionKey;
+    }
+    return sender.doUrl(url, 'post', params, axiosOption, httpOption);
+  }
+  // 获得流程以及工单信息
+  static listWorkOrder (sender, params, axiosOption, httpOption) {
+    let url = '/admin/flow/flowOnlineOperation/listWorkOrder';
+    if (axiosOption && axiosOption.processDefinitionKey) {
+      url += '/' + axiosOption.processDefinitionKey;
+    }
+    return sender.doUrl(url, 'post', params, axiosOption, httpOption);
+  }
+  // 提交用户任务数据
+  static submitUserTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOnlineOperation/submitUserTask', 'post', params, axiosOption, httpOption);
+  }
+  // 获取历史流程数据
+  static viewHistoricProcessInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOnlineOperation/viewHistoricProcessInstance', 'get', params, axiosOption, httpOption);
+  }
+  // 获取用户任务数据
+  static viewUserTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOnlineOperation/viewUserTask', 'get', params, axiosOption, httpOption);
+  }
+  // 获取在线表单工作流以及工作流下表单列表
+  static listFlowEntryForm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOnlineOperation/listFlowEntryForm', 'get', params, axiosOption, httpOption);
+  }
+  // 撤销工单
+  static cancelWorkOrder (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/cancelWorkOrder', 'post', params, axiosOption, httpOption);
+  }
+  // 多实例加签
+  static submitConsign (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/submitConsign', 'post', params, axiosOption, httpOption);
+  }
+  // 已办任务列表
+  static listHistoricTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listHistoricTask', 'post', params, axiosOption, httpOption);
+  }
+  // 获取已办任务信息
+  static viewHistoricTaskInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewHistoricTaskInfo', 'get', params, axiosOption, httpOption);
+  }
+  // 仅启动流程实例
+  static startOnly (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/startOnly', 'post', params, axiosOption, httpOption);
+  }
+  // 获得流程定义初始化用户任务信息
+  static viewInitialTaskInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewInitialTaskInfo', 'get', params, axiosOption, httpOption);
+  }
+  // 获取待办任务信息
+  static viewRuntimeTaskInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewRuntimeTaskInfo', 'get', params, axiosOption, httpOption);
+  }
+  // 获取流程实例审批历史
+  static listFlowTaskComment (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listFlowTaskComment', 'get', params, axiosOption, httpOption);
+  }
+  // 获取历史任务信息
+  static viewInitialHistoricTaskInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewInitialHistoricTaskInfo', 'get', params, axiosOption, httpOption);
+  }
+   // 获取历史任务信息
+   static viewAllInitialHistoricTaskInfo (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewAllInitialHistoricTaskInfo', 'get', params, axiosOption, httpOption);
+  }
+  // 获取所有待办任务
+  static listRuntimeTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listRuntimeTask', 'post', params, axiosOption, httpOption);
+  }
+  // 获得流程实例审批路径
+  static viewHighlightFlowData (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewHighlightFlowData', 'get', params, axiosOption, httpOption);
+  }
+  // 获得流程实例的配置XML
+  static viewProcessBpmn (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/viewProcessBpmn', 'get', params, axiosOption, httpOption);
+  }
+  // 获得所有历史流程实例
+  static listAllHistoricProcessInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listAllHistoricProcessInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 获得当前用户历史流程实例
+  static listHistoricProcessInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listHistoricProcessInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 终止流程
+  static stopProcessInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/stopProcessInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 删除流程实例
+  static deleteProcessInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/deleteProcessInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 催办
+  static remindRuntimeTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/remindRuntimeTask', 'post', params, axiosOption, httpOption);
+  }
+  // 催办消息列表
+  static listRemindingTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowMessage/listRemindingTask', 'post', params, axiosOption, httpOption);
+  }
+  // 驳回
+  static rejectRuntimeTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/rejectRuntimeTask', 'post', params, axiosOption, httpOption);
+  }
+  // 撤销
+  static revokeHistoricTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/revokeHistoricTask', 'post', params, axiosOption, httpOption);
+  }
+  // 挂起
+  static suspendInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/suspendInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 激活
+  static activeInstance (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/activeInstance', 'post', params, axiosOption, httpOption);
+  }
+  // 转交
+  static turnTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/turnTask', 'post', params, axiosOption, httpOption);
+  }
+  // 用户任务
+  static listUserTask (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOperation/listUserTask', 'post', params, axiosOption, httpOption);
+  }
+  
+}

+ 45 - 0
src/api/OnlineDBTableController/OnlineTable.js

@@ -0,0 +1,45 @@
+export default class OnlineTable {
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormHead/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormHead/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static show (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormField/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormHead/del', 'post', params, axiosOption, httpOption);
+  }
+
+  static letdbSync (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormHead/sync', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteData (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormField/del', 'post', params, axiosOption, httpOption);
+  }
+
+  static addData (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormField/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateData (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormField/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static getDetail (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormField/detail', 'get', params, axiosOption, httpOption);
+  }
+
+  static listSyncTable (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/table/onlineFormHead/listSyncTable', 'get', params, axiosOption, httpOption);
+  }
+
+  static dataview (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/flow/flowOnlineDataModelController/view', 'post', params, axiosOption, httpOption);
+  }
+}

+ 53 - 0
src/api/OnlineFormController/OnlineColumnController.js

@@ -0,0 +1,53 @@
+export default class OnlineColumnController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineColumn/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static refreshColumn (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/refresh', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static listOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/listOnlineColumnRule', 'post', params, axiosOption, httpOption);
+  }
+
+  static listNotInOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/listNotInOnlineColumnRule', 'post', params, axiosOption, httpOption);
+  }
+
+  static addOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/addOnlineColumnRule', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/deleteOnlineColumnRule', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/updateOnlineColumnRule', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewOnlineColumnRule (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineColumn/viewOnlineColumnRule', 'get', params, axiosOption, httpOption);
+  }
+}

+ 22 - 0
src/api/OnlineFormController/OnlineDataModelController.js

@@ -0,0 +1,22 @@
+export default class OnlineDataModelController {
+    static view (sender, params, axiosOption, httpOption) {
+        return sender.doUrl('/admin/flow/flowOnlineDataModelController/view', 'post', params, axiosOption, httpOption);
+      }
+   
+    static add (sender, params, axiosOption, httpOption) {
+        return sender.doUrl('/admin/flow/flowOnlineDataModelController/add', 'post', params, axiosOption, httpOption);
+      }
+
+    static del (sender, params, axiosOption, httpOption) {
+        return sender.doUrl('/admin/flow/flowOnlineDataModelController/del', 'post', params, axiosOption, httpOption);
+      }
+    
+    static update (sender, params, axiosOption, httpOption) {
+        return sender.doUrl('/admin/flow/flowOnlineDataModelController/update', 'post', params, axiosOption, httpOption);
+      }
+
+    static viewOneToMany (sender, params, axiosOption, httpOption) {
+        return sender.doUrl('/admin/flow/flowOnlineDataModelController/viewOneToMany', 'post', params, axiosOption, httpOption);
+      }
+  }
+  

+ 25 - 0
src/api/OnlineFormController/OnlineDatasourceController.js

@@ -0,0 +1,25 @@
+export default class OnlineDatasourceController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasource/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasource/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineDatasource/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasource/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasource/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasource/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 25 - 0
src/api/OnlineFormController/OnlineDatasourceRelationController.js

@@ -0,0 +1,25 @@
+export default class OnlineDatasourceRelationController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasourceRelation/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasourceRelation/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineDatasourceRelation/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasourceRelation/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasourceRelation/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDatasourceRelation/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 13 - 0
src/api/OnlineFormController/OnlineDblinkController.js

@@ -0,0 +1,13 @@
+export default class OnlineDblinkController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDblink/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static listDblinkTables (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDblink/listDblinkTables', 'get', params, axiosOption, httpOption);
+  }
+
+  static listDblinkTableColumns (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDblink/listDblinkTableColumns', 'get', params, axiosOption, httpOption);
+  }
+}

+ 25 - 0
src/api/OnlineFormController/OnlineDictController.js

@@ -0,0 +1,25 @@
+export default class OnlineDictController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDict/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDict/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineDict/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDict/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDict/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineDict/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 29 - 0
src/api/OnlineFormController/OnlineFormController.js

@@ -0,0 +1,29 @@
+export default class OnlineFormController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static render (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/render', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineForm/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineForm/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 45 - 0
src/api/OnlineFormController/OnlineOperation.js

@@ -0,0 +1,45 @@
+export default class OnlineOperation {
+  static listDict (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listDict', 'post', params, axiosOption, httpOption);
+  }
+
+  static listByDatasourceId (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByDatasourceId', 'post', params, axiosOption, httpOption);
+  }
+
+  static listByOneToManyRelationId (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByOneToManyRelationId', 'post', params, axiosOption, httpOption);
+  }
+
+  static addDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/addDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static addOneToManyRelation (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/addOneToManyRelation', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/updateDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateOneToManyRelation (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/updateOneToManyRelation', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewByDatasourceId (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/viewByDatasourceId', 'get', params, axiosOption, httpOption);
+  }
+
+  static viewByOneToManyRelationId (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/viewByOneToManyRelationId', 'get', params, axiosOption, httpOption);
+  }
+
+  static deleteDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/deleteDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteOneToManyRelation (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/deleteOneToManyRelation', 'post', params, axiosOption, httpOption);
+  }
+}

+ 61 - 0
src/api/OnlineFormController/OnlinePageController.js

@@ -0,0 +1,61 @@
+export default class OnlinePageController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static listAllPageAndForm (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/listAllPageAndForm', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlinePage/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static updatePublished (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/updatePublished', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/delete', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateStatus (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/updateStatus', 'post', params, axiosOption, httpOption);
+  }
+
+  static listOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/listOnlinePageDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static listNotInOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/listNotInOnlinePageDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static addOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/addOnlinePageDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static deleteOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/deleteOnlinePageDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static updateOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/updateOnlinePageDatasource', 'post', params, axiosOption, httpOption);
+  }
+
+  static viewOnlinePageDatasource (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlinePage/viewOnlinePageDatasource', 'get', params, axiosOption, httpOption);
+  }
+}

+ 25 - 0
src/api/OnlineFormController/OnlineRuleController.js

@@ -0,0 +1,25 @@
+export default class OnlineRuleController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineRule/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineRule/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineRule/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineRule/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineRule/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineRule/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 25 - 0
src/api/OnlineFormController/OnlineTableController.js

@@ -0,0 +1,25 @@
+export default class OnlineTableController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineTable/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineTable/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static export (sender, params, fileName) {
+    return sender.download('/admin/online/onlineTable/export', params, fileName);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineTable/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineTable/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineTable/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 21 - 0
src/api/OnlineFormController/OnlineVirtualColumnController.js

@@ -0,0 +1,21 @@
+export default class OnlineVirtualColumnController {
+  static list (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineVirtualColumn/list', 'post', params, axiosOption, httpOption);
+  }
+
+  static view (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineVirtualColumn/view', 'get', params, axiosOption, httpOption);
+  }
+
+  static add (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineVirtualColumn/add', 'post', params, axiosOption, httpOption);
+  }
+
+  static update (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineVirtualColumn/update', 'post', params, axiosOption, httpOption);
+  }
+
+  static delete (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineVirtualColumn/delete', 'post', params, axiosOption, httpOption);
+  }
+}

+ 17 - 0
src/api/fireController.js

@@ -0,0 +1,17 @@
+export default class fireController {
+  static center (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByDatasourceId/center', 'post', params, axiosOption, httpOption);
+  }
+  
+  static unit (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByDatasourceId/mainUnit', 'post', params, axiosOption, httpOption);
+  }
+  
+  static satellite (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByDatasourceId/satellite', 'post', params, axiosOption, httpOption);
+  }
+  
+  static situation (sender, params, axiosOption, httpOption) {
+    return sender.doUrl('/admin/online/onlineOperation/listByDatasourceId/main', 'post', params, axiosOption, httpOption);
+  }
+}

+ 13 - 0
src/api/flowController.js

@@ -0,0 +1,13 @@
+import FlowDictionaryController from './FlowController/FlowDictionaryController.js';
+import FlowCategoryController from './FlowController/FlowCategoryController.js';
+import FlowEntryController from './FlowController/FlowEntryController.js';
+import FlowEntryVariableController from './FlowController/FlowEntryVariableController.js';
+import FlowOperationController from './FlowController/FlowOperationController.js';
+
+export {
+  FlowDictionaryController,
+  FlowCategoryController,
+  FlowEntryController,
+  FlowEntryVariableController,
+  FlowOperationController
+}

+ 15 - 0
src/api/index.js

@@ -0,0 +1,15 @@
+import SystemController from './Controller/SystemController'
+import SysDataPermController from './Controller/SysDataPermController'
+import SysPostController from './Controller/SysPostController.js';
+import DictionaryController from './Controller/DictionaryController'
+import SysDeptController from './Controller/SysDeptController.js';
+import SysUserController from './Controller/SysUserController.js';
+
+export {
+  SystemController,
+  SysDataPermController,
+  SysPostController,
+  DictionaryController,
+  SysDeptController,
+  SysUserController
+}

+ 29 - 0
src/api/onlineController.js

@@ -0,0 +1,29 @@
+import OnlineDblinkController from './OnlineFormController/OnlineDblinkController.js';
+import OnlineDictController from './OnlineFormController/OnlineDictController.js';
+import OnlineTableController from './OnlineFormController/OnlineTableController.js';
+import OnlineColumnController from './OnlineFormController/OnlineColumnController.js';
+import OnlinePageController from './OnlineFormController/OnlinePageController.js';
+import OnlineFormController from './OnlineFormController/OnlineFormController.js';
+import OnlineDatasourceController from './OnlineFormController/OnlineDatasourceController.js';
+import OnlineDatasourceRelationController from './OnlineFormController/OnlineDatasourceRelationController.js';
+import OnlineRuleController from './OnlineFormController/OnlineRuleController.js';
+import OnlineVirtualColumnController from './OnlineFormController/OnlineVirtualColumnController.js';
+import OnlineOperation from './OnlineFormController/OnlineOperation.js';
+import OnlineTable from './OnlineDBTableController/OnlineTable.js';
+import OnlineDataModelController from './OnlineFormController/OnlineDataModelController.js';
+
+export {
+  OnlineDblinkController,
+  OnlineDictController,
+  OnlineColumnController,
+  OnlineTableController,
+  OnlinePageController,
+  OnlineFormController,
+  OnlineDatasourceController,
+  OnlineDatasourceRelationController,
+  OnlineRuleController,
+  OnlineVirtualColumnController,
+  OnlineOperation,
+  OnlineTable,
+  OnlineDataModelController
+}

BIN
src/assets/image/map-bg.jpg


BIN
src/assets/image/map-bg.png


+ 305 - 0
src/components/DateRange/index.vue

@@ -0,0 +1,305 @@
+<template>
+  <div class="date-range">
+    <!--<year-range-panel />-->
+    <el-select v-model="dateType" :size="size"
+      style="max-width: 100px; min-width: 100px; margin-right: 10px;"
+      v-if="!hideTypeOnlyOne || validTypeList.length > 1">
+      <el-option v-for="type in validTypeList" :key="type.value" :value="type.value" :label="type.label" />
+    </el-select>
+    <el-date-picker style="flex-grow: 1;" v-model="currentDates"
+      :size="size" :placeholder="placeholder" :type="innerDateType"
+      :disabled="disabled" :format="innerDateFormat" :readonly="readonly" :editable="editable"
+      :clearable="clearable" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder"
+      :align="align" :range-separator="rangeSeparator" :value-format="valueFormat"
+      :prefix-icon="prefixIcon" :clear-icon="clearIcon" @change="onValueChange" />
+  </div>
+</template>
+
+<script>
+import { formatDate, parseDate } from 'element-ui/src/utils/date-util';
+
+const allTypeList = [{
+  value: 'day',
+  label: '自然日'
+}, {
+  value: 'month',
+  label: '自然月'
+}, {
+  value: 'year',
+  label: '自然年'
+}];
+
+export default {
+  name: 'DateRange',
+  props: {
+    /**
+     * 绑定的数据
+     */
+    value: {
+      type: [Array],
+      default: () => {
+        return []
+      }
+    },
+    /**
+     * 默认显示的数据选择方式,如果不存在与allowTypes中则显示allowTypes中的第一个
+     */
+    defaultDateType: {
+      type: String,
+      default: 'day'
+    },
+    /**
+     * 组件大小(medium / small / mini)
+     */
+    size: {
+      type: String
+    },
+    /**
+     * 数据选择方式只有一个的时候是否隐藏数据选择方式下拉
+     */
+    hideTypeOnlyOne: {
+      type: Boolean,
+      default: true
+    },
+    /**
+     * 允许的数据选择方式(day, month, year)
+     * 默认值['day', 'month', 'year']
+     */
+    allowTypes: {
+      type: Array,
+      default: () => {
+        return allTypeList.map((item) => {
+          return item.value;
+        });
+      }
+    },
+    /**
+     * 是否范围选择
+     */
+    isRange: {
+      type: Boolean,
+      default: true
+    },
+    /**
+     * 输出字符串的format
+     */
+    outputFormat: {
+      type: String,
+      default: 'yyyy-MM-dd HH:mm:ss'
+    },
+    /**
+     * 非范围选择时的占位内容
+     */
+    placeholder: String,
+    /**
+     * 范围选择时开始日期的占位内容
+     */
+    startPlaceholder: String,
+    /**
+     * 范围选择时结束日期的占位内容
+     */
+    endPlaceholder: String,
+    /**
+     * 完全只读
+     */
+    readonly: Boolean,
+    /**
+     * 禁用
+     */
+    disabled: Boolean,
+    /**
+     * 文本框可输入
+     */
+    editable: {
+      type: Boolean,
+      default: true
+    },
+    /**
+     * 是否显示清除按钮
+     */
+    clearable: {
+      type: Boolean,
+      default: true
+    },
+    /**
+     * 对齐方式(left, center, right)
+     */
+    align: {
+      type: String,
+      default: 'left'
+    },
+    /**
+     * 选择范围时的分隔符
+     */
+    rangeSeparator: {
+      type: String,
+      default: '-'
+    },
+    /**
+     * 可选,绑定值的格式。不指定则绑定值为 Date 对象
+     */
+    valueFormat: {
+      type: String,
+      default: 'yyyy-MM-dd'
+    },
+    /**
+     * 自定义头部图标的类名
+     */
+    prefixIcon: {
+      type: String,
+      default: 'el-icon-date'
+    },
+    /**
+     * 自定义清空图标的类名
+     */
+    clearIcon: {
+      type: String,
+      default: 'el-icon-circle-close'
+    }
+  },
+  data () {
+    return {
+      dateType: this.defaultDateType,
+      currentDates: undefined
+    }
+  },
+  methods: {
+    onValueChange (values) {
+      this.$nextTick(() => {
+        this.emitChange();
+      });
+    },
+    emitChange () {
+      let outputDate = [];
+      if (this.currentDates != null) {
+        if (!this.isRange) {
+          outputDate[0] = new Date(this.currentDates);
+          outputDate[1] = new Date(this.currentDates);
+        } else {
+          if (Array.isArray(this.currentDates) && this.currentDates.length === 2) {
+            outputDate[0] = new Date(this.currentDates[0]);
+            outputDate[1] = new Date(this.currentDates[1]);
+          }
+        }
+
+        if (outputDate[0] != null && outputDate[1] != null) {
+          outputDate[0].setHours(0, 0, 0, 0);
+          outputDate[1].setHours(0, 0, 0, 0);
+          switch (this.dateType) {
+            case 'day':
+              outputDate[1].setDate(outputDate[1].getDate() + 1);
+              break;
+            case 'month':
+              outputDate[1].setDate(1);
+              outputDate[0].setDate(1);
+              outputDate[1].setMonth(outputDate[1].getMonth() + 1);
+              break;
+            case 'year':
+              outputDate[1].setMonth(0);
+              outputDate[1].setDate(1);
+              outputDate[0].setMonth(0);
+              outputDate[0].setDate(1);
+              outputDate[1].setFullYear(outputDate[1].getFullYear() + 1);
+              break;
+          }
+          outputDate[1] = new Date(outputDate[1].getTime() - 1);
+
+          outputDate[0] = formatDate(outputDate[0], this.outputFormat);
+          outputDate[1] = formatDate(outputDate[1], this.outputFormat);
+        }
+      }
+      this.$emit('input', outputDate);
+      this.$emit('change', outputDate);
+    },
+    getCurrentStatsDateType () {
+      return this.dateType;
+    }
+  },
+  computed: {
+    validTypeList () {
+      return allTypeList.filter((item) => {
+        return this.allowTypes.indexOf(item.value) !== -1;
+      });
+    },
+    /**
+     * el-date-picker使用的type
+     */
+    innerDateType () {
+      switch (this.dateType) {
+        case 'day': return this.isRange ? 'daterange' : 'date';
+        case 'month': return this.isRange ? 'monthrange' : 'month';
+        case 'year': return this.isRange ? 'monthrange' : 'year';
+        default: return this.isRange ? 'daterange' : 'date';
+      }
+    },
+    /**
+     * el-date-picker使用的format
+     */
+    innerDateFormat () {
+      switch (this.dateType) {
+        case 'day': return 'yyyy-MM-dd';
+        case 'month': return 'yyyy-MM';
+        case 'year': return 'yyyy';
+        default: return 'yyyy-MM-dd';
+      }
+    }
+  },
+  watch: {
+    value: {
+      handler: function (newValue, oldValue) {
+        if (newValue == null || newValue.length < 2) {
+          this.currentDates = this.isRange ? [] : undefined;
+        } else {
+          if (this.currentDates == null) this.currentDates = [];
+          if (this.isRange) {
+            this.currentDates = [
+              parseDate(newValue[0], this.valueFormat),
+              parseDate(newValue[1], this.valueFormat)
+            ];
+          } else {
+            this.currentDates = parseDate(newValue[0], this.valueFormat);
+          }
+        }
+      },
+      immediate: true,
+      deep: true
+    },
+    dateType: {
+      handler: function (newValue, oldValue) {
+        if (this.allowTypes.indexOf(this.dateType) === -1) {
+          this.dateType = this.allowTypes[0] || 'day';
+        }
+        this.emitChange();
+      },
+      immediate: true
+    },
+    defaultDateType: {
+      handler: function (newValue, oldValue) {
+        if (this.allowTypes.indexOf(newValue) !== -1) {
+          this.dateType = newValue;
+        } else {
+          this.dateType = this.allowTypes[0];
+        }
+      }
+    },
+    isRange: {
+      handler: function (newValue, oldValue) {
+        let temp;
+        if (newValue) {
+          temp = [this.currentDates, this.currentDates];
+        } else {
+          temp = this.currentDates[0];
+        }
+
+        this.currentDates = temp;
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+  .date-range {
+    display: flex;
+  }
+</style>

+ 77 - 0
src/components/Dialog/index.js

@@ -0,0 +1,77 @@
+import $ from 'jquery';
+import Vue from 'vue';
+import router from '@/router';
+import store from '@/store';
+
+window.jQuery = $;
+const layer = require('layui-layer');
+
+class Dialog {
+  /**
+   * 关闭弹窗
+   * @param {*} index 要关闭的弹窗的index
+   */
+  static close (index) {
+    layer.close(index);
+  }
+  /**
+   * 关闭所有弹窗
+   */
+  static closeAll () {
+    layer.closeAll();
+  }
+  /**
+   * 打开弹窗
+   * @param {*} title 弹窗标题
+   * @param {*} component 弹窗内容的组件
+   * @param {*} options 弹窗设置(详情请见layui官网)
+   * @param {*} params 弹窗组件参数
+   */
+  static show (title, component, options, params) {
+    return new Promise((resolve, reject) => {
+      let layerOptions = {
+        title: title,
+        type: 1,
+        skin: 'layer-dialog',
+        resize: false,
+        offset: 'auto',
+        zIndex: 1000,
+        index: 0,
+        contentDom: null
+      };
+
+      layerOptions = {...layerOptions, ...options};
+      layerOptions.end = () => {
+        if (layerOptions.contentDom) document.body.removeChild(layerOptions.contentDom);
+      }
+
+      let observer = {
+        cancel: function (isSuccess = false, data = undefined) {
+          layer.close(this.index);
+          if (isSuccess) {
+            resolve(data);
+          } else {
+            reject();
+          }
+        },
+        index: -1
+      }
+      layerOptions.cancel = () => {
+        reject();
+      }
+      let dom = document.createElement('div');
+      document.body.appendChild(dom);
+      let Content = Vue.extend(component);
+      let vueObj = new Content({router: router, store: store, propsData: params});
+      vueObj.observer = observer;
+      vueObj.$mount(dom);
+      layerOptions.contentDom = vueObj.$el;
+      layerOptions.content = $(layerOptions.contentDom);
+      observer.index = layer.open(layerOptions);
+    });
+  }
+}
+
+Vue.prototype.$dialog = Dialog;
+
+export default Dialog;

+ 134 - 0
src/components/FilterBox/index.vue

@@ -0,0 +1,134 @@
+<template>
+  <el-row class="flex-box" type="flex" :justify="rowJustify">
+    <slot />
+    <div v-for="item in tempDomCount" :key="item" :style="{width: tempDomWidth}" />
+    <el-row type="flex" :justify="operatorPosition" :style="getMenuBoxStyle">
+      <slot name="operator" />
+    </el-row>
+  </el-row>
+</template>
+
+<script>
+import $ from 'jquery';
+
+export default {
+  name: 'FilterBox',
+  props: {
+    /**
+     * 每一个过滤项宽度(包含标题和输入框宽度总和)
+     */
+    itemWidth: {
+      type: Number,
+      required: true
+    },
+    /**
+     * 每一项下间距
+     */
+    marginBottom: {
+      type: String,
+      default: '18px'
+    },
+    /**
+     * 按钮块最小宽度默认350,当每一行剩余空间大于此值,按钮块将不会折行
+     */
+    minMenuWidth: {
+      type: Number,
+      default: 350
+    },
+    /**
+     * 按钮位置,默认为end,可选值为start/end/center/space-around/space-between
+     */
+    operatorPosition: {
+      type: String,
+      default: 'end'
+    }
+  },
+  data () {
+    return {
+      tempDomCount: 0,
+      tempDomWidth: undefined,
+      operatorWidth: undefined,
+      oldFilterItemCount: 0,
+      oldHasOperator: false,
+      oldWidth: 0,
+      rowJustify: 'space-between'
+    }
+  },
+  computed: {
+    getMenuBoxStyle () {
+      return {
+        'width': this.operatorWidth,
+        'margin-bottom': this.marginBottom,
+        'flex-grow': this.operatorWidth ? undefined : '1'
+      }
+    }
+  },
+  methods: {
+    onUpdate () {
+      setTimeout(() => {
+        let filterItemCount = Array.isArray(this.$slots.default) ? this.$slots.default.filter(item => item.context).length : 0;
+        let hasOperator = Array.isArray(this.$slots.operator) && this.$slots.operator.length > 0;
+        let width = $(this.$el).width();
+        if (filterItemCount === this.oldFilterItemCount && hasOperator === this.oldHasOperator && width === this.oldWidth) {
+          return;
+        }
+        let lineCount = this.itemWidth > 0 ? parseInt(width / this.itemWidth) : 1;
+        lineCount = Math.max(1, lineCount);
+        let residueCount = filterItemCount % lineCount;
+
+        this.tempDomCount = 0;
+        this.tempDomWidth = undefined;
+        this.rowJustify = 'space-between';
+        let tempCount = residueCount === 0 ? 0 : (lineCount - residueCount);
+        if (hasOperator) {
+          let residueWidth = width - ((Math.min(lineCount, filterItemCount) - residueCount) * this.itemWidth) - ((tempCount >= 1) ? 20 : 0);
+          // 判断剩余的空间是否够放下操作按钮
+          if (residueWidth >= this.minMenuWidth && residueCount === 0) {
+            this.rowJustify = 'start';
+            this.operatorWidth = undefined;
+          } else {
+            // 剩余空位数大于1,需要占位dom
+            if (tempCount >= 1) {
+              if (residueWidth >= this.minMenuWidth) {
+                this.tempDomCount = tempCount - 1;
+                this.tempDomWidth = this.tempDomCount > 0 ? (20 / this.tempDomCount) + 'px' : undefined;
+                this.operatorWidth = this.tempDomCount > 0 ? (((tempCount * this.itemWidth) - 20) + 'px') : (this.itemWidth + 'px');
+              } else {
+                this.tempDomCount = tempCount;
+                this.tempDomWidth = (residueWidth / this.tempDomCount) + 'px';
+                this.operatorWidth = '100%';
+              }
+            } else {
+              this.operatorWidth = '100%';
+            }
+          }
+        } else {
+          this.tempDomCount = tempCount;
+          this.tempDomWidth = this.itemWidth + 'px';
+        }
+
+        this.oldFilterItemCount = filterItemCount;
+        this.oldHasOperator = hasOperator;
+        this.oldWidth = width;
+      });
+    }
+  },
+  beforeUpdate () {
+    this.onUpdate();
+  },
+  mounted () {
+    setTimeout(() => {
+      this.onUpdate();
+    });
+  },
+  created () {
+    window.addEventListener('resize', this.onUpdate);
+  },
+  beforeDestroy () {
+    window.removeEventListener('resize', this.onUpdate);
+  }
+}
+</script>
+
+<style>
+</style>

+ 44 - 0
src/components/Hamburger/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div>
+    <svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
+      version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
+      <path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
+        p-id="1692"></path>
+      <path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
+        p-id="1693"></path>
+      <path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
+        p-id="1694"></path>
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'hamburger',
+  props: {
+    isActive: {
+      type: Boolean,
+      default: false
+    },
+    toggleClick: {
+      type: Function,
+      default: null
+    }
+  }
+}
+</script>
+
+<style scoped>
+.hamburger {
+  display: inline-block;
+  cursor: pointer;
+  width: 20px;
+  height: 20px;
+  transform: rotate(90deg);
+  transform-origin: 50% 50%;
+}
+
+.hamburger.is-active {
+  transform: rotate(0deg);
+}
+</style>

+ 280 - 0
src/components/IconSelect/icon.json

@@ -0,0 +1,280 @@
+[
+  "el-icon-delete-solid",
+  "el-icon-delete",
+  "el-icon-s-tools",
+  "el-icon-setting",
+  "el-icon-user-solid",
+  "el-icon-user",
+  "el-icon-phone",
+  "el-icon-phone-outline",
+  "el-icon-more",
+  "el-icon-more-outline",
+  "el-icon-star-on",
+  "el-icon-star-off",
+  "el-icon-s-goods",
+  "el-icon-goods",
+  "el-icon-warning",
+  "el-icon-warning-outline",
+  "el-icon-question",
+  "el-icon-info",
+  "el-icon-remove",
+  "el-icon-circle-plus",
+  "el-icon-success",
+  "el-icon-error",
+  "el-icon-zoom-in",
+  "el-icon-zoom-out",
+  "el-icon-remove-outline",
+  "el-icon-circle-plus-outline",
+  "el-icon-circle-check",
+  "el-icon-circle-close",
+  "el-icon-s-help",
+  "el-icon-help",
+  "el-icon-minus",
+  "el-icon-plus",
+  "el-icon-check",
+  "el-icon-close",
+  "el-icon-picture",
+  "el-icon-picture-outline",
+  "el-icon-picture-outline-round",
+  "el-icon-upload",
+  "el-icon-upload2",
+  "el-icon-download",
+  "el-icon-camera-solid",
+  "el-icon-camera",
+  "el-icon-video-camera-solid",
+  "el-icon-video-camera",
+  "el-icon-message-solid",
+  "el-icon-bell",
+  "el-icon-s-cooperation",
+  "el-icon-s-order",
+  "el-icon-s-platform",
+  "el-icon-s-fold",
+  "el-icon-s-unfold",
+  "el-icon-s-operation",
+  "el-icon-s-promotion",
+  "el-icon-s-home",
+  "el-icon-s-release",
+  "el-icon-s-ticket",
+  "el-icon-s-management",
+  "el-icon-s-open",
+  "el-icon-s-shop",
+  "el-icon-s-marketing",
+  "el-icon-s-flag",
+  "el-icon-s-comment",
+  "el-icon-s-finance",
+  "el-icon-s-claim",
+  "el-icon-s-custom",
+  "el-icon-s-opportunity",
+  "el-icon-s-data",
+  "el-icon-s-check",
+  "el-icon-s-grid",
+  "el-icon-menu",
+  "el-icon-share",
+  "el-icon-d-caret",
+  "el-icon-caret-left",
+  "el-icon-caret-right",
+  "el-icon-caret-bottom",
+  "el-icon-caret-top",
+  "el-icon-bottom-left",
+  "el-icon-bottom-right",
+  "el-icon-back",
+  "el-icon-right",
+  "el-icon-bottom",
+  "el-icon-top",
+  "el-icon-top-left",
+  "el-icon-top-right",
+  "el-icon-arrow-left",
+  "el-icon-arrow-right",
+  "el-icon-arrow-down",
+  "el-icon-arrow-up",
+  "el-icon-d-arrow-left",
+  "el-icon-d-arrow-right",
+  "el-icon-video-pause",
+  "el-icon-video-play",
+  "el-icon-refresh",
+  "el-icon-refresh-right",
+  "el-icon-refresh-left",
+  "el-icon-finished",
+  "el-icon-sort",
+  "el-icon-sort-up",
+  "el-icon-sort-down",
+  "el-icon-rank",
+  "el-icon-loading",
+  "el-icon-view",
+  "el-icon-c-scale-to-original",
+  "el-icon-date",
+  "el-icon-edit",
+  "el-icon-edit-outline",
+  "el-icon-folder",
+  "el-icon-folder-opened",
+  "el-icon-folder-add",
+  "el-icon-folder-remove",
+  "el-icon-folder-delete",
+  "el-icon-folder-checked",
+  "el-icon-tickets",
+  "el-icon-document-remove",
+  "el-icon-document-delete",
+  "el-icon-document-copy",
+  "el-icon-document-checked",
+  "el-icon-document",
+  "el-icon-document-add",
+  "el-icon-printer",
+  "el-icon-paperclip",
+  "el-icon-takeaway-box",
+  "el-icon-search",
+  "el-icon-monitor",
+  "el-icon-attract",
+  "el-icon-mobile",
+  "el-icon-scissors",
+  "el-icon-umbrella",
+  "el-icon-headset",
+  "el-icon-brush",
+  "el-icon-mouse",
+  "el-icon-coordinate",
+  "el-icon-magic-stick",
+  "el-icon-reading",
+  "el-icon-data-line",
+  "el-icon-data-board",
+  "el-icon-pie-chart",
+  "el-icon-data-analysis",
+  "el-icon-collection-tag",
+  "el-icon-film",
+  "el-icon-suitcase",
+  "el-icon-suitcase-1",
+  "el-icon-receiving",
+  "el-icon-collection",
+  "el-icon-files",
+  "el-icon-notebook-1",
+  "el-icon-notebook-2",
+  "el-icon-toilet-paper",
+  "el-icon-office-building",
+  "el-icon-school",
+  "el-icon-table-lamp",
+  "el-icon-house",
+  "el-icon-no-smoking",
+  "el-icon-smoking",
+  "el-icon-shopping-cart-full",
+  "el-icon-shopping-cart-1",
+  "el-icon-shopping-cart-2",
+  "el-icon-shopping-bag-1",
+  "el-icon-shopping-bag-2",
+  "el-icon-sold-out",
+  "el-icon-sell",
+  "el-icon-present",
+  "el-icon-box",
+  "el-icon-bank-card",
+  "el-icon-money",
+  "el-icon-coin",
+  "el-icon-wallet",
+  "el-icon-discount",
+  "el-icon-price-tag",
+  "el-icon-news",
+  "el-icon-guide",
+  "el-icon-male",
+  "el-icon-female",
+  "el-icon-thumb",
+  "el-icon-cpu",
+  "el-icon-link",
+  "el-icon-connection",
+  "el-icon-open",
+  "el-icon-turn-off",
+  "el-icon-set-up",
+  "el-icon-chat-round",
+  "el-icon-chat-line-round",
+  "el-icon-chat-square",
+  "el-icon-chat-dot-round",
+  "el-icon-chat-dot-square",
+  "el-icon-chat-line-square",
+  "el-icon-message",
+  "el-icon-postcard",
+  "el-icon-position",
+  "el-icon-turn-off-microphone",
+  "el-icon-microphone",
+  "el-icon-close-notification",
+  "el-icon-bangzhu",
+  "el-icon-time",
+  "el-icon-odometer",
+  "el-icon-crop",
+  "el-icon-aim",
+  "el-icon-switch-button",
+  "el-icon-full-screen",
+  "el-icon-copy-document",
+  "el-icon-mic",
+  "el-icon-stopwatch",
+  "el-icon-medal-1",
+  "el-icon-medal",
+  "el-icon-trophy",
+  "el-icon-trophy-1",
+  "el-icon-first-aid-kit",
+  "el-icon-discover",
+  "el-icon-place",
+  "el-icon-location",
+  "el-icon-location-outline",
+  "el-icon-location-information",
+  "el-icon-add-location",
+  "el-icon-delete-location",
+  "el-icon-map-location",
+  "el-icon-alarm-clock",
+  "el-icon-timer",
+  "el-icon-watch-1",
+  "el-icon-watch",
+  "el-icon-lock",
+  "el-icon-unlock",
+  "el-icon-key",
+  "el-icon-service",
+  "el-icon-mobile-phone",
+  "el-icon-bicycle",
+  "el-icon-truck",
+  "el-icon-ship",
+  "el-icon-basketball",
+  "el-icon-football",
+  "el-icon-soccer",
+  "el-icon-baseball",
+  "el-icon-wind-power",
+  "el-icon-light-rain",
+  "el-icon-lightning",
+  "el-icon-heavy-rain",
+  "el-icon-sunrise",
+  "el-icon-sunrise-1",
+  "el-icon-sunset",
+  "el-icon-sunny",
+  "el-icon-cloudy",
+  "el-icon-partly-cloudy",
+  "el-icon-cloudy-and-sunny",
+  "el-icon-moon",
+  "el-icon-moon-night",
+  "el-icon-dish",
+  "el-icon-dish-1",
+  "el-icon-food",
+  "el-icon-chicken",
+  "el-icon-fork-spoon",
+  "el-icon-knife-fork",
+  "el-icon-burger",
+  "el-icon-tableware",
+  "el-icon-sugar",
+  "el-icon-dessert",
+  "el-icon-ice-cream",
+  "el-icon-hot-water",
+  "el-icon-water-cup",
+  "el-icon-coffee-cup",
+  "el-icon-cold-drink",
+  "el-icon-goblet",
+  "el-icon-goblet-full",
+  "el-icon-goblet-square",
+  "el-icon-goblet-square-full",
+  "el-icon-refrigerator",
+  "el-icon-grape",
+  "el-icon-watermelon",
+  "el-icon-cherry",
+  "el-icon-apple",
+  "el-icon-pear",
+  "el-icon-orange",
+  "el-icon-coffee",
+  "el-icon-ice-tea",
+  "el-icon-ice-drink",
+  "el-icon-milk-tea",
+  "el-icon-potato-strips",
+  "el-icon-lollipop",
+  "el-icon-ice-cream-square",
+  "el-icon-ice-cream-round"
+]

+ 104 - 0
src/components/IconSelect/index.vue

@@ -0,0 +1,104 @@
+<template>
+  <el-popover width="510" v-model="showDropdown" @show="onDropdownShow">
+    <div class="icon-select-dropdown">
+      <el-row type="flex" style="flex-wrap: wrap">
+        <el-col :span="3" v-for="icon in getIconList" :key="icon" class="icon-item"
+          :class="{active: (value === icon)}" @click.native="onIconClick(icon)">
+          <i :class="icon" />
+        </el-col>
+      </el-row>
+      <el-row type="flex" justify="space-between">
+        <el-button type="text" @click="onClearClick" style="margin-left: 10px;">清空</el-button>
+        <el-pagination
+          :current-page.sync="currentPage"
+          :page-size="pageSize"
+          layout="prev, pager, next"
+          :total="getIconCount">
+        </el-pagination>
+      </el-row>
+    </div>
+    <div slot="reference" class="icon-select"
+      :style="{width: height + 'px', height: height + 'px', 'line-height': height + 'px', 'font-size': height * 0.5 + 'px'}">
+      <i :class="value" />
+    </div>
+  </el-popover>
+</template>
+
+<script>
+import iconList from './icon.json';
+
+export default {
+  props: {
+    /**
+     * 绑定字段
+     */
+    value: String,
+    /**
+     * 组件高度,单位px
+     */
+    height: {
+      type: Number,
+      default: 45
+    }
+  },
+  data () {
+    return {
+      showDropdown: false,
+      currentPage: 1,
+      pageSize: 32
+    }
+  },
+  methods: {
+    onIconClick (icon) {
+      this.$emit('input', icon);
+      this.showDropdown = false;
+    },
+    onClearClick () {
+      this.$emit('input');
+      this.showDropdown = false;
+    },
+    onDropdownShow () {
+      this.currentPage = 1
+      let pos = iconList.indexOf(this.value);
+      if (pos >= 0) {
+        this.currentPage += Math.floor(pos / this.pageSize);
+      }
+    }
+  },
+  computed: {
+    getIconCount () {
+      return iconList.length;
+    },
+    getIconList () {
+      let beginPos = (this.currentPage - 1) * this.pageSize;
+      let endPos = beginPos + this.pageSize;
+      return iconList.slice(beginPos, endPos);
+    }
+  }
+}
+</script>
+
+<style scoped>
+  .icon-select {
+    text-align: center;
+    color: #5F6266;
+    border: 1px solid #DCDFE6;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+  .icon-item {
+    width: 40px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    font-size: 20px;
+    color: #5F6266;
+    border-radius: 3px;
+    border: 1px solid #DCDFE6;
+    margin: 10px;
+    cursor: pointer;
+  }
+  .active {
+    color: #EF5E1C;
+  }
+</style>

+ 226 - 0
src/components/InputNumberRange/index.vue

@@ -0,0 +1,226 @@
+<template>
+  <div class="el-input el-date-editor el-range-editor el-input__inner el-input-number-range"
+    :class="
+    [
+      inputSize ? 'el-range-editor--' + inputSize : '',
+      focused ? 'is-active' : '',
+      {
+        'is-disabled': inputDisabled,
+        'el-input--prefix': prefixIcon
+      }
+    ]"
+    @mouseenter="showClose = true"
+    @mouseleave="showClose = false">
+    <div class="el-input__icon el-range__icon" :class="prefixIcon">
+      <slot name="prepend"></slot>
+    </div>
+    <input
+      autocomplete="off"
+      :placeholder="startPlaceholder"
+      :value="userInput && userInput[0]"
+      :disabled="inputDisabled"
+      :readonly="readonly"
+      :name="name && name[0]"
+      @input="handleStartInput"
+      @change="handleStartChange"
+      @focus="focused = true"
+      @blur="focused = false"
+      class="el-range-input">
+    <slot name="range-separator">
+      <span class="el-range-separator">{{ rangeSeparator }}</span>
+    </slot>
+    <input
+      autocomplete="off"
+      :placeholder="endPlaceholder"
+      :value="userInput && userInput[1]"
+      :disabled="inputDisabled"
+      :readonly="readonly"
+      :name="name && name[1]"
+      @input="handleEndInput"
+      @change="handleEndChange"
+      @focus="focused = true"
+      @blur="focused = false"
+      class="el-range-input">
+    <i class="el-input__icon el-range__close-icon"
+      :class="[showClear ? 'el-icon-circle-close' : '']"
+      @click="handleClickClear">
+    </i>
+  </div>
+</template>
+
+<script>
+import emitter from 'element-ui/src/mixins/emitter';
+
+function isNumber (val) {
+  var regPos = /^\d+(\.\d+)?$/; // 非负浮点数
+  var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; // 负浮点数
+  if (regPos.test(val) || regNeg.test(val)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+export default {
+  name: 'InputNumberRange',
+  componentName: 'InputNumberRange',
+  mixins: [emitter],
+  props: {
+    /**
+     * 绑定字段
+     */
+    value: {
+      type: Array,
+      default: function () {
+        return [];
+      }
+    },
+    /**
+     * 组件大小(medium / small / mini)
+     */
+    size: String,
+    /**
+     * 禁用
+     */
+    disabled: Boolean,
+    /**
+     * 完全只读
+     */
+    readonly: Boolean,
+    /**
+     * 是否显示清除按钮
+     */
+    clearable: {
+      type: Boolean,
+      default: false
+    },
+    /**
+     * 自定义头部图标的类名
+     */
+    prefixIcon: String,
+    /**
+     * 范围选择时最小值的占位内容
+     */
+    startPlaceholder: String,
+    /**
+     * 范围选择时最大值的占位内容
+     */
+    endPlaceholder: String,
+    /**
+     * 原生属性
+     */
+    name: {
+      default: ''
+    },
+    /**
+     * 选择范围时的分隔符
+     */
+    rangeSeparator: {
+      type: String,
+      default: '-'
+    },
+    validateEvent: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data () {
+    return {
+      hovering: false,
+      focused: false,
+      userInput: this.value,
+      showClose: false
+    };
+  },
+  inject: {
+    elForm: {
+      default: ''
+    },
+    elFormItem: {
+      default: ''
+    }
+  },
+  computed: {
+    _elFormItemSize () {
+      return (this.elFormItem || {}).elFormItemSize;
+    },
+    inputSize () {
+      let temp = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
+      return temp;
+    },
+    inputDisabled () {
+      return this.disabled || (this.elForm || {}).disabled;
+    },
+    showClear () {
+      let temp = this.clearable && !this.inputDisabled && !this.readonly && this.showClose &&
+        this.userInput != null && Array.isArray(this.userInput) && this.userInput.length > 0 &&
+        (this.userInput[0] != null || this.userInput[1] != null);
+      return temp;
+    }
+  },
+  methods: {
+    handleStartInput (event) {
+      if (this.userInput) {
+        this.userInput = [event.target.value, this.userInput[1]];
+      } else {
+        this.userInput = [event.target.value, null];
+      }
+    },
+
+    handleEndInput (event) {
+      if (this.userInput) {
+        this.userInput = [this.userInput[0], event.target.value];
+      } else {
+        this.userInput = [null, event.target.value];
+      }
+    },
+    handleStartChange (event) {
+      let value = this.userInput && this.userInput[0];
+      value = isNumber(value) ? value : null;
+      value = value ? Number.parseFloat(value) : null;
+      if (this.userInput) {
+        this.userInput[0] = value;
+      } else {
+        this.userInput = [value, null];
+      }
+      event.srcElement.value = value;
+      this.emitInput(this.userInput);
+    },
+    handleEndChange (event) {
+      let value = this.userInput && this.userInput[1];
+      value = isNumber(value) ? value : null;
+      value = value ? Number.parseFloat(value) : null;
+      if (this.userInput) {
+        this.userInput[1] = value;
+      } else {
+        this.userInput = [null, value];
+      }
+      event.srcElement.value = value;
+      this.emitInput(this.userInput);
+    },
+    handleClickClear () {
+      this.userInput = undefined;
+      this.emitInput(this.userInput);
+    },
+    valueEquals (val, oldVal) {
+      return JSON.stringify(val) === JSON.stringify(oldVal);
+    },
+    emitInput (values) {
+      this.$emit('input', values);
+      this.$emit('change', values);
+    }
+  },
+  watch: {
+    value: {
+      handler: function (val, oldVal) {
+        if (!this.valueEquals(val, oldVal) && this.validateEvent) {
+          this.dispatch('ElFormItem', 'el.form.change', val);
+        }
+      },
+      deep: true
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 44 - 0
src/components/Progress/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <el-progress v-bind="$attrs" :percentage="getPercentage" />
+</template>
+
+<script>
+export default {
+  name: 'Progress',
+  props: {
+    /**
+     * 组件最小值
+     */
+    min: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * 组件最大值
+     */
+    max: {
+      type: Number,
+      default: 100
+    },
+    /**
+     * 组件当前值
+     */
+    value: {
+      type: Number,
+      default: 0
+    }
+  },
+  computed: {
+    getPercentage () {
+      let value = Math.min(this.max, Math.max(this.min, this.value));
+      value = value - this.min;
+      if ((this.max - this.min) === 0) {
+        value = 0;
+      } else {
+        value = ((value * 100) / (this.max - this.min));
+      }
+      return Number.isInteger(value) ? value : parseInt(value);
+    }
+  }
+}
+</script>

+ 132 - 0
src/components/RichEditor/index.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="uditor-class" ref="editor"></div>
+</template>
+
+<script>
+import WEditor from 'wangeditor';
+
+const defaultConfigs = {
+  uploadImgServer: undefined,
+  uploadFileName: 'imageFile',
+  uploadImgMaxSize: 1 * 1024 * 1024,
+  uploadImgShowBase64: true,
+  uploadImgMaxLength: 5,
+  uploadImgParams: undefined,
+  uploadImgParamsWithUrl: true,
+  withCredentials: true,
+  uploadImgTimeout: 5000,
+  uploadImgHeaders: undefined,
+  uploadImgHooks: undefined,
+  zIndex: 0,
+  lang: undefined,
+  pasteFilterStyle: true,
+  pasteIgnoreImg: false,
+  onchangeTimeout: 10,
+  menus: [
+    // 标题
+    'head',
+    // 粗体
+    'bold',
+    // 字号
+    'fontSize',
+    // 字体
+    'fontName',
+    // 斜体
+    'italic',
+    // 下划线
+    'underline',
+    // 删除线
+    'strikeThrough',
+    // 文字颜色
+    'foreColor',
+    // 背景颜色
+    'backColor',
+    // 插入链接
+    'link',
+    // 列表
+    'list',
+    // 对齐方式
+    'justify',
+    // 引用
+    'quote',
+    // 插入图片
+    'image',
+    // 撤销
+    'undo',
+    // 重复
+    'redo'
+  ]
+}
+
+export default {
+  props: {
+    /**
+     * 绑定字段
+     */
+    value: {
+      type: String
+    },
+    /**
+     * 配置项,详情请参考wangEditor文档
+     */
+    config: {
+      type: Object,
+      default: () => {
+        return defaultConfigs;
+      }
+    }
+  },
+  data () {
+    return {
+      editor: null
+    }
+  },
+  methods: {
+    getHtml () {
+      return this.editor ? this.editor.txt.html() : undefined;
+    }
+  },
+  computed: {
+    getConfigs () {
+      return {...this.config, ...defaultConfigs};
+    }
+  },
+  mounted () {
+    this.editor = new WEditor(this.$refs.editor);
+    this.editor.customConfig = {...this.getConfigs};
+    this.editor.customConfig.pasteTextHandle = (content) => {
+      // content 即粘贴过来的内容(html 或 纯文本),可进行自定义处理然后返回
+      return content;
+    }
+    this.editor.customConfig.linkImgCallback = (url) => {
+    }
+    this.editor.customConfig.linkCheck = (text, link) => {
+      return true // 返回 true 表示校验成功
+      // return '验证失败' // 返回字符串,即校验失败的提示信息
+    }
+
+    this.editor.customConfig.linkImgCheck = (src) => {
+      return true // 返回 true 表示校验成功
+      // return '验证失败' // 返回字符串,即校验失败的提示信息
+    }
+    // 失去焦点后更新数据
+    this.editor.customConfig.onblur = (html) => {
+      this.$emit('input', html);
+    }
+
+    this.editor.create();
+    this.editor.txt.html(this.value);
+  },
+  watch: {
+    value: {
+      handler (newValue) {
+        if (this.editor) this.editor.txt.html(this.value);
+      },
+      immediate: true
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 119 - 0
src/components/TableProgressColumn/index.vue

@@ -0,0 +1,119 @@
+<template>
+  <el-table-column v-bind="$attrs">
+    <template slot-scope="scope">
+      <orange-progress :stroke-width="strokeWidth" :type="type" :text-inside="textInside" :status="status" :color="color"
+        :width="width" :show-text="showText" :min="getMinValue(scope.row)" :max="getMaxValue(scope.row)"
+        :value="getValue(scope.row)" />
+    </template>
+  </el-table-column>
+</template>
+
+<script>
+import Progress from '@/components/Progress/index.vue';
+
+export default {
+  name: 'TableProgressColumn',
+  components: {
+    'orange-progress': Progress
+  },
+  props: {
+    /**
+     * 固定值最小值
+     */
+    min: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * 固定值最大值
+     */
+    max: {
+      type: Number,
+      default: 100
+    },
+    /**
+     * 固定值当前值
+     */
+    value: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * 表格最小值字段名
+     */
+    minColumn: {
+      type: String
+    },
+    /**
+     * 表格最大值字段名
+     */
+    maxColumn: {
+      type: String
+    },
+    /**
+     * 表格当前值字段名
+     */
+    valueColumn: {
+      type: String
+    },
+    /**
+     * 进度条的宽度,单位 px
+     */
+    strokeWidth: {
+      type: Number,
+      default: 16
+    },
+    /**
+     * 进度条类型(line/circle/dashboard)
+     */
+    type: {
+      type: String,
+      default: 'line'
+    },
+    /**
+     * 进度条显示文字内置在进度条内(只在 type=line 时可用)
+     */
+    textInside: {
+      type: Boolean,
+      default: true
+    },
+    /**
+     * 进度条当前状态(success/exception/warning)
+     */
+    status: {
+      type: String
+    },
+    /**
+     * 进度条背景色(会覆盖 status 状态颜色)
+     */
+    color: {
+      type: [String, Function, Array]
+    },
+    /**
+     * 环形进度条画布宽度(只在 type 为 circle 或 dashboard 时可用)
+     */
+    width: {
+      type: Number,
+      default: 126
+    },
+    /**
+     * 是否显示进度条文字内容
+     */
+    showText: {
+      type: Boolean,
+      default: true
+    }
+  },
+  methods: {
+    getValue (row) {
+      return this.valueColumn ? row[this.valueColumn] : this.value;
+    },
+    getMinValue (row) {
+      return this.minColumn ? row[this.minColumn] : this.min;
+    },
+    getMaxValue (row) {
+      return this.maxColumn ? row[this.maxColumn] : this.max;
+    }
+  }
+}
+</script>

+ 290 - 0
src/components/TreeSelect/index.vue

@@ -0,0 +1,290 @@
+<template>
+  <el-popover ref="popover" placement="bottom-start" trigger="click" popper-class="tree-select-popover"
+    :width="width" @show="onShowPopover">
+    <el-scrollbar :style="{'height': this.height, 'min-width': this.width}" ref="scrollbar">
+      <el-tree ref="dropdownTree" :props="getTreeProps" :highlightCurrent="highlightCurrent" :nodeKey="getDataProps.value"
+        :defaultExpandAll="defaultExpandAll" :expandOnClickNode="expandOnClickNode" :checkOnClickNode="checkOnClickNode"
+        :autoExpandParent="autoExpandParent" :defaultExpandedKeys="defaultExpandedKeys" :showCheckbox="showCheckbox"
+        :checkStrictly="checkStrictly" :defaultCheckedKeys="defaultCheckedKeys" :currentNodeKey="getCurrentNodeKey"
+        :accordion="accordion" :indent="indent" :iconClass="iconClass" :load="loadChildrenNodes" lazy :show-checkbox="multiple"
+        @node-click="onTreeNodeClick" @check="onTreeNodeCheck">
+        <span :style="getNodeStyle(data)" slot-scope="{ node, data }">{{data[getDataProps.label]}}</span>
+      </el-tree>
+    </el-scrollbar>
+    <el-select slot="reference" v-model="selectKeys" :multiple="multiple" :disabled="false" :size="size"
+      :clearable="clearable" :collapseTags="collapseTags" :placeholder="placeholder" popper-class="select-tree-popper"
+      @clear="onClear" @remove-tag="onClear">
+      <el-option v-for="item in selectNodes" :key="item[getDataProps.value]"
+        :value="item[getDataProps.value]" :label="item[getDataProps.label]" />
+    </el-select>
+  </el-popover>
+</template>
+
+<script>
+import { findTreeNode } from '@/utils';
+
+export default {
+  name: 'TreeSelect',
+  props: {
+    value: {
+      type: [String, Number]
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+    size: {
+      type: String
+    },
+    height: {
+      type: String,
+      default: '200px'
+    },
+    width: {
+      type: String,
+      default: '300px'
+    },
+    activeColor: {
+      type: String,
+      default: '#EF5E1C'
+    },
+    clearable: {
+      type: Boolean,
+      default: false
+    },
+    collapseTags: {
+      type: Boolean,
+      default: true
+    },
+    placeholder: {
+      type: String
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    loadingText: {
+      type: String,
+      default: '加载中'
+    },
+    // 树属性
+    data: {
+      type: Array
+    },
+    props: {
+      type: Object,
+      default: () => {
+        return {
+          label: 'label',
+          value: 'value',
+          parentKey: 'parentId',
+          children: 'children',
+          disabled: 'disabled'
+        }
+      }
+    },
+    defaultExpandAll: {
+      type: Boolean,
+      default: false
+    },
+    expandOnClickNode: {
+      type: Boolean,
+      default: true
+    },
+    checkOnClickNode: {
+      type: Boolean,
+      default: false
+    },
+    autoExpandParent: {
+      type: Boolean,
+      default: true
+    },
+    defaultExpandedKeys: {
+      type: Array
+    },
+    checkStrictly: {
+      type: Boolean,
+      default: true
+    },
+    currentNodeKey: {
+      type: [String, Number]
+    },
+    accordion: {
+      type: Boolean,
+      default: false
+    },
+    indent: {
+      type: Number,
+      default: 16
+    },
+    iconClass: {
+      type: String
+    }
+  },
+  data () {
+    return {
+      rootNode: undefined,
+      rootResolve: undefined,
+      allTreeNode: [],
+      selectNodes: [],
+      scrollTop: 0,
+      selectKeys: undefined
+    }
+  },
+  methods: {
+    onShowPopover () {
+      setTimeout(() => {
+        this.$refs.scrollbar.wrap.scrollTop = this.scrollTop;
+        // this.$refs.scrollbar.update();
+      }, 20);
+      if (!this.multiple) {
+        this.$refs.dropdownTree.setCurrentKey(this.value);
+      }
+    },
+    onClear () {
+      this.$nextTick(() => {
+        this.$emit('input', this.selectKeys);
+      });
+    },
+    onTreeNodeClick (data, node) {
+      this.$refs.popover.showPopper = false;
+      if (!this.multiple) {
+        this.scrollTop = this.$refs.scrollbar.wrap.scrollTop;
+        this.$emit('input', data[this.getDataProps.value]);
+        this.$emit('change', data[this.getDataProps.value]);
+      }
+    },
+    onTreeNodeCheck (data, {checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys}) {
+      this.scrollTop = this.$refs.scrollbar.wrap.scrollTop
+      this.$emit('input', checkedKeys);
+      this.$emit('change', checkedKeys);
+    },
+    parseNode (node) {
+      if (Array.isArray(node) && node.length > 0) {
+        node.forEach((item) => {
+          item['__node_is_leaf__'] = !(Array.isArray(item[this.getDataProps.children]) && item[this.getDataProps.children].length > 0);
+        });
+        return node;
+      } else {
+        return [];
+      }
+    },
+    loadChildrenNodes (node, resolve) {
+      if (node.level === 0) {
+        this.rootNode = node;
+        this.rootResolve = resolve;
+        return resolve(this.parseNode(this.allTreeNode));
+      } else {
+        return resolve(this.parseNode(node.data[this.getDataProps.children]));
+      }
+    },
+    getNodeStyle (data) {
+      if (!this.multiple && (this.selectNodes[0] || {})[this.getDataProps.value] === data[this.getDataProps.value]) {
+        return {
+          color: this.activeColor,
+          'font-weight': 700
+        }
+      }
+    }
+  },
+  computed: {
+    showCheckbox () {
+      return this.multiple;
+    },
+    getCurrentNodeKey () {
+      if (!this.multiple && Array.isArray(this.selectNodes) && this.selectNodes.length > 0) {
+        return this.selectNodes[0][this.getDataProps.value];
+      } else {
+        return null;
+      }
+    },
+    highlightCurrent () {
+      return this.multiple;
+    },
+    defaultCheckedKeys () {
+      return this.multiple ? this.selectNodes : undefined
+    },
+    getDataProps () {
+      return {
+        label: this.props.label || 'label',
+        value: this.props.value || 'value',
+        parentKey: this.props.parentKey || 'parentId',
+        children: this.props.children || 'children',
+        disabled: this.props.disabled || 'disabled'
+      }
+    },
+    getTreeProps () {
+      return {
+        label: this.getDataProps.label,
+        children: '__children_list__',
+        disabled: this.getDataProps.disabled,
+        isLeaf: '__node_is_leaf__'
+      };
+    }
+  },
+  watch: {
+    data: {
+      handler (newValue, oldValue) {
+        this.allTreeNode = newValue;
+        if (this.rootNode != null && this.rootResolve != null) {
+          this.rootNode.childNodes = [];
+          this.loadChildrenNodes(this.rootNode, this.rootResolve);
+        }
+        this.selectNodes = [];
+        if (this.multiple) {
+          if (Array.isArray(this.value)) {
+            this.value.forEach((item) => {
+              let data = findTreeNode(this.allTreeNode, item, this.getDataProps.value, this.getDataProps.children);
+              if (data) this.selectNodes.push(data);
+            });
+          }
+        } else {
+          let data = findTreeNode(this.allTreeNode, this.value, this.getDataProps.value, this.getDataProps.children);
+          if (data) this.selectNodes.push(data);
+        }
+      },
+      immediate: true
+    },
+    value: {
+      handler (newValue) {
+        this.selectNodes = [];
+        if (Array.isArray(newValue)) {
+          newValue.forEach((item) => {
+            let data = findTreeNode(this.allTreeNode, item, this.getDataProps.value, this.getDataProps.children);
+            if (data) this.selectNodes.push(data);
+          });
+          this.selectKeys = newValue;
+        } else {
+          let data = findTreeNode(this.allTreeNode, newValue, this.getDataProps.value, this.getDataProps.children);
+          if (data) this.selectNodes.push(data);
+          this.selectKeys = newValue;
+        }
+        if (this.$refs.dropdownTree) {
+          this.multiple ? this.$refs.dropdownTree.setCheckedKeys(newValue) : this.$refs.dropdownTree.setCurrentKey(newValue);
+        }
+      },
+      immediate: true
+    }
+  }
+}
+</script>
+
+<style>
+  .select-tree-popper {
+    display: none;
+  }
+  .tree-select-popover {
+    padding: 6px 0px;
+  }
+  .tree-select-popover .popper__arrow {
+    left: 35px!important;
+  }
+  .tree-select-popover .el-tree .el-tree-node__content {
+    height: 34px;
+    line-height: 34px;
+  }
+</style>

+ 5 - 0
src/core/config/development.js

@@ -0,0 +1,5 @@
+module.exports = {
+ // baseUrl: "http://180.76.231.231:8082/",
+   baseUrl: "http://localhost:8084/",
+  projectName: "模型管理平台",
+};

+ 18 - 0
src/core/config/index.js

@@ -0,0 +1,18 @@
+const projectConfig = require('../config/' + process.env.NODE_ENV);
+
+export const globalConfig = {
+  httpOption: {
+    // 调用的时候是否显示蒙版
+    showMask: true,
+    // 是否显示公共的错误提示
+    showError: true,
+    // 是否开启节流功能,同一个url不能频繁重复调用
+    throttleFlag: false,
+    // 节流间隔
+    throttleTimeout: 50
+  },
+  axiosOption: {
+  }
+};
+
+export default projectConfig;

+ 5 - 0
src/core/config/production.js

@@ -0,0 +1,5 @@
+module.exports = {
+ // baseUrl: "http://180.76.231.231:8082/",
+   baseUrl: "http://localhost:8082/",
+  projectName: "模型管理平台",
+};

+ 14 - 0
src/core/directive/sortable.js

@@ -0,0 +1,14 @@
+import Vue from 'vue'
+import { SortableData } from './sortableData';
+
+/**
+ * 拖拽排序指令
+ */
+Vue.directive('sortable', {
+  inserted: function (el, binding, vnode) {
+    let sortableData = binding.value;
+    if (sortableData == null || !(sortableData instanceof SortableData)) return;
+    
+    sortableData.init(vnode.elm);
+  }
+});

+ 60 - 0
src/core/directive/sortableData.js

@@ -0,0 +1,60 @@
+import sortable from 'sortablejs'
+/**
+ * 拖拽排序对象
+ * expample
+ * <ul v-sortable="new SortableData(data)">
+ *   <li>A</li>
+ *   <li>B</li>
+ *   <li>C</li>
+ *   <li>D</li>
+ * </ul>
+ */
+export class SortableData {
+  constructor (data, group) {
+    this.list = data;
+    this.group = group;
+    this.ghostClass = 'sortable-ghost';
+    this.sortable = null;
+    this.disabled = false;
+  };
+
+  setData (list) {
+    this.list = list;
+  }
+
+  getElement (el) {
+    return el;
+  };
+
+  onEnd (oldIndex, newIndex) {
+    if (oldIndex === newIndex || this.list == null) return;
+    let targetRow = this.list.splice(oldIndex, 1)[0]
+    this.list.splice(newIndex, 0, targetRow);
+  };
+
+  init (el) {
+    var _this = this;
+
+    var _option = {};
+    if (this.ghostClass != null) _option.ghostClass = this.ghostClass;
+    if (this.group != null) _option.group = this.group;
+    if (this.disabled != null) _option.disabled = this.disabled;
+    // 列表中能拖动的dom的选择器(例如:.drag-item)
+    if (this.draggable != null) _option.draggable = this.draggable;
+    // 列表中拖动项,拖动把柄的选择器,只有点击这个选择出来的dom才可以开始拖动(例如:.drag-handle)
+    if (this.handle != null) _option.handle = this.handle;
+    _option.setData = function (dataTransfer) {
+      dataTransfer.setData('Text', '');
+    };
+    _option.onEnd = function (evt) {
+      _this.onEnd(evt.oldIndex, evt.newIndex);
+    };
+
+    this.sortable = sortable.create(_this.getElement(el), _option);
+  };
+
+  release () {
+    if (this.sortable != null) this.sortable.destroy();
+    this.sortable = null;
+  }
+};

+ 203 - 0
src/core/http/index.js

@@ -0,0 +1,203 @@
+import Vue from 'vue';
+import { Loading, Message } from 'element-ui';
+import request from './request';
+import requestUrl from './requestUrl';
+import { globalConfig } from '@/core/config';
+
+/**
+ * 遮罩管理,多次调用支持引用计数
+ */
+class LoadingManager {
+  constructor (options) {
+    this.options = options;
+    this.refCount = 0;
+    this.loading = undefined;
+  }
+
+  showMask () {
+    this.loading = Loading.service(this.options);
+    this.refCount++;
+  }
+
+  hideMask () {
+    if (this.refCount <= 1 && this.loading != null) {
+      this.loading.close();
+      this.loading = null;
+    }
+    this.refCount--;
+    this.refCount = Math.max(0, this.refCount);
+  }
+}
+
+const loadingManager = new LoadingManager({
+  fullscreen: true,
+  background: 'rgba(0, 0, 0, 0.1)'
+});
+
+/**
+ * post请求
+ * @param {String} url 请求的url
+ * @param {Object} params 请求参数
+ * @param {Object} options axios设置项
+ * @returns {Promise}
+ */
+const fetchPost = function (url, params, options) {
+  if (options == null) return {};
+  let tempOptions = {
+    ...options,
+    method: 'post',
+    url: requestUrl(url),
+    data: params
+  };
+
+  return request(tempOptions);
+};
+/**
+ * get请求
+ * @param {String} url 请求的url
+ * @param {Object} params 请求参数
+ * @param {Object} options axios设置项
+ * @returns {Promise}
+ */
+const fetchGet = function (url, params, options) {
+  if (options == null) return {};
+  let tempOptions = {
+    ...options,
+    method: 'get',
+    url: requestUrl(url),
+    params
+  };
+  return request(tempOptions);
+};
+/**
+ * 下载请求
+ * @param {String} url 请求的url
+ * @param {Object} params 请求参数
+ * @param {String} fileName 下载后保存的文件名
+ * @returns {Promise}
+ */
+const fetchDownload = function (url, params, fileName) {
+  return new Promise((resolve, reject) => {
+    request({
+      url: requestUrl(url),
+      method: 'post',
+      data: params,
+      responseType: 'blob',
+      transformResponse: function (data) {
+        return (data instanceof Blob && data.size > 0) ? data : undefined;
+      }
+    }).then(res => {
+      if (res.data == null) {
+        reject(new Error('下载文件失败'));
+      } else {
+        let blobData = new Blob([res.data], { type: 'application/octet-stream' });
+        let blobUrl = window.URL.createObjectURL(blobData);
+        let linkDom = document.createElement('a');
+        linkDom.style.display = 'none';
+        linkDom.href = blobUrl;
+        linkDom.setAttribute('download', fileName);
+        if (typeof linkDom.download === 'undefined') {
+          linkDom.setAttribute('target', '_blank');
+        }
+        document.body.appendChild(linkDom);
+        linkDom.click();
+        document.body.removeChild(linkDom);
+        window.URL.revokeObjectURL(blobData);
+        resolve();
+      }
+    }).catch(e => {
+      if (e instanceof Blob) {
+        let reader = new FileReader();
+        reader.onload = function () {
+          let jsonObj = JSON.parse(reader.result);
+          reject((jsonObj || {}).errorMessage || '下载文件失败');
+        }
+        reader.readAsText(e);
+      } else {
+        reject(e);
+      }
+    });
+  });
+}
+
+// url调用节流Set
+const ajaxThrottleSet = new Set();
+/**
+ * 数据请求
+ * @param {String} url 请求的url
+ * @param {String} type 请求类型 (get,post)
+ * @param {Object} params 请求参数
+ * @param {Object} axiosOption axios设置
+ * @param {Object} options 显示设置
+ */
+const doUrl = function (url, type, params, axiosOption, options) {
+  let finalOption = {
+    ...globalConfig.httpOption,
+    ...options
+  };
+  let { showMask, showError, throttleFlag, throttleTimeout } = finalOption;
+  let finalAxiosOption = {
+    ...globalConfig.axiosOption,
+    ...axiosOption
+  }
+  if (type == null || type === '') type = 'post';
+  if (ajaxThrottleSet.has(url) && throttleFlag) {
+    return Promise.resolve();
+  } else {
+    if (throttleFlag) {
+      ajaxThrottleSet.add(url);
+      setTimeout(() => {
+        ajaxThrottleSet.delete(url);
+      }, throttleTimeout || 50);
+    }
+    return new Promise((resolve, reject) => {
+      if (showMask) loadingManager.showMask();
+      let ajaxCall = null;
+      if (type.toLowerCase() === 'get') {
+        ajaxCall = fetchGet(url, params, finalAxiosOption);
+      } else if (type.toLowerCase() === 'post') {
+        ajaxCall = fetchPost(url, params, finalAxiosOption);
+      }
+  
+      if (ajaxCall != null) {
+        ajaxCall.then(res => {
+          if (showMask) loadingManager.hideMask();
+          if (res.data && res.data.success) {
+            resolve(res.data);
+          } else {
+            if (showError) {
+              Message.error({
+                showClose: true,
+                message: res.data.errorMessage ? res.data.errorMessage : '数据请求失败'
+              });
+            }
+            reject(res.data);
+          }
+        }).catch(e => {
+          if (showMask) loadingManager.hideMask();
+          if (showError) {
+            Message.error({
+              showClose: true,
+              message: e.errorMessage ? e.errorMessage : '网络请求错误'
+            });
+          }
+          reject(e);
+        });
+      } else {
+        if (showMask) loadingManager.hideMask();
+        reject(new Error('错误的请求类型 - ' + type));
+      }
+    });
+  }
+};
+
+Vue.prototype.download = fetchDownload;
+Vue.prototype.doUrl = doUrl;
+Vue.prototype.loadingManager = loadingManager;
+
+export default {
+  doUrl,
+  fetchPost,
+  fetchGet,
+  fetchDownload
+}

+ 75 - 0
src/core/http/request.js

@@ -0,0 +1,75 @@
+import axios from 'axios';
+import router from '@/router';
+import dialog from '@/components/Dialog';
+import JSONbig from 'json-bigint';
+import { getToken, setToken } from '@/utils';
+
+// 创建axios实例
+const service = axios.create({
+  timeout: 1000 * 30,
+  withCredentials: true,
+  headers: {
+    // 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
+    'Content-Type': 'application/json; charset=utf-8',
+    'deviceType': '4'
+  },
+  transformResponse: [
+    function (data) {
+      if (typeof data === 'string') {
+        const JSONbigString = new JSONbig({storeAsString: true});
+        return JSONbigString.parse(data);
+      } else {
+        return data;
+      }
+    }
+  ]
+})
+
+// request拦截器
+service.interceptors.request.use(
+  config => {
+    let token = getToken();
+    let menuIdJsonStr = window.sessionStorage.getItem('currentMenuId');
+    let currentMenuId;
+    if (menuIdJsonStr != null) {
+      currentMenuId = (JSON.parse(menuIdJsonStr) || {}).data;
+    }
+    if (token != null) config.headers['Authorization'] = token;
+    if (currentMenuId != null) config.headers['MenuId'] = currentMenuId;
+    return config
+  }, error => {
+    return Promise.reject(error)
+  }
+);
+
+// response拦截器
+service.interceptors.response.use(
+  response => {
+    if (response.data && response.data.errorCode === 'UNAUTHORIZED_LOGIN') { // 401, token失效
+      dialog.closeAll();
+      router.push({ name: 'login' })
+    } else {
+      if (response.headers['refreshedtoken'] != null) {
+        setToken(response.headers['refreshedtoken']);
+      }
+    }
+    return response
+  }, error => {
+    let response = error.response;
+
+    if (response && response.data) {
+      if (response.data.errorCode === 'UNAUTHORIZED_LOGIN') {
+        dialog.closeAll();
+        router.push({ name: 'login' });
+      }
+
+      return Promise.reject(response.data);
+    } else {
+      return Promise.reject(new Error({
+        errorMessage: '数据获取失败,请稍后再试'
+      }));
+    }
+  }
+);
+
+export default service

+ 27 - 0
src/core/http/requestUrl.js

@@ -0,0 +1,27 @@
+import projectConfig from '@/core/config';
+import { objectToQueryString } from '@/utils';
+console.log(process.env.NODE_ENV, projectConfig);
+
+/**
+ * 请求地址统一处理/组装
+ * @param actionName action方法名称
+ */
+export default function (actionName) {
+  if (actionName != null && actionName !== '') {
+    if (actionName.substr(0, 1) === '/') actionName = actionName.substr(1);
+  }
+  return projectConfig.baseUrl + actionName;
+}
+
+export function buildGetUrl (actionName, params) {
+  let queryString = objectToQueryString(params);
+  if (actionName != null && actionName !== '') {
+    if (actionName.substr(0, 1) === '/') actionName = actionName.substr(1);
+  }
+
+  return projectConfig.baseUrl + actionName + (queryString == null ? '' : ('?' + queryString));
+}
+
+export {
+  projectConfig
+}

+ 114 - 0
src/core/mixins/global.js

@@ -0,0 +1,114 @@
+import Vue from 'vue';
+import Request from '@/core/http/request.js';
+import { mapMutations, mapGetters } from 'vuex';
+
+// 全局mixin对象
+const globalMixin = {
+  data () {
+    return {
+      isHttpLoading: false
+    }
+  },
+  methods: {
+    /**
+     * 是否显示遮罩
+     * @param {Boolean} isShow  是否显示
+     */
+    showMask (isShow) {
+      isShow ? this.loadingManager.showMask() : this.loadingManager.hideMask();
+    },
+    /**
+     * 判读用户是否有权限
+     * @param {String} permCode  权限字
+     */
+    checkPermCodeExist (permCode) {
+      if ((this.getUserInfo || {}).permCodeSet != null) {
+        return this.getUserInfo.permCodeSet.has(permCode);
+      } else {
+        return this.getUserInfo.isAdmin;
+      }
+    },
+    /**
+     * 将输入的值转换成指定的类型
+     * @param {Any} value
+     * @param {String} type 要转换的类型(integer、float、boolean、string)
+     */
+    parseParams (value, type = 'string') {
+      if (value == null) return value;
+      switch (type) {
+        case 'integer': return Number.parseInt(value);
+        case 'float': return Number.parseFloat(value);
+        case 'boolean': return (value === 'true' || value);
+        default: return String(value);
+      }
+    },
+    /**
+     * 将输入值转换为执行的类型数组
+     * @param {Array} value 输入数组
+     * @param {String} type 要转换的类型(integer、float、boolean、string)
+     */
+    parseArrayParams (value, type = 'string') {
+      if (Array.isArray(value)) {
+        return value.map((item) => {
+          switch (type) {
+            case 'integer': return Number.parseInt(item);
+            case 'float': return Number.parseFloat(item);
+            case 'boolean': return (item === 'true' || item);
+            default: return String(item);
+          }
+        });
+      } else {
+        return [];
+      }
+    },
+    /**
+     * 下载上传的文件
+     * @param {*} url 下载文件的url
+     * @param {*} fileName 下载文件名
+     */
+    downloadFile (url, fileName) {
+      Request({
+        url: url,
+        method: 'get',
+        responseType: 'blob',
+        transformResponse: function (data) {
+          return data;
+        }
+      }).then(res => {
+        let data = res.data;
+        if (res.status === 200 && data instanceof Blob) {
+          let url = window.URL.createObjectURL(data);
+          let link = document.createElement('a');
+          link.style.display = 'none';
+          link.href = url;
+          link.setAttribute('download', fileName);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('下载文件失败');
+        }
+      }).catch(e => {
+        let reader = new FileReader();
+        reader.onload = () => {
+          let jsonObj = JSON.parse(reader.result);
+          this.$message.error((jsonObj || {}).errorMessage || '下载文件失败');
+        }
+        reader.readAsText(e);
+      });
+    },
+    ...mapMutations(['setLoadingStatus'])
+  },
+  computed: {
+    ...mapGetters(['getUserInfo'])
+  },
+  watch: {
+    'loadingManager.loading': {
+      handler: function (newValue) {
+        this.isHttpLoading = (newValue != null);
+      }
+    }
+  }
+}
+
+Vue.mixin(globalMixin);

+ 298 - 0
src/core/mixins/index.js

@@ -0,0 +1,298 @@
+import projectConfig from '@/core/config';
+import { buildGetUrl } from '@/core/http/requestUrl.js';
+import { formatDate, parseDate } from 'element-ui/src/utils/date-util';
+import { mapMutations } from 'vuex';
+import { getToken } from '@/utils';
+
+/**
+ * 上传文件组件相关方法
+ */
+const uploadMixin = {
+  methods: {
+    /**
+     * 解析返回的上传文件数据
+     * @param {String} jsonData 上传文件数据,[{name, downloadUri, filename}]
+     * @param {Object} params 上传文件的参数
+     * @returns {Array} 上传文件信息,[{name, downloadUri, filename, url}]
+     */
+    parseUploadData (jsonData, params) {
+      let pathList = [];
+      if (jsonData != null) {
+        try {
+          pathList = JSON.parse(jsonData);
+        } catch (e) {
+          console.error(e);
+        }
+      }
+
+      return pathList.map((item) => {
+        let downloadParams = {...params};
+        downloadParams.filename = item.filename;
+        return {
+          ...item,
+          url: this.getUploadFileUrl(item, downloadParams)
+        }
+      });
+    },
+    /**
+     * 获得上传文件url列表
+     * @param {*} jsonData 上传文件数据,[{name, downloadUri, filename}]
+     * @param {*} params 上传文件的参数
+     * @returns {Array} 文件url列表
+     */
+    getPictureList (jsonData, params) {
+      let tempList = this.parseUploadData(jsonData, params);
+      if (Array.isArray(tempList)) {
+        return tempList.map(item => item.url);
+      } else {
+        return [];
+      }
+    },
+    /**
+     * 将选中文件信息格式化成json信息
+     * @param {Array} fileList 上传文件列表,[{name, fileUrl, data}]
+     */
+    fileListToJson (fileList) {
+      if (Array.isArray(fileList)) {
+        return JSON.stringify(fileList.map((item) => {
+          return {
+            name: item.name,
+            downloadUri: item.downloadUri || item.response.data.downloadUri,
+            filename: item.filename || item.response.data.filename
+          }
+        }));
+      } else {
+        return undefined;
+      }
+    },
+    /**
+     * 获得上传文件url
+     * @param {*} item 上传文件
+     * @param {*} params 上传文件的参数
+     */
+    getUploadFileUrl (item, params) {
+      if (item == null || item.downloadUri == null) {
+        return null;
+      } else {
+        let menuIdJsonStr = window.sessionStorage.getItem('currentMenuId');
+        let currentMenuId;
+        if (menuIdJsonStr != null) {
+          currentMenuId = (JSON.parse(menuIdJsonStr) || {}).data;
+        }
+        params.Authorization = getToken();
+        params.MenuId = currentMenuId;
+        return buildGetUrl(item.downloadUri, params);
+      }
+    },
+    /**
+     * 获得上传接口
+     * @param {*} url 上传路径
+     */
+    getUploadActionUrl (url) {
+      if (url != null && url[0] === '/') {
+        url = url.substr(1);
+      }
+      return projectConfig.baseUrl + url;
+    },
+    /**
+     * 上传文件是否图片文件
+     * @param {*} file 上传文件
+     */
+    pictureFile (file) {
+      if (['image/jpeg', 'image/jpg', 'image/png'].indexOf(file.type) !== -1) {
+        return true;
+      } else {
+        this.$message.error('图片文件格式不正确,请重新选择');
+        return false;
+      }
+    }
+  },
+  computed: {
+    getUploadHeaders () {
+      let token = getToken();
+      return {
+        Authorization: token
+      }
+    }
+  }
+};
+
+const allowStatsType = [
+  'time',
+  'datetime',
+  'day',
+  'month',
+  'year'
+];
+/**
+ * 日期相关方法
+ */
+const statsDateRangeMixin = {
+  methods: {
+    /**
+     * 根据输入的日期获得日期范围(例如:输入2019-12-12,输出['2019-12-12 00:00:00', '2019-12-12 23:59:59'])
+     * @param {Date|String} date 要转换的日期
+     * @param {String} statsType 转换类型(day, month, year)
+     * @param {String} format 输出格式
+     */
+    getDateRangeFilter (date, statsType = 'day', format = 'yyyy-MM-dd HH:mm:ss') {
+      if (date == null) return [];
+
+      statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
+      date = date.substr(0, date.indexOf(' '));
+      let tempList = date.split('-');
+      let year = Number.parseInt(tempList[0]);
+      let month = Number.parseInt(tempList[1]);
+      let day = Number.parseInt(tempList[2]);
+      if (isNaN(year) || isNaN(month) || isNaN(day)) {
+        return [];
+      }
+      let tempDate = new Date(year, month - 1, day);
+      // 判断是否正确的日期
+      if (isNaN(tempDate.getTime())) return [];
+
+      tempDate.setHours(0, 0, 0, 0);
+      let retDate;
+      switch (statsType) {
+        case 'day':
+          retDate = [
+            new Date(tempDate),
+            new Date(tempDate.setDate(tempDate.getDate() + 1))
+          ];
+          break;
+        case 'month':
+          tempDate.setDate(1);
+          retDate = [
+            new Date(tempDate),
+            new Date(tempDate.setMonth(tempDate.getMonth() + 1))
+          ];
+          break;
+        case 'year':
+          tempDate.setDate(1);
+          tempDate.setMonth(0);
+          retDate = [
+            new Date(tempDate),
+            new Date(tempDate.setFullYear(tempDate.getFullYear() + 1))
+          ]
+      }
+
+      retDate[1] = new Date(retDate[1].getTime() - 1);
+
+      return [
+        formatDate(retDate[0], format),
+        formatDate(retDate[1], format)
+      ];
+    },
+    /**
+     * 格式化日期
+     * @param {Date|String} date 要格式化的日期
+     * @param {String} statsType 输出日期类型
+     * @param {String} format 输入日期的格式
+     */
+    formatDateByStatsType (date, statsType = 'day', format = 'yyyy-MM-dd') {
+      if (date == null) return undefined;
+      statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
+      if (statsType === 'datetime') format = 'yyyy-MM-dd HH:mm:ss';
+      
+      let tempDate = ((date instanceof Date) ? date : parseDate(date, format));
+      if (!tempDate) return undefined;
+      switch (statsType) {
+        case 'time':
+          return formatDate(tempDate, 'HH:mm:ss');
+        case 'datetime':
+          return formatDate(tempDate, 'yyyy-MM-dd HH:mm:ss');
+        case 'day':
+          return formatDate(tempDate, 'yyyy-MM-dd');
+        case 'month':
+          return formatDate(tempDate, 'yyyy-MM');
+        case 'year':
+          return formatDate(tempDate, 'yyyy');
+        default:
+          return formatDate(tempDate, 'yyyy-MM-dd');
+      }
+    },
+    /**
+     * 获得统计类型中文名称
+     * @param {String} statsType 统计类型(day, month, year)
+     */
+    getStatsTypeShowName (statsType) {
+      statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
+      switch (statsType) {
+        case 'day': return '日统计';
+        case 'month': return '月统计';
+        case 'year': return '年统计';
+      }
+    },
+    /**
+     * 获取统计类型字典列表
+     * @param {Array} statsTypeList 统计类型列表
+     */
+    getAllowStatsTypeList (statsTypeList) {
+      if (Array.isArray(statsTypeList) && statsTypeList.length > 0) {
+        return statsTypeList.map((item) => {
+          return {
+            id: item,
+            name: this.getStatsTypeShowName(item)
+          }
+        });
+      } else {
+        return [];
+      }
+    }
+  }
+}
+/**
+ * 页面缓存相关方法
+ */
+const cachePageMixin = {
+  methods: {
+    /**
+     * 移除缓存页面
+     * @param {*} name 缓存组件的名称
+     */
+    removeCachePage (name) {
+      this.removeCachePage(name);
+    },
+    /**
+     * 从跳转页面返回并且刷新当前页面时调用
+     */
+    onResume () {
+    },
+    ...mapMutations(['addCachePage', 'removeCachePage'])
+  },
+  created () {
+    this.addCachePage(this.$options.name);
+  },
+  mounted () {
+    this.$route.meta.refresh = false;
+  },
+  activated () {
+    if (this.$route && this.$route.meta && this.$route.meta.refresh) {
+      this.onResume();
+    }
+    this.$route.meta.refresh = true;
+  }
+}
+/**
+ * 缓存页面跳转页面相关方法
+ */
+const cachedPageChildMixin = {
+  data () {
+    return {
+      // 是否刷新父页面
+      refreshParentCachedPage: false
+    }
+  },
+  beforeRouteLeave (to, from, next) {
+    if (to.meta == null) to.meta = {};
+    to.meta.refresh = this.refreshParentCachedPage;
+    next();
+  }
+}
+
+export {
+  uploadMixin,
+  statsDateRangeMixin,
+  cachePageMixin,
+  cachedPageChildMixin
+}

+ 13 - 13
src/main.js

@@ -5,11 +5,12 @@ import 'element-ui/lib/theme-chalk/index.css';
 import router from './router'
 import store from './store'
 import echarts from 'echarts'
-import 'echarts/map/js/china' 
+import 'echarts/map/js/china'
 import websocket from 'vue-native-websocket'
-import wst from  '@/utils/websocket'
-import SvgIcon from '@/components/svgIcon/index.vue'// svg component
-import '@/assets/svg'  // 导入图标资源
+import wst from '@/utils/websocket'
+import SvgIcon from '@/components/svgIcon/index.vue' // svg component
+import '@/assets/svg' // 导入图标资源
+import '@/core/http';
 // 将自动注册所有组件为全局组件
 import dataV from '@jiaminghi/data-view'
 import VueWorker from 'vue-worker' // Web worker插件
@@ -19,10 +20,10 @@ Vue.prototype.Cesium = Cesium
 Vue.prototype.Widgets = widget
 Vue.use(VueWorker)
 Vue.use(dataV)
-Vue.use(websocket, 'ws://localhost:1234', {// 这里要填的是服务器的地址,可以换一个在线服务器wss://echo.websocket.org
-  reconnection: true, // (Boolean)是否自动重连,默认false
-  reconnectionAttempts: Infinity, // 重连次数
-  reconnectionDelay: 3000, // 再次重连等待时常(1000)
+Vue.use(websocket, 'ws://localhost:1234', { // 这里要填的是服务器的地址,可以换一个在线服务器wss://echo.websocket.org
+    reconnection: true, // (Boolean)是否自动重连,默认false
+    reconnectionAttempts: Infinity, // 重连次数
+    reconnectionDelay: 3000, // 再次重连等待时常(1000)
 })
 Vue.use(wst)
 Vue.prototype.$wst = wst
@@ -32,8 +33,7 @@ Vue.prototype.$store = store
 Vue.component('svg-icon', SvgIcon)
 Vue.config.productionTip = false
 new Vue({
-  router,
-  store,
-  render: h => h(App),
-}).$mount('#app')
-
+    router,
+    store,
+    render: h => h(App),
+}).$mount('#app')

+ 7 - 1
src/router/index.js

@@ -11,9 +11,15 @@ export const constantRoutes = [ // 配置路由,这里是个数组
     { // 每一个链接都是一个对象
         path: '/', // 链接路径
         name: 'root', // 路由名称,
-        redirect: '/home',
+        redirect: '/login',
 
     },
+    {
+        path: '/login',
+        name: 'login',
+        component: () =>
+            import ('@/views/login/index.vue')
+    },
     {
         path: '/home',
         component: Layout,

+ 193 - 0
src/staticDict/flowStaticDict.js

@@ -0,0 +1,193 @@
+/**
+ * 工作流常量字典
+ */
+import Vue from 'vue';
+import { DictionaryBase } from './index.js';
+
+const SysFlowEntryBindFormType = new DictionaryBase('流程绑定表单类型', [
+  {
+    id: 0,
+    name: '动态表单',
+    symbol: 'ONLINE_FORM'
+  },
+  {
+    id: 1,
+    name: '路由表单',
+    symbol: 'ROUTER_FORM'
+  }
+]);
+Vue.prototype.SysFlowEntryBindFormType = SysFlowEntryBindFormType;
+
+const SysFlowEntryPublishedStatus = new DictionaryBase('流程设计发布状态', [
+  {
+    id: 0,
+    name: '未发布',
+    symbol: 'UNPUBLISHED'
+  },
+  {
+    id: 1,
+    name: '已发布',
+    symbol: 'PUBLISHED'
+  }
+]);
+Vue.prototype.SysFlowEntryPublishedStatus = SysFlowEntryPublishedStatus;
+
+const SysFlowEntryStep = new DictionaryBase('流程设计步骤', [
+  {
+    id: 0,
+    name: '编辑基础信息',
+    symbol: 'BASIC'
+  },
+  {
+    id: 1,
+    name: '流程变量设置',
+    symbol: 'PROCESS_VARIABLE'
+  },
+  {
+    id: 2,
+    name: '设计流程',
+    symbol: 'PROCESS_DESIGN'
+  }
+]);
+Vue.prototype.SysFlowEntryStep = SysFlowEntryStep;
+
+const SysFlowTaskOperationType = new DictionaryBase('任务操作类型', [
+  {
+    id: 'agree',
+    name: '同意',
+    symbol: 'AGREE'
+  },
+  {
+    id: 'refuse',
+    name: '拒绝',
+    symbol: 'REFUSE'
+  },
+  {
+    id: 'reject',
+    name: '驳回',
+    symbol: 'REJECT'
+  },
+  {
+    id: 'revoke',
+    name: '撤销',
+    symbol: 'REVOKE'
+  },
+  {
+    id: 'transfer',
+    name: '转办',
+    symbol: 'TRANSFER'
+  },
+  {
+    id: 'multi_consign',
+    name: '加签',
+    symbol: 'CO_SIGN'
+  },
+  {
+    id: 'save',
+    name: '保存',
+    symbol: 'SAVE'
+  },
+  {
+    id: 'stop',
+    name: '终止',
+    symbol: 'STOP'
+  },
+  {
+    id: 'multi_sign',
+    name: '会签',
+    symbol: 'MULTI_SIGN'
+  },
+  {
+    id: 'multi_agree',
+    name: '同意(会签)',
+    symbol: 'MULTI_AGREE'
+  },
+  {
+    id: 'multi_refuse',
+    name: '拒绝(会签)',
+    symbol: 'MULTI_REFUSE'
+  },
+  {
+    id: 'multi_abstain',
+    name: '弃权(会签)',
+    symbol: 'MULTI_ABSTAIN'
+  },
+  {
+    id: 'set_assignee',
+    name: '指定审批人',
+    symbol: 'SET_ASSIGNEE'
+  }
+]);
+Vue.prototype.SysFlowTaskOperationType = SysFlowTaskOperationType;
+
+const SysFlowTaskType = new DictionaryBase('工作流任务类型', [
+  {
+    id: 0,
+    name: '其他任务',
+    symbol: 'OTHER_TASK'
+  },
+  {
+    id: 1,
+    name: '用户任务',
+    symbol: 'USER_TASK'
+  }
+]);
+Vue.prototype.SysFlowTaskType = SysFlowTaskType;
+
+const SysFlowVariableType = new DictionaryBase('工作流变量类型', [
+  {
+    id: 0,
+    name: '流程变量',
+    symbol: 'INSTANCE'
+  },
+  {
+    id: 1,
+    name: '任务变量',
+    symbol: 'TASK'
+  }
+]);
+Vue.prototype.SysFlowVariableType = SysFlowVariableType;
+
+const SysFlowWorkOrderStatus = new DictionaryBase('工单状态', [
+  {
+    id: 0,
+    name: '已提交',
+    symbol: 'SUBMITED'
+  },
+  {
+    id: 1,
+    name: '审批中',
+    symbol: 'APPROVING'
+  },
+  {
+    id: 2,
+    name: '已拒绝',
+    symbol: 'REFUSED'
+  },
+  {
+    id: 3,
+    name: '已完成',
+    symbol: 'FINISHED'
+  },
+  {
+    id: 4,
+    name: '终止',
+    symbol: 'STOPPED'
+  },
+  {
+    id: 5,
+    name: '撤销',
+    symbol: 'CANCEL'
+  }
+]);
+Vue.prototype.SysFlowWorkOrderStatus = SysFlowWorkOrderStatus;
+
+export {
+  SysFlowEntryPublishedStatus,
+  SysFlowEntryBindFormType,
+  SysFlowEntryStep,
+  SysFlowTaskOperationType,
+  SysFlowTaskType,
+  SysFlowVariableType,
+  SysFlowWorkOrderStatus
+}

+ 201 - 0
src/staticDict/index.js

@@ -0,0 +1,201 @@
+/**
+ * 常量字典数据
+ */
+import Vue from 'vue';
+
+class DictionaryBase extends Map {
+  constructor (name, dataList, keyId = 'id', symbolId = 'symbol') {
+    super();
+    this.showName = name;
+    this.setList(dataList, keyId, symbolId);
+  }
+
+  setList (dataList, keyId = 'id', symbolId = 'symbol') {
+    this.clear();
+    if (Array.isArray(dataList)) {
+      dataList.forEach((item) => {
+        this.set(item[keyId], item);
+        if (item[symbolId] != null) {
+          Object.defineProperty(this, item[symbolId], {
+            get: function () {
+              return item[keyId];
+            }
+          });
+        }
+      });
+    }
+  }
+
+  getList (valueId = 'name', parentIdKey = 'parentId', filter) {
+    let temp = [];
+    this.forEach((value, key) => {
+      let obj = {
+        id: key,
+        name: (typeof value === 'string') ? value : value[valueId],
+        parentId: value[parentIdKey]
+      };
+      if (typeof filter !== 'function' || filter(obj)) {
+        temp.push(obj);
+      }
+    });
+
+    return temp;
+  }
+
+  getValue (id, valueId = 'name') {
+    // 如果id为boolean类型,则自动转换为0和1
+    if (typeof id === 'boolean') {
+      id = id ? 1 : 0;
+    }
+    return (this.get(id) || {})[valueId];
+  }
+}
+
+const SysUserStatus = new DictionaryBase('用户状态', [
+  {
+    id: 0,
+    name: '正常状态',
+    symbol: 'NORMAL'
+  },
+  {
+    id: 1,
+    name: '锁定状态',
+    symbol: 'LOCKED'
+  }
+]);
+Vue.prototype.SysUserStatus = SysUserStatus;
+
+const SysUserType = new DictionaryBase('用户类型', [
+  {
+    id: 0,
+    name: '管理员',
+    symbol: 'ADMIN'
+  },
+  {
+    id: 1,
+    name: '系统操作员',
+    symbol: 'SYSTEM'
+  },
+  {
+    id: 2,
+    name: '普通操作员',
+    symbol: 'OPERATOR'
+  }
+]);
+Vue.prototype.SysUserType = SysUserType;
+
+const SysPermModuleType = new DictionaryBase('权限分组类型', [
+  {
+    id: 0,
+    name: '分组模块',
+    symbol: 'GROUP'
+  }, {
+    id: 1,
+    name: '接口模块',
+    symbol: 'CONTROLLER'
+  }
+]);
+Vue.prototype.SysPermModuleType = SysPermModuleType;
+
+const SysPermCodeType = new DictionaryBase('权限字类型', [{
+  id: 0,
+  name: '表单',
+  symbol: 'FORM'
+}, {
+  id: 1,
+  name: '片段',
+  symbol: 'FRAGMENT'
+}, {
+  id: 2,
+  name: '操作',
+  symbol: 'OPERATION'
+}]);
+Vue.prototype.SysPermCodeType = SysPermCodeType;
+
+const SysMenuType = new DictionaryBase('菜单类型', [
+  {
+    id: 0,
+    name: '目录',
+    symbol: 'DIRECTORY'
+  },
+  {
+    id: 1,
+    name: '表单',
+    symbol: 'MENU'
+  },
+  {
+    id: 2,
+    name: '片段',
+    symbol: 'FRAGMENT'
+  },
+  {
+    id: 3,
+    name: '按钮',
+    symbol: 'BUTTON'
+  }
+]);
+Vue.prototype.SysMenuType = SysMenuType;
+
+const SysMenuBindType = new DictionaryBase('菜单绑定类型', [
+  {
+    id: 0,
+    name: '路由菜单',
+    symbol: 'ROUTER'
+  },
+  {
+    id: 1,
+    name: '在线表单',
+    symbol: 'ONLINE_FORM'
+  },
+  {
+    id: 2,
+    name: '工单列表',
+    symbol: 'WORK_ORDER'
+  }
+]);
+Vue.prototype.SysMenuBindType = SysMenuBindType;
+
+const SysDataPermType = new DictionaryBase('数据权限类型', [
+  {
+    id: 0,
+    name: '查看全部',
+    symbol: 'ALL'
+  },
+  {
+    id: 1,
+    name: '仅看自己',
+    symbol: 'ONLY_USER'
+  },
+  {
+    id: 2,
+    name: '仅看所在部门',
+    symbol: 'ONLY_DEPT'
+  },
+  {
+    id: 3,
+    name: '仅看所在部门及子部门',
+    symbol: 'ONLY_DEPT_AND_CHILD'
+  },
+  {
+    id: 4,
+    name: '自选部门及子部门',
+    symbol: 'CUSTOM_DEPT_AND_CHILD'
+  },
+  {
+    id: 5,
+    name: '仅自选部门',
+    symbol: 'CUSTOM_DEPT'
+  }
+]);
+Vue.prototype.SysDataPermType = SysDataPermType;
+
+export {
+  DictionaryBase,
+  SysUserStatus,
+  SysUserType,
+  SysDataPermType,
+  SysPermModuleType,
+  SysPermCodeType,
+  SysMenuBindType,
+  SysMenuType
+}

+ 566 - 0
src/staticDict/onlineStaticDict.js

@@ -0,0 +1,566 @@
+/**
+ * 在线表单常量字典
+ */
+import Vue from 'vue';
+import { DictionaryBase } from './index.js';
+
+const SysOnlineFieldKind = new DictionaryBase('字段类型', [
+  {
+    id: 1,
+    name: '文件上传字段',
+    symbol: 'UPLOAD'
+  },
+  {
+    id: 2,
+    name: '图片上传字段',
+    symbol: 'UPLOAD_IMAGE'
+  },
+  {
+    id: 3,
+    name: '富文本字段',
+    symbol: 'RICH_TEXT'
+  },
+  {
+    id: 20,
+    name: '创建时间字段',
+    symbol: 'CREATE_TIME'
+  },
+  {
+    id: 21,
+    name: '创建人字段',
+    symbol: 'CREATE_USER_ID'
+  },
+  {
+    id: 22,
+    name: '更新时间字段',
+    symbol: 'UPDATE_TIME'
+  },
+  {
+    id: 23,
+    name: '更新人字段',
+    symbol: 'UPDATE_USER_ID'
+  },
+  /**
+   * 暂时屏蔽掉,等租户运营支持在线表单再开启
+  {
+    id: 30,
+    name: '租户过滤字段',
+    symbol: 'TENANT_FILTER'
+  },
+  */
+  {
+    id: 31,
+    name: '逻辑删除字段',
+    symbol: 'LOGIC_DELETE'
+  }
+]);
+Vue.prototype.SysOnlineFieldKind = SysOnlineFieldKind;
+
+const SysOnlineDataPermFilterType = new DictionaryBase('数据权限过滤类型', [
+  {
+    id: 1,
+    name: '用户过滤字段',
+    symbol: 'USER_FILTER'
+  },
+  {
+    id: 2,
+    name: '部门过滤字段',
+    symbol: 'DEPT_FILTER'
+  }
+]);
+Vue.prototype.SysOnlineDataPermFilterType = SysOnlineDataPermFilterType;
+
+const SysOnlineRelationType = new DictionaryBase('关联类型', [
+  {
+    id: 0,
+    name: '一对一关联',
+    symbol: 'ONE_TO_ONE'
+  },
+  {
+    id: 1,
+    name: '一对多关联',
+    symbol: 'ONE_TO_MANY'
+  }
+]);
+Vue.prototype.SysOnlineRelationType = SysOnlineRelationType;
+
+const SysOnlineFormType = new DictionaryBase('表单类型', [
+  {
+    id: 1,
+    name: '查询表单',
+    symbol: 'QUERY'
+  },
+  {
+    id: 5,
+    name: '编辑表单',
+    symbol: 'FORM'
+  },
+  {
+    id: 10,
+    name: '流程表单',
+    symbol: 'FLOW'
+  },
+  {
+    id: 11,
+    name: '工单列表',
+    symbol: 'WORK_ORDER'
+  }
+]);
+Vue.prototype.SysOnlineFormType = SysOnlineFormType;
+
+const SysOnlineFormKind = new DictionaryBase('表单类别', [
+  {
+    id: 1,
+    name: '弹出窗口',
+    symbol: 'DIALOG'
+  },
+  {
+    id: 5,
+    name: '跳转页面',
+    symbol: 'PAGE'
+  }
+]);
+Vue.prototype.SysOnlineFormKind = SysOnlineFormKind;
+
+const SysOnlinePageType = new DictionaryBase('页面类型', [
+  {
+    id: 1,
+    name: '业务页面',
+    symbol: 'BIZ'
+  },
+  {
+    id: 5,
+    name: '统计页面',
+    symbol: 'STATS'
+  },
+  {
+    id: 10,
+    name: '流程页面',
+    symbol: 'FLOW'
+  }
+]);
+Vue.prototype.SysOnlinePageType = SysOnlinePageType;
+
+const SysOnlinePageStatus = new DictionaryBase('页面状态', [
+  {
+    id: 0,
+    name: '基础信息录入',
+    symbol: 'BASIC'
+  },
+  {
+    id: 1,
+    name: '数模模型录入',
+    symbol: 'DATASOURCE'
+  },
+  {
+    id: 2,
+    name: '表单设计',
+    symbol: 'DESIGNING'
+  }
+]);
+Vue.prototype.SysOnlinePageStatus = SysOnlinePageStatus;
+
+const SysOnlineDictType = new DictionaryBase('字典类型', [
+  {
+    id: 1,
+    name: '数据表字典',
+    symbol: 'TABLE'
+  },
+  {
+    id: 5,
+    name: 'URL字典',
+    symbol: 'URL'
+  },
+  {
+    id: 10,
+    name: '静态字典',
+    symbol: 'STATIC'
+  },
+  {
+    id: 15,
+    name: '自定义字典',
+    symbol: 'CUSTOM'
+  }
+]);
+Vue.prototype.SysOnlineDictType = SysOnlineDictType;
+
+const SysOnlineRuleType = new DictionaryBase('验证规则类型', [
+  {
+    id: 1,
+    name: '只允许整数',
+    symbol: 'INTEGER_ONLY'
+  },
+  {
+    id: 2,
+    name: '只允许数字',
+    symbol: 'DIGITAL_ONLY'
+  },
+  {
+    id: 3,
+    name: '只允许英文字符',
+    symbol: 'LETTER_ONLY'
+  },
+  {
+    id: 4,
+    name: '范围验证',
+    symbol: 'RANGE'
+  },
+  {
+    id: 5,
+    name: '邮箱格式验证',
+    symbol: 'EMAIL'
+  },
+  {
+    id: 6,
+    name: '手机格式验证',
+    symbol: 'MOBILE'
+  },
+  {
+    id: 7,
+    name: '自定义验证',
+    symbol: 'CUSTOM'
+  }
+]);
+Vue.prototype.SysOnlineRuleType = SysOnlineRuleType;
+
+const SysCustomWidgetType = new DictionaryBase('组件类型', [
+  {
+    id: 0,
+    name: '文本显示',
+    symbol: 'Label'
+  },
+  {
+    id: 1,
+    name: '文本输入框',
+    symbol: 'Input'
+  },
+  {
+    id: 3,
+    name: '数字输入框',
+    symbol: 'NumberInput'
+  },
+  {
+    id: 4,
+    name: '数字范围输入框',
+    symbol: 'NumberRange'
+  },
+  {
+    id: 5,
+    name: '开关组件',
+    symbol: 'Switch'
+  },
+  {
+    id: 10,
+    name: '下拉选择框',
+    symbol: 'Select'
+  },
+  {
+    id: 12,
+    name: '级联选择框',
+    symbol: 'Cascader'
+  },
+  {
+    id: 20,
+    name: '日期选择框',
+    symbol: 'Date'
+  },
+  {
+    id: 21,
+    name: '日期范围选择框',
+    symbol: 'DateRange'
+  },
+  {
+    id: 31,
+    name: '上传组件',
+    symbol: 'Upload'
+  },
+  {
+    id: 32,
+    name: '富文本编辑',
+    symbol: 'RichEditor'
+  },
+  {
+    id: 40,
+    name: '分割线',
+    symbol: 'Divider'
+  },
+  {
+    id: 41,
+    name: '文本',
+    symbol: 'Text'
+  },
+  {
+    id: 42,
+    name: '图片',
+    symbol: 'Image'
+  },
+  {
+    id: 100,
+    name: '表格组件',
+    symbol: 'Table'
+  },
+  {
+    id: 300,
+    name: '基础块',
+    symbol: 'Block'
+  },
+  {
+    id: 301,
+    name: '卡片组件',
+    symbol: 'Card'
+  }
+]);
+Vue.prototype.SysCustomWidgetType = SysCustomWidgetType;
+
+const SysCustomWidgetKind = new DictionaryBase('组件类别', [
+  {
+    id: 0,
+    name: '过滤组件',
+    symbol: 'Filter'
+  },
+  {
+    id: 1,
+    name: '表单组件',
+    symbol: 'Form'
+  },
+  {
+    id: 2,
+    name: '数据组件',
+    symbol: 'Data'
+  },
+  {
+    id: 4,
+    name: '容器组件',
+    symbol: 'Container'
+  }
+]);
+Vue.prototype.SysCustomWidgetKind = SysCustomWidgetKind;
+
+const SysOnlineColumnFilterType = new DictionaryBase('组件类别', [
+  {
+    id: 0,
+    name: '无过滤',
+    symbol: 'NONE'
+  },
+  {
+    id: 1,
+    name: '普通过滤',
+    symbol: 'EQUAL_FILTER'
+  },
+  {
+    id: 2,
+    name: '范围过滤',
+    symbol: 'RANFGE_FILTER'
+  },
+  {
+    id: 3,
+    name: '模糊过滤',
+    symbol: 'LIKE_FILTER'
+  }
+]);
+Vue.prototype.SysOnlineColumnFilterType = SysOnlineColumnFilterType;
+
+const SysCustomWidgetOperationType = new DictionaryBase('操作类型', [
+  {
+    id: 0,
+    name: '新建',
+    symbol: 'ADD'
+  },
+  {
+    id: 1,
+    name: '编辑',
+    symbol: 'EDIT'
+  },
+  {
+    id: 2,
+    name: '删除',
+    symbol: 'DELETE'
+  },
+  {
+    id: 3,
+    name: '导出',
+    symbol: 'EXPORT'
+  },
+  {
+    id: 20,
+    name: '自定义操作',
+    symbol: 'CUSTOM'
+  }
+]);
+Vue.prototype.SysCustomWidgetOperationType = SysCustomWidgetOperationType;
+
+const SysOnlinePageDatasourceFieldStatus = new DictionaryBase('数据表状态', [
+  {
+    id: 0,
+    name: '已删除',
+    symbol: 'DELETED'
+  },
+  {
+    id: 1,
+    name: '已使用',
+    symbol: 'USED'
+  },
+  {
+    id: 0,
+    name: '未使用',
+    symbol: 'UNUSED'
+  }
+]);
+Vue.prototype.SysOnlinePageDatasourceFieldStatus = SysOnlinePageDatasourceFieldStatus;
+
+const SysOnlinePageSettingStep = new DictionaryBase('在线表单编辑步骤', [
+  {
+    id: 0,
+    name: '编辑基础信息',
+    symbol: 'BASIC'
+  },
+  {
+    id: 1,
+    name: '编辑数据模型',
+    symbol: 'DATASOURCE'
+  },
+  {
+    id: 2,
+    name: '设计表单',
+    symbol: 'FORM_DESIGN'
+  }
+]);
+Vue.prototype.SysOnlinePageSettingStep = SysOnlinePageSettingStep;
+
+const SysOnlineParamValueType = new DictionaryBase('参数值类型', [
+  {
+    id: 0,
+    name: '表单参数',
+    symbol: 'FORM_PARAM'
+  },
+  {
+    id: 1,
+    name: '数据字段',
+    symbol: 'TABLE_COLUMN'
+  },
+  {
+    id: 2,
+    name: '静态字典',
+    symbol: 'STATIC_DICT'
+  },
+  {
+    id: 3,
+    name: '直接输入',
+    symbol: 'INPUT_VALUE'
+  }
+]);
+Vue.prototype.SysOnlineParamValueType = SysOnlineParamValueType;
+
+const SysOnlineAggregationType = new DictionaryBase('字段聚合类型', [
+  {
+    id: 0,
+    name: '总数',
+    symbol: 'SUM'
+  },
+  {
+    id: 1,
+    name: '个数',
+    symbol: 'COUNT'
+  },
+  {
+    id: 2,
+    name: '平均数',
+    symbol: 'AVG'
+  },
+  {
+    id: 3,
+    name: '最小值',
+    symbol: 'MIN'
+  },
+  {
+    id: 4,
+    name: '最大值',
+    symbol: 'MAX'
+  }
+]);
+Vue.prototype.SysOnlineAggregationType = SysOnlineAggregationType;
+
+const SysOnlineFilterOperationType = new DictionaryBase('过滤条件操作类型', [
+  {
+    id: 0,
+    name: ' = ',
+    symbol: 'EQUAL'
+  },
+  {
+    id: 1,
+    name: ' != ',
+    symbol: 'NOT_EQUAL'
+  },
+  {
+    id: 2,
+    name: ' >= ',
+    symbol: 'GREATER_THAN_OR_EQUAL'
+  },
+  {
+    id: 3,
+    name: ' > ',
+    symbol: 'GREATER_THAN'
+  },
+  {
+    id: 4,
+    name: ' <= ',
+    symbol: 'LESS_THAN_OR_EQUAL'
+  },
+  {
+    id: 5,
+    name: ' < ',
+    symbol: 'LESS_THAN'
+  },
+  {
+    id: 6,
+    name: ' like ',
+    symbol: 'LIKE'
+  },
+  {
+    id: 7,
+    name: ' not null ',
+    symbol: 'NOT_NULL'
+  },
+  {
+    id: 8,
+    name: ' is null ',
+    symbol: 'IS_NULL'
+  }
+]);
+Vue.prototype.SysOnlineFilterOperationType = SysOnlineFilterOperationType;
+
+const SysOnlineVirtualColumnFilterValueType = new DictionaryBase('虚拟字段过滤值类型', [
+  {
+    id: 0,
+    name: '输入值',
+    symbol: 'CUSTOM_INPUT'
+  },
+  {
+    id: 1,
+    name: '静态字典',
+    symbol: 'STATIC_DICT'
+  }
+]);
+Vue.prototype.SysOnlineVirtualColumnFilterValueType = SysOnlineVirtualColumnFilterValueType;
+
+export {
+  SysOnlineFieldKind,
+  SysOnlineDataPermFilterType,
+  SysOnlineRelationType,
+  SysOnlineFormType,
+  SysOnlineFormKind,
+  SysOnlinePageType,
+  SysOnlinePageStatus,
+  SysOnlineDictType,
+  SysOnlineRuleType,
+  SysCustomWidgetType,
+  SysCustomWidgetKind,
+  SysOnlineColumnFilterType,
+  SysCustomWidgetOperationType,
+  SysOnlinePageSettingStep,
+  SysOnlinePageDatasourceFieldStatus,
+  SysOnlineParamValueType,
+  SysOnlineAggregationType,
+  SysOnlineFilterOperationType,
+  SysOnlineVirtualColumnFilterValueType
+}

+ 5 - 30
src/store/getters.js

@@ -1,32 +1,7 @@
 const getters = {
-  init: state => state.app.init,
-  isCollapse: state => state.app.isCollapse,
-  map: state => state.app.map,
-  platforms: state => state.app.platforms,
-  properties: state => state.app.properties,
-  platformShow: state => state.app.platformShow,
-  platformID: state => state.app.platformID,
-  leadPost: state => state.app.leadPost,
-  airLine: state => state.app.airLine,
-  taskPlan: state => state.app.taskPlan,
-  // 通信管理
-  linkVU: state => state.app.linkVU,
-  linkJ: state => state.app.linkJ,
-  linkZY: state => state.app.linkZY,
-  memberVU: state => state.app.memberVU,
-  memberJ: state => state.app.memberJ,
-  memberZY: state => state.app.memberZY,
-  // 健康管理
-  systemFunctionality: state => state.app.systemFunctionality,
-  threads: state => state.app.threads,
-  sensors: state => state.app.sensors,
-  deviceVU: state => state.app.deviceVU,
-  deviceJ: state => state.app.deviceJ,
-  deviceZY: state => state.app.deviceZY,
-  // 雷侦 & 通侦
-  esmInstances: state => state.app.esmInstances,
-  esmParams: state => state.app.esmParams,
-  esmStatus: state => state.app.esmStatus,
-  esmData: state => state.app.esmData
+    //app
+    isCollapse: state => state.app.isCollapse,
+    //userInfo
+    userInfo: state => state.user.userInfo
 }
-export default getters
+export default getters

+ 7 - 5
src/store/index.js

@@ -2,15 +2,17 @@ import Vue from 'vue'
 import Vuex from 'vuex'
 import getters from './getters'
 import app from './modules/app'
+import user from './modules/user'
 
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
 
-  modules: {
-    app
-  },
-  getters
+    modules: {
+        app,
+        user
+    },
+    getters
 })
 
-export default store
+export default store

+ 5 - 110
src/store/modules/app.js

@@ -1,39 +1,8 @@
 const getDefaultState = () => {
     return {
-        init: 0,
-        map: null,
+
         isCollapse: false,
-        platforms: null,
-        platformShow: false,
-        platformID: 8015,
-        leadPost: null,
-        airLine: {
-            TargetArea: 1,
-            radius: 300000
-        },
-        taskPlan: null,
-        // 通信管理
-        linkVU: null,
-        linkJ: null,
-        linkZY: null,
-        memberVU: null,
-        memberJ: null,
-        memberZY: null,
-        // 健康管理
-        systemFunctionality: null,
-        threads: null,
-        sensors: null,
-        deviceVU: null,
-        deviceJ: null,
-        deviceZY: null,
-        // 雷侦 & 通侦
-        esmInstances: null,
-        esmParams: {
-            InitParams: null,
-            CtrlParams: null
-        },
-        esmStatus: null,
-        esmData: null
+
     }
 }
 
@@ -41,84 +10,10 @@ const state = getDefaultState()
 
 const mutations = {
 
-    setInit(state, init) {
-        state.init = init
-    },
-    setMap(state, map) {
-        state.map = map
-    },
-    setPlatforms(state, platforms) {
-        state.platforms = platforms
-    },
-    setPlatformShow(state, platformShow) {
-        state.platformShow = platformShow
-    },
-    setPlatformID(state, platformID) {
-        state.platformID = platformID
-    },
-    setLeadPost(state, leadPost) {
-        state.leadPost = leadPost
-    },
-    setAirLine(state, airLine) {
-        state.airLine = airLine
-    },
-    setTaskPlan(state, taskPlan) {
-        state.taskPlan = taskPlan
-    },
-    // 通信管理
-    setLinkVU(state, linkVU) {
-        state.linkVU = linkVU
-    },
-    setLinkJ(state, linkJ) {
-        state.linkJ = linkJ
-    },
-    setLinkZY(state, linkZY) {
-        state.linkZY = linkZY
-    },
-    setMemberVU(state, memberVU) {
-        state.memberVU = memberVU
-    },
-    setMemberJ(state, memberJ) {
-        state.memberJ = memberJ
-    },
-    setMemberZY(state, memberZY) {
-        state.memberZY = memberZY
-    },
-    // 健康管理
-    setSystemFunctionality(state, systemFunctionality) {
-        state.systemFunctionality = systemFunctionality
-    },
-    setThreads(state, threads) {
-        state.threads = threads
-    },
-    setSensors(state, sensors) {
-        state.sensors = sensors
-    },
-    setDeviceVU(state, deviceVU) {
-        state.deviceVU = deviceVU
-    },
-    setDeviceJ(state, deviceJ) {
-        state.deviceJ = deviceJ
-    },
-    setDeviceZY(state, deviceZY) {
-        state.deviceZY = deviceZY
-    },
+
     setIsCollapse(state, isCollapse) {
         state.isCollapse = isCollapse
-    },
-    // 雷侦 & 通侦 
-    setESMInstances(state, esmInstances) {
-        state.esmInstances = esmInstances
-    },
-    setESMParams(state, esmParams) {
-        state.esmParams = esmParams
-    },
-    setESMStatus(state, esmStatus) {
-        state.esmStatus = esmStatus
-    },
-    setESMData(state, esmData) {
-        state.esmData = esmData
-    },
+    }
 }
 
 const actions = {
@@ -132,4 +27,4 @@ export default {
     state,
     mutations,
     actions
-}
+}

+ 33 - 0
src/store/modules/user.js

@@ -0,0 +1,33 @@
+import { initUserInfo } from './utils';
+import { setObjectToSessionStorage } from '@/utils';
+const getDefaultState = () => {
+    return {
+
+        // 用户登录信息
+        userInfo: initUserInfo(),
+
+    }
+}
+
+const state = getDefaultState()
+
+const mutations = {
+    setUserInfo: (state, info) => {
+        setObjectToSessionStorage('userInfo', info);
+        state.userInfo = initUserInfo(info);
+    },
+
+}
+
+const actions = {
+
+
+
+}
+
+export default {
+    namespaced: true,
+    state,
+    mutations,
+    actions
+}

+ 36 - 0
src/store/modules/utils/index.js

@@ -0,0 +1,36 @@
+import { getObjectFromSessionStorage } from '@/utils';
+
+function findMenuItem (menuItem, menuId, path) {
+  if (Array.isArray(path)) path.push(menuItem);
+  if ((menuItem.menuId + '') === (menuId + '')) return menuItem;
+
+  let bFind = false;
+  let findItem = null;
+  if (Array.isArray(menuItem.children)) {
+    for (let i = 0; i < menuItem.children.length; i++) {
+      findItem = findMenuItem(menuItem.children[i], menuId, path);
+      if (findItem != null) {
+        bFind = true;
+        break;
+      }
+    }
+  }
+
+  if (!bFind && Array.isArray(path)) path.pop();
+  return bFind ? findItem : null;
+}
+
+function initUserInfo (userInfo) {
+  if (userInfo == null) userInfo = getObjectFromSessionStorage('userInfo');
+
+  if (userInfo != null && userInfo.permCodeList != null && Array.isArray(userInfo.permCodeList)) {
+    userInfo.permCodeSet = new Set(userInfo.permCodeList);
+  }
+
+  return userInfo;
+}
+
+export {
+  findMenuItem,
+  initUserInfo
+}

+ 56 - 0
src/utils/chartOption.js

@@ -0,0 +1,56 @@
+const defaultLineChartOption = {
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '20px',
+    containLabel: true
+  },
+  xAxis: {
+    axisLabel: {
+      interval: 0,
+      showMaxLabel: true
+    }
+  },
+  legend: {
+    top: '3%'
+  }
+}
+
+const defaultBarChartOption = {
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '20px',
+    containLabel: true
+  },
+  xAxis: {
+    axisLabel: {
+      interval: 0,
+      showMaxLabel: true
+    }
+  },
+  legend: {
+    top: '3%'
+  }
+}
+
+const defaultPieChartOption = {
+  grid: {
+    left: '3%',
+    right: '4%',
+    bottom: '20px',
+    containLabel: true
+  },
+  legend: {
+    top: '3%'
+  },
+  series: {
+    center: ['50%', '60%']
+  }
+}
+
+export {
+  defaultLineChartOption,
+  defaultBarChartOption,
+  defaultPieChartOption
+}

+ 442 - 0
src/utils/index.js

@@ -0,0 +1,442 @@
+import JSEncrypt from 'jsencrypt';
+// eslint-disable-next-line no-unused-vars
+// import Cookies from 'js-cookie';
+
+/**
+ * 列表数据转换树形数据
+ * @param {Array} data 要转换的列表
+ * @param {String} id 主键字段字段名
+ * @param {String} pid 父字段字段名
+ * @returns {Array} 转换后的树数据
+ */
+export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
+  var res = []
+  var temp = {}
+  for (var i = 0; i < data.length; i++) {
+    temp[data[i][id]] = data[i]
+  }
+  for (var k = 0; k < data.length; k++) {
+    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
+      if (!temp[data[k][pid]]['children']) {
+        temp[data[k][pid]]['children'] = []
+      }
+      if (!temp[data[k][pid]]['_level']) {
+        temp[data[k][pid]]['_level'] = 1
+      }
+      data[k]['_level'] = temp[data[k][pid]]._level + 1
+      data[k]['_parent'] = data[k][pid]
+      temp[data[k][pid]]['children'].push(data[k])
+    } else {
+      res.push(data[k])
+    }
+  }
+
+  return res
+}
+/**
+ * 获取字符串字节长度(中文算2个字符)
+ * @param {String} str 要获取长度的字符串
+ */
+export function getStringLength (str) {
+  return str.replace(/[\u4e00-\u9fa5\uff00-\uffff]/g, '**').length
+}
+/**
+ * 获取uuid
+ */
+export function getUUID () {
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+    return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
+  });
+}
+/**
+ * 大小驼峰变换函数
+ * @param name 要转换的字符串
+ * @param type 转换的类型0:转换成小驼峰,1:转换成大驼峰
+ */
+export function nameTranslate (name, type) {
+  name = name.toLowerCase();
+  let nameArray = name.split('_');
+  nameArray.forEach((item, index) => {
+    if (index === 0) {
+      name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
+    } else {
+      name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
+    }
+  });
+
+  nameArray = name.split('-');
+  nameArray.forEach((item, index) => {
+    if (index === 0) {
+      name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
+    } else {
+      name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
+    }
+  });
+  return name;
+}
+/**
+ * 通过id从树中获取指定的节点
+ * @param {Object} node 根节点
+ * @param {String|Nubmer} id 键值
+ * @param {Array} list 保存查询路径
+ * @param {String} idKey 主键字段名
+ * @param {String} childKey 子节点字段名
+ */
+function findNode (node, id, list, idKey = 'id', childKey = 'children') {
+  if (Array.isArray(list)) list.push(node[idKey]);
+  if (node[idKey] === id) {
+    return node;
+  }
+
+  if (node[childKey] != null && Array.isArray(node[childKey])) {
+    for (let i = 0; i < node[childKey].length; i++) {
+      let tempNode = findNode(node[childKey][i], id, list, idKey, childKey);
+      if (tempNode) return tempNode;
+    }
+  }
+
+  if (Array.isArray(list)) list.pop();
+}
+/**
+ * 通过id返回从根节点到指定节点的路径
+ * @param {Array} treeRoot 树根节点数组
+ * @param {*} id 要查询的节点的id
+ * @param {*} idKey 主键字段名
+ * @param {*} childKey 子节点字段名
+ */
+export function findTreeNodePath (treeRoot, id, idKey = 'id', childKey = 'children') {
+  let tempList = [];
+  for (let i = 0; i < treeRoot.length; i++) {
+    if (findNode(treeRoot[i], id, tempList, idKey, childKey)) {
+      return tempList;
+    }
+  }
+
+  return [];
+}
+/**
+ * 通过id从树中查找节点
+ * @param {Array} treeRoot 根节点数组
+ * @param {*} id 要查找的节点的id
+ * @param {*} idKey 主键字段名
+ * @param {*} childKey 子节点字段名
+ */
+export function findTreeNode (treeRoot, id, idKey = 'id', childKey = 'children') {
+  for (let i = 0; i < treeRoot.length; i++) {
+    let tempNode = findNode(treeRoot[i], id, undefined, idKey, childKey);
+    if (tempNode) return tempNode;
+  }
+}
+/**
+ * 把Object转换成query字符串
+ * @param {Object} params 要转换的Object
+ */
+export function objectToQueryString (params) {
+  if (params == null) {
+    return null;
+  } else {
+    return Object.keys(params).map((key) => {
+      if (params[key] !== undefined) {
+        return `${key}=${params[key]}`;
+      } else {
+        return undefined;
+      }
+    }).filter(item => item != null).join('&');
+  }
+}
+/**
+ * 从数组中查找某一项
+ * @param {Array} list 要查找的数组
+ * @param {String} id 要查找的节点id
+ * @param {String} idKey 主键字段名(如果为null则直接比较)
+ * @param {Boolean} removeItem 是否从数组中移除查找到的节点
+ * @returns {Object} 找到返回节点,没找到返回undefined
+ */
+export function findItemFromList (list, id, idKey, removeItem = false) {
+  if (Array.isArray(list) && list.length > 0 && id != null) {
+    for (let i = 0; i < list.length; i++) {
+      let item = list[i];
+      if (((idKey == null || idKey === '') && item === id) || (idKey != null && item[idKey] === id)) {
+        if (removeItem) list.splice(i, 1);
+        return item;
+      }
+    }
+  }
+  return null;
+}
+/**
+ * 将数据保存到sessionStorage
+ * @param {*} key sessionStorage的键值
+ * @param {*} value 要保存的数据
+ */
+export function setObjectToSessionStorage (key, value) {
+  if (key == null || key === '') return false;
+  if (value == null) {
+    window.sessionStorage.removeItem(key);
+    return true;
+  } else {
+    let jsonObj = {
+      data: value
+    }
+    window.sessionStorage.setItem(key, JSON.stringify(jsonObj));
+    return true;
+  }
+}
+/**
+ * 从sessionStorage里面获取数据
+ * @param {String} key 键值
+ * @param {*} defaultValue 默认值
+ */
+export function getObjectFromSessionStorage (key, defaultValue) {
+  let jsonObj = null;
+  try {
+    jsonObj = JSON.parse(window.sessionStorage.getItem(key));
+    jsonObj = (jsonObj || {}).data;
+  } catch (e) {
+    jsonObj = defaultValue;
+  };
+  return (jsonObj != null) ? jsonObj : defaultValue;
+}
+/**
+ * 判读字符串是否一个数字
+ * @param {String} str 要判断的字符串
+ */
+export function isNumber (str) {
+  let num = Number.parseFloat(str);
+  if (Number.isNaN(num)) return false;
+  return num.toString() === str;
+}
+/**
+ * 生成随机数
+ * @param {Integer} min 随机数最小值
+ * @param {Integer} max 随机数最大值
+ */
+export function random (min, max) {
+  let base = Math.random();
+  return min + base * (max - min);
+}
+/**
+ * 加密
+ * @param {*} value 要加密的字符串
+ */
+const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpC4QMnbTrQOFriJJCCFFWhlruBJThAEBfRk7pRx1jsAhyNVL3CqJb0tRvpnbCnJhrRAEPdgFHXv5A0RrvFp+5Cw7QoFH6O9rKB8+0H7+aVQeKITMUHf/XMXioymw6Iq4QfWd8RhdtM1KM6eGTy8aU7SO2s69Mc1LXefg/x3yw6wIDAQAB';
+export function encrypt (value) {
+  if (value == null || value === '') return null;
+  let encrypt = new JSEncrypt();
+  encrypt.setPublicKey(publicKey);
+  return encodeURIComponent(encrypt.encrypt(value));
+}
+
+export function getToken () {
+  return sessionStorage.getItem('token');
+  // return Cookies.get('token');
+}
+
+export function setToken (token) {
+  if (token == null || token === '') {
+    sessionStorage.removeItem('token');
+    // Cookies.remove('token');
+  } else {
+    sessionStorage.setItem('token', token);
+    // Cookies.set('token', token);
+  }
+}
+
+export function traversalTree (treeNode, callback, childrenKey = 'children') {
+  if (treeNode != null && Array.isArray(treeNode[childrenKey]) && treeNode[childrenKey].length > 0) {
+    treeNode[childrenKey].forEach(childNode => {
+      traversalTree(childNode, callback, childrenKey);
+    });
+  }
+  return typeof callback === 'function' ? callback(treeNode) : undefined;
+}
+
+export class TreeTableImpl {
+  constructor (dataList, options) {
+    this.options = {
+      idKey: options ? options.idKey : 'id',
+      nameKey: options ? options.nameKey : 'name',
+      parentIdKey: options ? options.parentIdKey : 'parentId',
+      isLefeCallback: options ? options.isLefeCallback : undefined,
+      checkStrictly: options ? options.checkStrictly : false
+    }
+
+    this.dataList = Array.isArray(dataList) ? dataList : [];
+    this.dataMap = new Map();
+    this.dataList.forEach(item => {
+      this.dataMap.set(item[this.options.idKey], item);
+    });
+    // 表格选中行
+    this.checkedRows = undefined;
+    this.onCheckedRowChange = this.onCheckedRowChange.bind(this);
+  }
+
+  /**
+   * 过滤表格数据
+   * @param {string} filterString 过滤条件字符串
+   * @param {boolean} onlyChecked 是否只显示选中节点
+   * @returns {array} 过滤后的表格数据列表
+   */
+  getFilterTableData (filterString, onlyChecked = false) {
+    let { idKey, nameKey, parentIdKey, isLefeCallback } = this.options;
+    let tempMap = new Map();
+    let parentIdList = [];
+    this.dataList.forEach(item => {
+      if ((filterString == null || filterString === '' || item[nameKey].indexOf(filterString) !== -1) &&
+        (!onlyChecked || (this.checkedRows != null && this.checkedRows.get(item[idKey])))) {
+        if (isLefeCallback == null || !isLefeCallback(item)) {
+          parentIdList.push(item[idKey]);
+        }
+        // 将命中节点以及它的父节点都设置为命中
+        let tempItem = item;
+        do {
+          tempMap.set(tempItem[idKey], tempItem);
+          tempItem = this.dataMap.get(tempItem[parentIdKey]);
+        } while (tempItem != null)
+      }
+    });
+
+    return this.dataList.map(item => {
+      let disabled = true;
+      
+      if (parentIdList.indexOf(item[parentIdKey]) !== -1 || tempMap.get(item[idKey]) != null) {
+        if (parentIdList.indexOf(item[parentIdKey]) !== -1 && (isLefeCallback == null || !isLefeCallback(item))) {
+          parentIdList.push(item[idKey]);
+        }
+        disabled = false;
+      }
+
+      return {
+        ...item,
+        __disabled: disabled
+      }
+    });
+  }
+
+  /**
+   * 获取表格树数据,计算选中状态
+   * @param {array} dataList 表格列表数据
+   */
+  getTableTreeData (dataList, checkedRows) {
+    let { idKey, parentIdKey, checkStrictly } = this.options;
+    let treeData = [];
+    function calcPermCodeTreeAttribute (treeNode, checkedRows) {
+      let checkedItem = checkedRows == null ? null : checkedRows.get(treeNode[idKey]);
+      treeNode.__checked = checkedItem != null;
+      // 是否所有子权限字都被选中
+      let allChildChecked = true;
+      // 是否任意子权限字被选中
+      let hasChildChecked = false;
+      // 如果存在子权限字
+      if (Array.isArray(treeNode.children) && treeNode.children.length > 0) {
+        treeNode.children.forEach(item => {
+          let isChecked = calcPermCodeTreeAttribute(item, checkedRows);
+          hasChildChecked = hasChildChecked || isChecked;
+          allChildChecked = allChildChecked && isChecked;
+        });
+      } else {
+        allChildChecked = false;
+      }
+      treeNode.__indeterminate = !checkStrictly && hasChildChecked && !allChildChecked;
+      treeNode.__checked = treeNode.__checked || (allChildChecked && !checkStrictly);
+      return treeNode.__checked || treeNode.__indeterminate;
+    }
+
+    if (Array.isArray(dataList)) {
+      treeData = treeDataTranslate(dataList.map(item => {
+        return {...item};
+      }), idKey, parentIdKey);
+      treeData.forEach(item => {
+        calcPermCodeTreeAttribute(item, checkedRows);
+      });
+    }
+    
+    return treeData;
+  }
+
+  /**
+   * 树表格行选中状态改变
+   * @param {object} row 选中状态改变行数据
+   */
+  onCheckedRowChange (row) {
+    if (this.checkedRows == null) {
+      this.checkedRows = new Map();
+    } else {
+      let temp = new Map();
+      this.checkedRows.forEach((item, key) => {
+        temp.set(key, item);
+      });
+      this.checkedRows = temp;
+    }
+    let { idKey } = this.options;
+    if (!row.__checked || row.__indeterminate) {
+      // 节点之前未被选中或者之前为半选状态,修改当前节点以及子节点为选中状态
+      this.checkedRows.set(row[idKey], row);
+      if (Array.isArray(row.children) && !this.options.checkStrictly) {
+        row.children.forEach(childNode => {
+          traversalTree(childNode, (node) => {
+            this.checkedRows.set(node[idKey], node);
+          });
+        });
+      }
+    } else {
+      // 节点之前为选中状态,修改节点以及子节点为未选中状态
+      this.checkedRows.delete(row[idKey]);
+      if (Array.isArray(row.children) && !this.options.checkStrictly) {
+        row.children.forEach(childNode => {
+          traversalTree(childNode, (node) => {
+            this.checkedRows.delete(node[idKey]);
+          });
+        });
+      }
+    }
+  }
+
+  /**
+   * 获取所有选中的权限字节点
+   * @param {array} treeData 树数据
+   * @param {boolean} includeHalfChecked 是否包含半选节点,默认为false
+   * @returns {array} 选中节点列表
+   */
+  getCheckedRows (treeData, includeHalfChecked = false) {
+    let checkedRows = [];
+
+    function traversalCallback (node) {
+      if (node == null) return;
+      if (node.__checked || (includeHalfChecked && node.__indeterminate)) {
+        checkedRows.push(node);
+      }
+    }
+
+    if (Array.isArray(treeData) && treeData.length > 0) {
+      treeData.forEach(permCode => {
+        traversalTree(permCode, traversalCallback, 'children');
+      });
+    }
+
+    return checkedRows;
+  }
+
+  /**
+   * 设置选中节点
+   * @param {array} checkedRows
+   */
+  setCheckedRows (checkedRows) {
+    this.checkedRows = new Map();
+    if (Array.isArray(checkedRows)) {
+      checkedRows.forEach(item => {
+        let node = this.dataMap.get(item[this.options.idKey]);
+        if (node != null) {
+          this.checkedRows.set(node[this.options.idKey], node);
+        }
+      });
+    }
+  }
+  /**
+   * 根据id获取表格行
+   * @param {*} id
+   */
+  getTableRow (id) {
+    return this.dataMap.get(id);
+  }
+}

+ 33 - 0
src/utils/validate.js

@@ -0,0 +1,33 @@
+const pattern = {
+  mobie: /^((\+?86)|(\(\+86\)))?(13[012356789][0-9]{8}|15[012356789][0-9]{8}|18[02356789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/,
+  english: /^[a-zA-Z]+$/,
+  englishAndNumber: /^[a-zA-Z0-9]+$/
+}
+
+/**
+ * 邮箱
+ * @param str
+ */
+export function isEmail (str) {
+  return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(str)
+}
+
+/**
+ * 手机号码
+ * @param str
+ */
+export function isMobile (str) {
+  return pattern.mobie.test(str)
+}
+
+/**
+ * 电话号码
+ * @param str
+ */
+export function isPhone (str) {
+  return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(str)
+}
+
+export default {
+  pattern
+}

+ 322 - 0
src/utils/widget.js

@@ -0,0 +1,322 @@
+import { Message } from 'element-ui';
+import { treeDataTranslate } from '@/utils';
+
+const DEFAULT_PAGE_SIZE = 10;
+
+export class DropdownWidget {
+  /**
+   * 下拉组件(Select、Cascade、TreeSelect、Tree等)
+   * @param {function () : Promise} loadDropdownData 下拉数据获取函数
+   * @param {Boolean} isTree 是否是树数据
+   * @param {String} idKey 键字段字段名
+   * @param {String} parentIdKey 父字段字段名
+   */
+  constructor (loadDropdownData, isTree = false, idKey = 'id', parentIdKey = 'parentId') {
+    this.loading = false;
+    this.dirty = true;
+    this.dropdownList = [];
+    this.isTree = isTree;
+    this.idKey = idKey;
+    this.parentIdKey = parentIdKey;
+    this.loadDropdownData = loadDropdownData;
+    this.setDropdownList = this.setDropdownList.bind(this);
+    this.onVisibleChange = this.onVisibleChange.bind(this);
+  }
+  /**
+   * 重新获取下拉数据
+   */
+  reloadDropdownData () {
+    return new Promise((resolve, reject) => {
+      if (!this.loading) {
+        if (typeof this.loadDropdownData === 'function') {
+          this.loading = true;
+          this.loadDropdownData().then(dataList => {
+            this.setDropdownList(dataList);
+            this.loading = false;
+            this.dirty = false;
+            resolve(this.dropdownList);
+          }).catch(e => {
+            this.setDropdownList([]);
+            this.loading = false;
+            reject(this.dropdownList);
+          });
+        } else {
+          reject(new Error('获取下拉数据失败'));
+        }
+      } else {
+        resolve(this.dropdownList);
+      }
+    });
+  }
+  /**
+   * 下拉框显示或隐藏时调用
+   * @param {Boolean} isShow 正在显示或者隐藏
+   */
+  onVisibleChange (isShow) {
+    return new Promise((resolve, reject) => {
+      if (isShow && this.dirty && !this.loading) {
+        this.reloadDropdownData().then(res => {
+          resolve(res);
+        }).catch(e => {
+          reject(e);
+        });
+      } else {
+        resolve(this.dropdownList);
+      }
+    });
+  }
+  /**
+   * 设置下拉数据
+   * @param {Array} dataList 要显示的下拉数据
+   */
+  setDropdownList (dataList) {
+    if (Array.isArray(dataList)) {
+      this.dropdownList = this.isTree ? treeDataTranslate(dataList, this.idKey, this.parentIdKey) : dataList;
+    }
+  }
+}
+
+export class TableWidget {
+  /**
+   * 表格组件
+   * @param {function (params: Object) : Promise} loadTableData 表数据获取函数
+   * @param {function () : Boolean} verifyTableParameter 表数据获取检验函数
+   * @param {Boolean} paged 是否支持分页
+   * @param {Boolean} rowSelection 是否支持行选择
+   * @param {String} orderFieldName 默认排序字段
+   * @param {Boolean} ascending 默认排序方式(true为正序,false为倒序)
+   * @param {String} dateAggregateBy 默认排序字段的日期统计类型
+   */
+  constructor (loadTableData, verifyTableParameter, paged, rowSelection, orderFieldName, ascending, dateAggregateBy) {
+    this.currentRow = null;
+    this.loading = false;
+    this.oldPage = 0;
+    this.currentPage = 1;
+    this.oldPageSize = DEFAULT_PAGE_SIZE;
+    this.pageSize = DEFAULT_PAGE_SIZE;
+    this.totalCount = 0;
+    this.dataList = [];
+    this.orderInfo = {
+      fieldName: orderFieldName,
+      asc: ascending,
+      dateAggregateBy: dateAggregateBy
+    };
+    this.paged = paged;
+    this.rowSelection = rowSelection;
+    this.searchVerify = verifyTableParameter || function () { return true; };
+    this.loadTableData = loadTableData || function () { return Promise.resolve(); };
+    this.onCurrentPageChange = this.onCurrentPageChange.bind(this);
+    this.onPageSizeChange = this.onPageSizeChange.bind(this);
+    this.onSortChange = this.onSortChange.bind(this);
+    this.getTableIndex = this.getTableIndex.bind(this);
+    this.currentRowChange = this.currentRowChange.bind(this);
+  }
+  /**
+   * 表格分页变化
+   * @param {Integer} newCurrentPage 变化后的显示页面
+   */
+  onCurrentPageChange (newCurrentPage) {
+    this.loadTableDataImpl(newCurrentPage, this.pageSize).then(() => {
+      this.oldPage = this.currentPage = newCurrentPage;
+    }).catch(() => {
+      this.currentPage = this.oldPage;
+    });
+  }
+  /**
+   * 表格分页每页显示数量变化
+   * @param {Integer} newPageSize 变化后的每页显示数量
+   */
+  onPageSizeChange (newPageSize) {
+    this.pageSize = newPageSize;
+    this.currentPage = 1
+    this.loadTableDataImpl(1, newPageSize).then(() => {
+      this.oldPage = this.currentPage;
+      this.oldPageSize = this.pageSize;
+    }).catch(e => {
+      this.currentPage = this.oldPage;
+      this.pageSize = this.oldPageSize;
+    });
+  }
+  /**
+   * 表格排序字段变化
+   * @param {String} prop 排序字段的字段名
+   * @param {String} order 正序还是倒序
+   */
+  onSortChange ({ prop, order }) {
+    this.orderInfo.fieldName = prop;
+    this.orderInfo.asc = (order === 'ascending');
+    this.refreshTable();
+  }
+  /**
+   * 获取每一行的index信息
+   * @param {Integer} index 表格在本页位置
+   */
+  getTableIndex (index) {
+    return this.paged ? ((this.currentPage - 1) * this.pageSize + (index + 1)) : (index + 1);
+  }
+  /**
+   * 当前选中行改变
+   * @param {Object} currentRow 当前选中行
+   * @param {Object} oldRow 老的选中行
+   */
+  currentRowChange (currentRow, oldRow) {
+    this.currentRow = currentRow;
+  }
+  clearTable () {
+    this.currentRow = null;
+    this.oldPage = 0;
+    this.currentPage = 1;
+    this.totalCount = 0;
+    this.dataList = [];
+  }
+  /**
+   * 获取表格数据
+   * @param {Integer} pageNum 当前分页
+   * @param {Integer} pageSize 每页数量
+   * @param {Boolean} reload 是否重新获取数据
+   */
+  loadTableDataImpl (pageNum, pageSize, reload = false) {
+    return new Promise((resolve, reject) => {
+      if (typeof this.loadTableData !== 'function') {
+        reject();
+      } else {
+        // 如果pageSize和pageNum没有变化,并且不强制刷新
+        if (this.paged && !reload && this.oldPage === pageNum && this.oldPageSize === pageSize) {
+          resolve();
+        } else {
+          let params = {};
+          if (this.orderInfo.fieldName != null) params.orderParam = [this.orderInfo];
+          if (this.paged) {
+            params.pageParam = {
+              pageNum,
+              pageSize
+            }
+          }
+          this.loading = true;
+          this.loadTableData(params).then(tableData => {
+            this.dataList = tableData.dataList;
+            this.totalCount = tableData.totalCount;
+            this.loading = false;
+            resolve();
+          }).catch(e => {
+            this.loading = false;
+            reject(e);
+          });
+        }
+      }
+    });
+  }
+  /**
+   * 刷新表格数据
+   * @param {Boolean} research 是否按照新的查询条件重新查询(调用verify函数)
+   * @param {Integer} pageNum 当前页面
+   */
+  refreshTable (research = false, pageNum = undefined, showMsg = false) {
+    let reload = false;
+    if (research) {
+      if (typeof this.searchVerify === 'function' && !this.searchVerify()) return;
+      reload = true;
+    }
+
+    if (Number.isInteger(pageNum) && pageNum !== this.currentPage) {
+      this.loadTableDataImpl(pageNum, this.pageSize, reload).then(res => {
+        this.oldPage = this.currentPage = pageNum;
+        if (research && showMsg) Message.success('查询成功');
+      }).catch(e => {
+        this.currentPage = this.oldPage;
+      });
+    } else {
+      this.loadTableDataImpl(this.currentPage, this.pageSize, true).catch(e => {});
+    }
+  }
+}
+
+export class UploadWidget {
+  /**
+   * 上传组件
+   * @param {Integer} maxCount 最大上传数量
+   */
+  constructor (maxCount = 1) {
+    this.maxCount = maxCount;
+    this.fileList = [];
+    this.onFileChange = this.onFileChange.bind(this);
+  }
+  /**
+   * 上传文件列表改变
+   * @param {Object} file 改变的文件
+   * @param {Array} fileList 改变后的文件列表
+   */
+  onFileChange (file, fileList) {
+    if (Array.isArray(fileList) && fileList.length > 0) {
+      if (this.maxCount === 1) {
+        this.fileList = [fileList[fileList.length - 1]];
+      } else {
+        this.fileList = fileList;
+      }
+    } else {
+      this.fileList = undefined;
+    }
+    return this.fileList;
+  }
+}
+
+export class ChartWidget {
+  /**
+   * 图表组件
+   * @param {function (params) : Promise} loadTableData chart数据获取函数
+   * @param {function () : Boolean} verifyTableParameter 数据参数检验函数
+   * @param {Array} columns 数据列
+   */
+  constructor (loadTableData, verifyTableParameter, columns) {
+    this.columns = columns;
+    this.loading = false;
+    this.dataEmpty = false;
+    this.chartData = undefined;
+    this.chartObject = undefined;
+    this.dimensionMaps = new Map();
+    this.chartSetting = undefined;
+    this.searchVerify = verifyTableParameter || function () { return true; };
+    this.loadTableData = loadTableData || function () { return Promise.resolve(); };
+  }
+  /**
+   * 获取图表数据
+   * @param {Boolean} reload 是否重新获取数据
+   */
+  loadChartDataImpl (reload = false) {
+    return new Promise((resolve, reject) => {
+      if (typeof this.loadTableData !== 'function') {
+        reject();
+      } else {
+        if (!reload) {
+          resolve();
+        } else {
+          this.loading = true;
+          this.loadTableData().then(tableData => {
+            this.chartData = {
+              columns: this.columns,
+              rows: tableData.dataList
+            }
+            this.loading = false;
+            if (this.chartObject) this.chartObject.resize();
+            resolve();
+          }).catch(e => {
+            console.error(e);
+            this.loading = false;
+            reject(e);
+          });
+        }
+      }
+    });
+  }
+  /**
+   * 刷新图表数据
+   * @param {Boolean} research 是否按照新的查询条件重新查询(调用verify函数)
+   */
+  refreshChart (research = false) {
+    if (research) {
+      if (typeof this.searchVerify === 'function' && !this.searchVerify()) return;
+    }
+
+    this.loadChartDataImpl(true).catch(e => {});
+  }
+}

+ 146 - 0
src/views/login/index.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="login-form">
+    <div class="login-box">
+      <div class="login-input">
+        <span class="title">模型管理平台</span>
+        <el-form
+          :model="dataForm"
+          :rules="dataRule"
+          size="medium"
+          ref="dataForm"
+          @keyup.enter.native="dataFormSubmit()"
+          style="width: 356px; margin-top: 4vh"
+        >
+          <el-col :span="24">
+            <el-form-item prop="mobilePhone">
+              <el-input
+                v-model="dataForm.mobilePhone"
+                style="width: 100%"
+                placeholder="帐号"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item prop="password">
+              <el-input
+                v-model="dataForm.password"
+                style="width: 100%"
+                type="password"
+                placeholder="密码"
+                show-password
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-button
+            class="login-btn-submit"
+            type="primary"
+            style="width: 100%"
+            @click="dataFormSubmit()"
+            :loading="isHttpLoading"
+          >
+            登录
+          </el-button>
+        </el-form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { SystemController } from "@/api";
+import projectConfig from "@/core/config";
+import { encrypt, setToken } from "@/utils";
+
+export default {
+  data() {
+    return {
+      dataForm: {
+        mobilePhone: "xxyyhh",
+        password: "123456",
+      },
+      dataRule: {
+        mobilePhone: [
+          { required: true, message: "帐号不能为空", trigger: "blur" },
+        ],
+        password: [
+          { required: true, message: "密码不能为空", trigger: "blur" },
+        ],
+      },
+      projectName: projectConfig.projectName,
+    };
+  },
+  methods: {
+    dataFormSubmit() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          let params = {
+            loginName: this.dataForm.mobilePhone,
+            password: encrypt(this.dataForm.password),
+          };
+
+          SystemController.login(this, params, null, { showMask: false })
+            .then((data) => {
+              this.$store.commit("user/setUserInfo",{ loginName: params.loginName, ...data.data });
+              setToken(data.data.tokenData);
+              this.$router.push({ path: "/home" });
+            })
+            .catch((e) => {});
+        }
+      });
+    },
+  },
+  mounted() {
+    this.$store.commit("user/setUserInfo",{});
+    setToken();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.login-form {
+  width: 100vw;
+  height: 100vh;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-image: url("~@/assets/image/map-bg.jpg") !important;
+  background-repeat: no-repeat;
+  background-position: 50%;
+  background-size: 100% 100%;
+  .login-box {
+    display: flex;
+    align-items: center;
+    height: 30vh;
+    border-radius: 3px;
+    opacity: 0.8;
+    background: white;
+    .login-input {
+      height: 100%;
+      width: 420px;
+      display: flex;
+      align-items: center;
+      flex-direction: column;
+      img {
+        width: 356px;
+        height: 42px;
+        margin-top: 6vh;
+      }
+      .title {
+        color: #232323;
+        font-size: 20px;
+        margin-top: 2vh;
+        text-align: center;
+      }
+    }
+  }
+}
+
+.login-form .el-input__inner {
+  height: 45px !important;
+}
+
+.login-form .el-button {
+  height: 45px !important;
+  font-size: 20px;
+}
+</style>

+ 8 - 0
src/views/situation/index.vue

@@ -112,6 +112,14 @@
       this.cesiumInit();
       this.pointMove();
       this.startWebSocket();
+      this.viewer2D.entities.add({
+          position: new this.Cesium.Cartesian3.fromDegrees(117.918977, 25.0, 100000),
+          model: {
+            uri: satelliteModel, // 替换为你的3D模型文件路径
+            scale: 1.0, // 调整3D模型的缩放大小
+            minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
+          }
+        });
     },
     beforeDestroy() {
       // 在组件销毁前,关闭WebSocket连接