zhangkunling před 3 roky
rodič
revize
d3de7ec2f5
45 změnil soubory, kde provedl 4160 přidání a 334 odebrání
  1. 100 0
      package-lock.json
  2. 8 0
      package.json
  3. 1 1
      public/index.html
  4. 8 5
      src/App.vue
  5. 39 15
      src/assets/iconfont/iconfont.css
  6. 0 0
      src/assets/iconfont/iconfont.js
  7. 63 21
      src/assets/iconfont/iconfont.json
  8. binární
      src/assets/iconfont/iconfont.ttf
  9. binární
      src/assets/iconfont/iconfont.woff
  10. binární
      src/assets/iconfont/iconfont.woff2
  11. binární
      src/assets/images/childStation.png
  12. binární
      src/assets/images/headPortrait.png
  13. binární
      src/assets/images/loginBg.png
  14. binární
      src/assets/images/logo.png
  15. binární
      src/assets/images/mainBox.png
  16. binární
      src/assets/images/noData.png
  17. binární
      src/assets/images/parentStation.png
  18. binární
      src/assets/images/subStation.png
  19. binární
      src/assets/images/titleBg.png
  20. 287 156
      src/assets/styles/common.css
  21. 0 9
      src/assets/styles/common.styl
  22. 0 58
      src/components/HelloWorld.vue
  23. 3 3
      src/components/common/LoadingAnimation.vue
  24. 226 0
      src/components/common/TreeList.vue
  25. 3 3
      src/components/common/index.js
  26. 1 2
      src/libs/utils.js
  27. 205 20
      src/login/Login.vue
  28. 2 2
      src/main.js
  29. 87 8
      src/router/index.js
  30. 50 11
      src/views/MainPage.vue
  31. 488 0
      src/views/homecomponents/BasicInfomation/ApplicationEquip.vue
  32. 53 0
      src/views/homecomponents/BasicInfomation/ApplicationManage.vue
  33. 546 0
      src/views/homecomponents/BasicInfomation/ApplicationStation.vue
  34. 246 0
      src/views/homecomponents/BasicInfomation/DeviceManage.vue
  35. 24 0
      src/views/homecomponents/BasicInfomation/InstruManage.vue
  36. 498 0
      src/views/homecomponents/BasicInfomation/LineManage.vue
  37. 242 0
      src/views/homecomponents/BasicInfomation/LineStationManage.vue
  38. 24 0
      src/views/homecomponents/BasicInfomation/OperaTimeManage.vue
  39. 497 0
      src/views/homecomponents/BasicInfomation/StationManage.vue
  40. 58 3
      src/views/homecomponents/Content.vue
  41. 24 0
      src/views/homecomponents/EquipmentAnalysis/AlarmHandling.vue
  42. 24 0
      src/views/homecomponents/EquipmentAnalysis/AlarmMonitor.vue
  43. 195 10
      src/views/homecomponents/Head.vue
  44. 133 3
      src/views/homecomponents/Nav.vue
  45. 25 4
      vue.config.js

+ 100 - 0
package-lock.json

@@ -6405,11 +6405,22 @@
       "integrity": "sha1-J8dlOb4U2L0Sghmi1zGwkzeQTnk=",
       "dev": true
     },
+    "js-base64": {
+      "version": "2.6.4",
+      "resolved": "https://registry.npmmirror.com/js-base64/download/js-base64-2.6.4.tgz",
+      "integrity": "sha1-9OaGxd4eofhn28rT1G2WlCjfmMQ=",
+      "dev": true
+    },
     "js-calendar": {
       "version": "1.2.3",
       "resolved": "https://registry.npm.taobao.org/js-calendar/download/js-calendar-1.2.3.tgz",
       "integrity": "sha1-pYOwZEtOaVujlPNE0QPbzHp6fT4="
     },
+    "js-md5": {
+      "version": "0.7.3",
+      "resolved": "https://registry.nlark.com/js-md5/download/js-md5-0.7.3.tgz",
+      "integrity": "sha1-tPL7sLMnRV9ZjWcn447Ccs0Jw/I="
+    },
     "js-message": {
       "version": "1.0.7",
       "resolved": "https://registry.npm.taobao.org/js-message/download/js-message-1.0.7.tgz",
@@ -8226,6 +8237,95 @@
         }
       }
     },
+    "postcss-plugin-px2rem": {
+      "version": "0.8.1",
+      "resolved": "https://registry.nlark.com/postcss-plugin-px2rem/download/postcss-plugin-px2rem-0.8.1.tgz",
+      "integrity": "sha1-6K3yj9K++8B5oRkSa1xiqIkF1eE=",
+      "dev": true,
+      "requires": {
+        "postcss": "^5.0.21"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.nlark.com/ansi-regex/download/ansi-regex-2.1.1.tgz?cache=0&sync_timestamp=1631634988487&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-regex%2Fdownload%2Fansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "2.2.1",
+          "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-2.2.1.tgz",
+          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmmirror.com/chalk/download/chalk-1.1.3.tgz",
+          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^2.2.1",
+            "escape-string-regexp": "^1.0.2",
+            "has-ansi": "^2.0.0",
+            "strip-ansi": "^3.0.0",
+            "supports-color": "^2.0.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmmirror.com/supports-color/download/supports-color-2.0.0.tgz",
+              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+              "dev": true
+            }
+          }
+        },
+        "has-ansi": {
+          "version": "2.0.0",
+          "resolved": "https://registry.nlark.com/has-ansi/download/has-ansi-2.0.0.tgz",
+          "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "1.0.0",
+          "resolved": "https://registry.nlark.com/has-flag/download/has-flag-1.0.0.tgz",
+          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "5.2.18",
+          "resolved": "https://registry.npmmirror.com/postcss/download/postcss-5.2.18.tgz",
+          "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=",
+          "dev": true,
+          "requires": {
+            "chalk": "^1.1.3",
+            "js-base64": "^2.1.9",
+            "source-map": "^0.5.6",
+            "supports-color": "^3.2.3"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmmirror.com/strip-ansi/download/strip-ansi-3.0.1.tgz?cache=0&sync_timestamp=1632420634508&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmmirror.com/supports-color/download/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        }
+      }
+    },
     "postcss-reduce-initial": {
       "version": "4.0.3",
       "resolved": "https://registry.nlark.com/postcss-reduce-initial/download/postcss-reduce-initial-4.0.3.tgz",

+ 8 - 0
package.json

@@ -9,6 +9,7 @@
   "dependencies": {
     "axios": "^0.24.0",
     "core-js": "^3.6.5",
+    "js-md5": "^0.7.3",
     "lib-flexible": "^0.3.2",
     "lodash": "^4.17.21",
     "moment": "^2.29.1",
@@ -22,11 +23,18 @@
     "@vue/cli-plugin-router": "~4.5.0",
     "@vue/cli-plugin-vuex": "~4.5.0",
     "@vue/cli-service": "~4.5.0",
+    "postcss-plugin-px2rem": "^0.8.1",
     "px2rem-loader": "^0.1.9",
     "stylus": "^0.54.7",
     "stylus-loader": "^3.0.2",
     "vue-template-compiler": "^2.6.11"
   },
+  "postcss": {
+    "plugins": {
+      "autoprefixer": {},
+      "precss": {}
+    }
+  },
   "browserslist": [
     "> 1%",
     "last 2 versions",

+ 1 - 1
public/index.html

@@ -3,7 +3,7 @@
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <!-- <title><%= htmlWebpackPlugin.options.title %></title> -->
     <title>智慧城轨大数据后台管理平台</title>

+ 8 - 5
src/App.vue

@@ -4,9 +4,12 @@
   </div>
 </template>
 
-<style lang="stylus">
-#app
-  font-family Avenir, Helvetica, Arial, sans-serif
-  -webkit-font-smoothing antialiased
-  -moz-osx-font-smoothing grayscale 
+<style scoped lang="stylus">
+* {
+  margin: 0;
+  padding:0;
+}
+#app {
+  height 100%
+}
 </style>

+ 39 - 15
src/assets/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2962009 */
-  src: url('iconfont.woff2?t=1637916518198') format('woff2'),
-       url('iconfont.woff?t=1637916518198') format('woff'),
-       url('iconfont.ttf?t=1637916518198') format('truetype');
+  src: url('iconfont.woff2?t=1638406575427') format('woff2'),
+       url('iconfont.woff?t=1638406575427') format('woff'),
+       url('iconfont.ttf?t=1638406575427') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,42 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-qiyong:before {
+  content: "\e7e5";
+}
+
+.icon-guanbi:before {
+  content: "\e611";
+}
+
+.icon-shouye:before {
+  content: "\e684";
+}
+
+.icon-bianji:before {
+  content: "\e6de";
+}
+
+.icon-084tuichu:before {
+  content: "\e659";
+}
+
+.icon-xiaoxi:before {
+  content: "\e6eb";
+}
+
+.icon-suoding:before {
+  content: "\e8d4";
+}
+
+.icon-people:before {
+  content: "\e61d";
+}
+
+.icon-yanzheng:before {
+  content: "\e632";
+}
+
 .icon-shanchu:before {
   content: "\e74b";
 }
@@ -33,18 +69,10 @@
   content: "\e624";
 }
 
-.icon-xianlu:before {
-  content: "\e6ee";
-}
-
 .icon-xianlu1:before {
   content: "\e63c";
 }
 
-.icon-kucunguanli:before {
-  content: "\e7ca";
-}
-
 .icon-ic_chart_yibiaopan_disd:before {
   content: "\eadf";
 }
@@ -65,10 +93,6 @@
   content: "\e66f";
 }
 
-.icon-jichuguanli:before {
-  content: "\e61c";
-}
-
 .icon-tongyongshebei:before {
   content: "\e62d";
 }

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
src/assets/iconfont/iconfont.js


+ 63 - 21
src/assets/iconfont/iconfont.json

@@ -6,6 +6,69 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "752475",
+      "name": "启用",
+      "font_class": "qiyong",
+      "unicode": "e7e5",
+      "unicode_decimal": 59365
+    },
+    {
+      "icon_id": "1356143",
+      "name": "关闭",
+      "font_class": "guanbi",
+      "unicode": "e611",
+      "unicode_decimal": 58897
+    },
+    {
+      "icon_id": "3978426",
+      "name": "首页",
+      "font_class": "shouye",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "2064844",
+      "name": "编辑",
+      "font_class": "bianji",
+      "unicode": "e6de",
+      "unicode_decimal": 59102
+    },
+    {
+      "icon_id": "584065",
+      "name": "退出",
+      "font_class": "084tuichu",
+      "unicode": "e659",
+      "unicode_decimal": 58969
+    },
+    {
+      "icon_id": "3405405",
+      "name": "消息",
+      "font_class": "xiaoxi",
+      "unicode": "e6eb",
+      "unicode_decimal": 59115
+    },
+    {
+      "icon_id": "1727485",
+      "name": "242锁定",
+      "font_class": "suoding",
+      "unicode": "e8d4",
+      "unicode_decimal": 59604
+    },
+    {
+      "icon_id": "2837652",
+      "name": "people",
+      "font_class": "people",
+      "unicode": "e61d",
+      "unicode_decimal": 58909
+    },
+    {
+      "icon_id": "7964512",
+      "name": "验证",
+      "font_class": "yanzheng",
+      "unicode": "e632",
+      "unicode_decimal": 58930
+    },
+    {
       "icon_id": "577357",
       "name": "删除",
       "font_class": "shanchu",
@@ -41,13 +104,6 @@
       "unicode_decimal": 58916
     },
     {
-      "icon_id": "9059189",
-      "name": "线路",
-      "font_class": "xianlu",
-      "unicode": "e6ee",
-      "unicode_decimal": 59118
-    },
-    {
       "icon_id": "13741569",
       "name": "线路 ",
       "font_class": "xianlu1",
@@ -55,13 +111,6 @@
       "unicode_decimal": 58940
     },
     {
-      "icon_id": "16137360",
-      "name": "库存管理",
-      "font_class": "kucunguanli",
-      "unicode": "e7ca",
-      "unicode_decimal": 59338
-    },
-    {
       "icon_id": "20308195",
       "name": "ic_chart_仪表盘_disd",
       "font_class": "ic_chart_yibiaopan_disd",
@@ -97,13 +146,6 @@
       "unicode_decimal": 58991
     },
     {
-      "icon_id": "11835090",
-      "name": "基础管理",
-      "font_class": "jichuguanli",
-      "unicode": "e61c",
-      "unicode_decimal": 58908
-    },
-    {
       "icon_id": "14151211",
       "name": "通用设备",
       "font_class": "tongyongshebei",

binární
src/assets/iconfont/iconfont.ttf


binární
src/assets/iconfont/iconfont.woff


binární
src/assets/iconfont/iconfont.woff2


binární
src/assets/images/childStation.png


binární
src/assets/images/headPortrait.png


binární
src/assets/images/loginBg.png


binární
src/assets/images/logo.png


binární
src/assets/images/mainBox.png


binární
src/assets/images/noData.png


binární
src/assets/images/parentStation.png


binární
src/assets/images/subStation.png


binární
src/assets/images/titleBg.png


+ 287 - 156
src/assets/styles/common.css

@@ -1,3 +1,149 @@
+html,body{
+  overflow-x: hidden;
+  height: 100%;
+  -webkit-tap-highlight-color: transparent;
+}
+/* 对话框样式 */
+/*添加draggable 防止遮罩层消失*/
+.ivu-modal-no-mask {
+  /* 防止出现滚动条 */
+  overflow: hidden !important; 
+  pointer-events: auto !important;
+  background-color: rgba(55,55,55,.6);
+}
+/* 弹窗垂直居中 */
+.common-modal .ivu-modal {
+  width: auto !important;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  top:0
+}
+.common-modal .ivu-modal-content {
+  background-color: #06214D;
+  border: 1px solid #0185EA;
+}
+.common-modal .ivu-modal-header {
+  background: linear-gradient(90deg, #0B7FD8, #09398E);
+  border-bottom: 1px solid #21437B;
+  /* height: 46px;
+  line-height: 46px; */
+}
+.common-modal .ivu-modal-header .ivu-modal-header-inner {
+  font-size: 16px;
+  font-weight: bold;
+  color: #FFFFFF;
+}
+.common-modal .ivu-modal-close .ivu-icon-ios-close:hover {
+  color: #999;
+}
+.common-modal .ivu-modal-footer {
+  border-top: none;
+  padding-top: 0;
+}
+.common-modal .ivu-btn-default {
+  background-color: #0E2F63;
+  border: 1px solid #5774A3;
+  border-radius: 5px;
+  color: #83A4D9;
+  font-size: 12px;
+}
+.common-modal .ivu-btn-default:hover {
+  background-color: #1A4385;
+  border: 1px solid #5774A3; 
+}
+.common-modal .modal-icon {
+  font-size: 24px;
+  vertical-align: middle;
+}
+.common-modal .modal-text {
+  font-size: 14px;
+  vertical-align: middle;
+  margin-left: 10px;
+  color: #fff;
+}
+/* form表单样式 */
+.common-form .ivu-form-item-label {
+  color: #F5F5F5;
+}
+.common-form .ivu-form-item {
+  color: #F5F5F5;
+}
+.common-form .ivu-input {
+  background: #06214D;
+  border: 1px solid #204A8F;
+  border-radius: 6px;
+  color: #F5F5F5;
+}
+.common-form .ivu-input-word-count {
+  background: transparent;
+}
+.common-form .ivu-input-number{
+  border: 1px solid #204A8F;
+  background-color: transparent;
+  width: -webkit-fill-available;
+}
+.common-form .ivu-input-number-input {
+  background: #06214D;
+  /* border: 1px solid #0185EA; */
+  border-radius: 6px;
+  color: #F5F5F5;
+}
+.common-form .ivu-input-number-handler-wrap {
+  background: #06214D;
+  border-left: 1px solid #0185EA;
+}
+.common-form .ivu-input-number-handler-down {
+  border-top: 1px solid #0185EA;
+}
+.common-form .ivu-input-number-handler-down-inner, .common-form .ivu-input-number-handler-up-inner {
+  color: #0185EA;
+}
+.ivu-input:focus{
+  border: 1px solid #0185EA;
+}
+.common-form .ivu-input-number-focused {
+  border: 1px solid #0185EA;
+}
+/* 下拉框样式 */
+.ivu-select-selection {
+  background: #06214D;
+  border: 1px solid #204A8F;
+  border-radius: 6px;
+  color: #F5F5F5;
+}
+.ivu-select-single .ivu-select-selection {
+  height: 100%;
+}
+.ivu-select-single .ivu-select-selection div{
+  height: 100%;
+}
+.ivu-select-single .ivu-select-selection div span{
+  height: 100% !important;
+  display: flex !important;
+  align-items: center !important;
+}
+.ivu-select-dropdown {
+  background-color: #06214D;
+}
+.ivu-select-item {
+  color: #F5F5F5;
+}
+.ivu-select-item-focus {
+  background: transparent;
+}
+.ivu-select-item:hover {
+  background: #2e4e89;
+  color: #f2f2f2;
+}
+.ivu-select-item-selected, .ivu-select-item-selected:hover {
+  background: #0185ea;
+  color: #f2f2f2;
+}
+.ivu-select-single .ivu-select-selection .ivu-select-placeholder {
+  color: #718EBD;
+}
 /* 滚动条 webkit内核 start  .ivu-cascader-menu 级联下拉列表里的滚动条 .ivu-select-dropdown 单个下拉列表里的滚动条 .common-modal-tabs .ivu-tabs-tabpane详情对话框里的滚动条*/
 .common-scroll::-webkit-scrollbar,
 .ivu-select-dropdown::-webkit-scrollbar {
@@ -8,7 +154,7 @@
 
 .common-scroll::-webkit-scrollbar-track,
 .ivu-select-dropdown::-webkit-scrollbar-track {
-  background-color: rgba(89, 91, 93, 0.3);
+  background-color: rgba(39, 76, 136, 0.3);
   -webkit-border-radius: 2em;
   -moz-border-radius: 2em;
   border-radius: 2em;
@@ -22,185 +168,170 @@
   -moz-border-radius: 2em;
   border-radius: 2em;
 }
-
-/*IE*/
-.common-scroll,
-.ivu-select-dropdown {
-  scrollbar-arrow-color: rgba(8, 26, 64, 0.8);
-  scrollbar-track-color: rgba(8, 26, 64, 0.8);
-  scrollbar-highlight-color: rgba(8, 26, 64, 0.8);
-  scrollbar-base-color: rgba(8, 26, 64, 0.8);
+/* tab页的通用样式 */
+.common-tabs {
+  color: #fff;
 }
-
-/* ivu-table-body大多数表格里的滚动条 special-table个别表格里的滚动条*/
-.ivu-table-body::-webkit-scrollbar,
-.special-table .ivu-table-body::-webkit-scrollbar {
-  height: 5px;
-  width: 5px;
-  opacity: 0.6;
+.common-tabs .ivu-tabs-bar {
+  border-bottom: 1px solid #173B77;
 }
-
-/* 定义滚动条的滑块部分 */
-.ivu-table-body::-webkit-scrollbar-track,
-.special-table .ivu-table-body::-webkit-scrollbar-track {
-  background-color: #1f2f69;
-  -webkit-border-radius: 0em;
-  -moz-border-radius: 0em;
-  border-radius: 0em;
+.common-tabs .ivu-tabs-bar {
+  margin-bottom: 0;
+} 
+.common-tabs .ivu-tabs-nav-container {
+  font-size: 16px;
 }
-
-/*  */
-.ivu-table-body::-webkit-scrollbar-thumb,
-.special-table .ivu-table-body::-webkit-scrollbar-thumb {
-  opacity: 1;
-  background-color: #435579;
-  -webkit-border-radius: 0em;
-  -moz-border-radius: 0em;
-  border-radius: 0em;
+.common-tabs .ivu-tabs-nav-wrap {
+  height: 50px;
+  line-height: 50px;
 }
-
-.ivu-table-body,
-.special-table .ivu-table-body {
-  scrollbar-arrow-color: #435579;
-  scrollbar-track-color: #435579;
-  scrollbar-highlight-color: #435579;
-  scrollbar-base-color: #435579;
+.common-tabs .ivu-tabs-nav-scroll {
+  height: 100%;
 }
-
-/* 滚动条 end */
-/* 日期选择
-     .common-datepick .ivu-input {
-        background-color: #18255c;
-        border: 1px solid #058FF9;;
-		    color: #fff;
-     }
-     .common-datepick .ivu-select-dropdown {
-        background-color: #081a40;
-        border: 1px solid #024a8a;
-        border-radius: 2px;
-     }
-     .common-datepick .ivu-date-picker-header {
-      color: #fff;
-      border-bottom: 1px solid #04386e;
-     }
-     .common-datepick .ivu-date-picker-cells span em {
-        color: #fff;
-     }
-     .common-datepick .ivu-date-picker-cells-cell:hover em {
-		background-color: #2d8cf0
-    }
-    .common-datepick .ivu-date-picker-cells-cell-selected em{
-       background-color: transparent
-    }
-    .common-datepick span.ivu-date-picker-cells-cell-disabled,
-	.common-datepick span.ivu-date-picker-cells-cell-disabled:hover {
-		background-color: transparent !important
-    }
-    .common-datepick .ivu-date-picker-cells-cell-range:before {
-      background-color: #0e3458 !important;
-    } */
-/* .ivu-date-picker-cells-month .ivu-date-picker-cells-cell-focused, .ivu-date-picker-cells-year .ivu-date-picker-cells-cell-focused {
-        background-color: #5b8cf3;
-    } */
-/*下拉列表共同样式 相同class名common-select*/
-.common-select {
-  background-color: rgba(0, 0, 0, 0);
-  border: 0px solid red;
-  color: #fff;
+.common-tabs .ivu-tabs-nav {
+  height: 100%;
 }
-
-.common-select .ivu-select-dropdown {
-  background-color: #1c2c4e;
-  border: 0px solid #014b8c;
+.common-tabs .ivu-tabs-nav .ivu-tabs-tab-active {
+  color: #0185EA;
+  font-weight: bold;
 }
-
-.common-select .ivu-select-arrow {
-  color: #0b85e5;
+.common-tabs .ivu-tabs-ink-bar{
+  color: #0185EA;
+  height: 3px;
 }
-
-.common-select .ivu-select-dropdown-list li {
-  padding-left: 10px;
-  color: #fff;
+.common-tabs .ivu-tabs-nav .ivu-tabs-tab {
+ padding-top: 0;
+ padding-bottom: 0;
 }
-
-.common-select .ivu-select-item-focus {
-  /* background-color: #0b85e5; */
-  background-color: transparent;
+/* 新增按钮表格的样式 */
+.ivu-btn {
+  height: 32px;
 }
-
-.common-select .ivu-select-item-selected,
-.common-select .ivu-select-item-selected:hover {
-  background-color: #0b85e5;
+ .common-add-btn {
+  background: #0D2C5E;
+  border: 1px solid #4795F9;
+  border-radius: 6px;
+  font-weight: bold;
+  color: #4795F9;
+  height: 32px;
+  font-size: 14px;
+  box-shadow: none;
+ }
+ .common-add-btn .ivu-icon-ios-add {
+  font-size: 18px;
+ }
+ .common-add-btn:hover {
+  color: #fff;
+  background-color: #0185ea;
+ }
+ .common-add-btn.active, .common-add-btn:active {
+  color: #fff;
+  background-color: #0185ea;
+ }
+ /* 表格的样式 */
+ .common-table .ivu-table{
+  background-color: transparent;
+ }
+ .common-table .ivu-table:before {
+  height: 0;
+  /* background-color: #173B77; */
+ }
+ .common-table .ivu-table th {
+  background-color: #14316A;
+  color: #FFFFFF;
+  border-bottom: 1px solid #173B77;
+ }
+ .common-table .ivu-table td {
+  border-bottom: 1px solid #173B77;
+  color: #FFFFFF;
+ }
+ .common-table .ivu-table td {
+  background-color: transparent;
+ }
+ .common-table .ivu-table .ivu-table-cell {
+   padding-left: 10px;
+   padding-right: 10px;
+ }
+ .common-table .ivu-table-stripe-even td{
+  background-color: #081C43;
+  
+ }
+ .common-table .ivu-table-stripe-odd td{
+  background-color: #072453;
+ }
+ /*表格暂无数据*/
+ .common-table .ivu-table-tip {
+  display: flex;
+  align-items: center;
+  background: url('../../assets/images/noData.png') no-repeat center;
+  min-height: 300px;
 }
-
-.common-select .ivu-select-item {
-  padding: 7px 16px;
+.ivu-table-tip table {
+  display: none;
 }
-
-.common-select .ivu-select-item:hover {
-  background-color: #0b85e5;
+ .ivu-spin-fix {
+  background-color: #06214d;
+ }
+ .ivu-spin-fix .ivu-spin-main {
+   width: 100%;
+ }
+ /* 分页的样式 */
+.common-page .ivu-page-next, .common-page .ivu-page-prev {
+  background-color: #154086;
+  border: 1px solid #014b8c;
   color: #fff;
+  min-width: 32px;
+  height: 32px;
+  line-height: 30px;
+  margin-right: 4px;
+  font-size: 12px;
 }
-
-.common-select .ivu-select-selection {
-  border: 1px solid #058ff9;
-  border-radius: 5px;
-  background-color: #18255c;
+.common-page .ivu-page-item {
+  background-color: #154086;
+  border: none;
+  min-width: 32px;
+  height: 32px;
+  line-height: 30px;
+  margin-right: 4px;
+  font-size: 12px;
 }
-
-.common-select .ivu-select-input {
+.common-page .ivu-page-item a, .common-page .ivu-page-item:hover a {
   color: #fff;
 }
-
-/*添加draggable 防止遮罩层消失*/
-.ivu-modal-no-mask {
-  /* 防止出现滚动条 */
-  overflow: hidden !important;
-  pointer-events: auto !important;
-  background-color: rgba(55, 55, 55, 0.6);
+.common-page .ivu-page-item-active {
+  background-color: #409EFF;
 }
-
-/* 弹窗垂直居中 */
-.ivu-modal-wrap .ivu-modal {
-  width: auto !important;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  height: 100%;
-  top: 0;
+.common-page .ivu-page-item-active a, .common-page .ivu-page-item-active:hover a {
+  color: #fff;
 }
-.ivu-modal .ivu-modal-header {
-  border-bottom: 1px solid #2c3d6d;
+.common-page .ivu-icon  {
+  color: #fff;
 }
-
-.ivu-modal-wrap .ivu-modal-content {
-  width: 100%;
-  background-color: #152143 !important;
+.common-page .ivu-page-options-elevator {
+  color: #fff;
+  height: 32px;
 }
-
-/* 搜索框样式 */
-.common-search .ivu-input{
-  border: 1px solid #1D84B9;
-  border-radius: 16px;
-  background-color: transparent;
+.common-page .ivu-page-options-elevator input {
+  background-color: #154086;
+  border: none;
   color: #fff;
+  padding: 4px 7px;
+  font-size: 12px;
+  min-width: 50px;
+  height: 32px;
 }
-.common-search .ivu-input-suffix {
-  display: flex;
-  align-items: center;
-  justify-content: center;
+.common-page .ivu-page-item-jump-next, .common-page .ivu-page-item-jump-prev, .common-page .ivu-page-next, .common-page .ivu-page-prev {
+  height: 32px;
+  line-height: 30px;
 }
-.common-search .ivu-input-suffix i {
-  color: #1D84B9;
+.common-page .ivu-page-item-jump-next, 。.common-page .ivu-page-item-jump-prev, 。.common-page .ivu-page-next, .ivu-page-prev {
+  height: 32px;
+  line-height: 30px;
 }
-/* 表格下按钮新增样式 */
-.common-btn-add {
-  background-color: #1B3670;
-  border: 1px solid #2AADF7;
-  border-radius: 4px;
-  font-weight: bold;
-  color: #2AADF7;
+/* Tooltip的样式 */
+.ivu-tooltip-inner {
+  background-color: #335493;
 }
-.common-btn-add:hover {
-  background-color: #2AADF7;
+.ivu-tooltip-popper[x-placement^=top] .ivu-tooltip-arrow {
+  border-top-color: #335493;
 }

+ 0 - 9
src/assets/styles/common.styl

@@ -1,9 +0,0 @@
-$baseFontSizeWidth = 1920
-$baseFontSizeHeight = 1080
-
-px2vw($px){
-  $px / $baseFontSizeWidth * 100vw
-}
-px2vh($px) {
-  $px / $baseFontSizeHeight * 100vh
-}

+ 0 - 58
src/components/HelloWorld.vue

@@ -1,58 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br>
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
-      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
-      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
-      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
-      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'HelloWorld',
-  props: {
-    msg: String
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="stylus">
-h3
-  margin 40px 0 0
-
-ul
-  list-style-type none
-  padding 0
-
-li
-  display inline-block
-  margin 0 10px
-
-a
-  color #42b983
-</style>

+ 3 - 3
src/components/common/LoadingAnimation.vue

@@ -64,13 +64,13 @@ export default {
   align-items: center;
   justify-content: center;
   flex-direction: column;
-  position: absolute;
+  /* position: absolute;
   top: 0;
   bottom: 0;
   right: 0;
   left: 0;
   right: 0;
-  margin: auto;
+  margin: auto; */
 }
 .loading-has-text {
   height: calc(100% - 30px);
@@ -85,7 +85,7 @@ export default {
   color: #636b7f;
   line-height: 16px;
   text-align: center;
-  padding-top: 20px;
+  padding-top: 30px;
 }
 .spinner {
   /* margin: 10px auto; */

+ 226 - 0
src/components/common/TreeList.vue

@@ -0,0 +1,226 @@
+<template>
+  <div>
+    <Tree :data="treeData" @on-select-change="selectChange" ref="tree" :render="renderContent"></Tree>
+  </div>
+</template>
+<script>
+export default {
+  name: "TreeList",
+  props: {
+    currentStaData: {
+      type: Array,
+      default: () => {
+        return [];
+      }
+    },
+    defaultData: {
+      type: Array,
+      default: () => {
+        return [];
+      }
+    },
+    clickAllNode: { // 是否能点击全部节点 (true可点击  false只能点击最后层级站点)
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      treeData: [],
+      parentSrc:require('../../assets/images/parentStation.png'),
+      secondSrc:require('../../assets/images/subStation.png'),
+      childSrc:require('../../assets/images/childStation.png'),
+      selectVal: '合肥火车站',
+    };
+  },
+  watch: {},
+  mounted() {
+    this.treeData = this.defaultData;
+    console.log('treelist',this.treeData)
+  },
+  methods: {
+    renderContent(h, { root, node, data }) {
+      let src = "";
+      if (data.title == '合肥轨道交通') {
+        src = this.parentSrc;
+      } else if (data.parent) {
+        // src = this.secondSrc;
+        src = this.secondSrc;
+      } else {
+        src = this.childSrc;
+      }
+      return h(
+        "span",
+        {
+          style: {
+            display: "inline-block",
+            width: "100%",
+          }
+        },
+        [
+          h("span", [
+            h("img", {
+              attrs: {
+                src: src
+              },
+              style: {
+                verticalAlign: "text-bottom",
+                display: "inline-block",
+                margin: "0px 5px"
+              }
+            }),
+            h(
+              "span",data.title
+            )
+          ])
+        ]
+      );
+    },
+    selectChange(option) {
+      let newArr = []
+      let arr = []
+      if (option.length != 0) {
+        if (option.length == 2) {
+          var result = []; // 两组数组对象取不同属性的值
+          for(var i = 0; i < option.length; i++){
+              var obj = option[i];
+              var num = obj.title;
+              var isExist = false;
+              for(var j = 0; j < this.currentStaData.length; j++){
+                  var aj = this.currentStaData[j];
+                  var n = aj.title;
+                  if(n == num){
+                      isExist = true;
+                      break;
+                  }
+              }
+              if(!isExist){
+                  result.push(obj);
+              }
+          }
+          newArr = result
+        } else {
+          newArr = option
+        }
+        if (this.clickAllNode) {
+          this.treeData.forEach((items, index,itemsArr) => {
+            items.expand = false; //expand 是否展开直子节点 
+            items.disabled = false; // disabled 是否禁止选中
+            items.selected = false;
+            if (items.title == newArr[0].title && items.id == newArr[0].id) {
+                items.selected = true;
+                items.disabled = true; // disabled 是否禁止选中 
+                items.expand = true;
+                this.selectVal = items.title;
+                arr.push(items.title)
+            }  
+            items.children.forEach((val, i,valArr) => {
+              val.expand = false; //expand 是否展开直子节点 
+              val.disabled = false; // disabled 是否禁止选中
+              val.selected = false;
+              if (val.title == newArr[0].title && val.id == newArr[0].id) {
+                  val.selected = true;
+                  val.disabled = true; // disabled 是否禁止选中 
+                  val.expand = true;
+                  this.selectVal = val.title;
+                  items.expand = true
+                  arr.push(items.title)
+                  arr.push(val.title)
+              }
+              if (val.children && val.children.length>0) {
+                val.children.forEach((selectItem, j) => {
+                  selectItem.expand = false; //expand 是否展开直子节点 
+                  selectItem.disabled = false; 
+                  selectItem.selected = false;
+                  if (newArr[0].title =='合肥轨道交通') {
+                    valArr[index].expand = true
+                  }
+                  if (selectItem.title == newArr[0].title && selectItem.id == newArr[0].id) {
+                    selectItem.selected = true;
+                    selectItem.disabled = true; // disabled 是否禁止选中 
+                    selectItem.expand = true;
+                    val.expand = true
+                    items.expand = true
+                    this.selectVal = selectItem.title;
+                    arr.push(items.title)
+                    arr.push(val.title)
+                    arr.push(selectItem.title)
+                  }
+                })
+              }
+            });   
+          });
+        } else {
+           this.treeData.forEach((items, index) => {
+              items.expand = false; //expand 是否展开直子节点 
+              items.children.forEach((val, i) => {
+                val.selected = false; // selected 是否选中子节点
+                val.disabled = false;
+                if (val.title == newArr[0].title && val.id == newArr[0].id) {
+                  val.selected = true;
+                  val.disabled = true; // disabled 是否禁止选中 
+                  items.expand = true;
+                  this.selectVal = val.title;
+                  arr.push(items.title)
+                  arr.push(val.title)
+                }
+              });
+          });
+        }
+      }
+      this.$emit('treeChange',this.selectVal,arr)
+    },
+  }
+}
+
+</script>
+<style scoped lang="stylus">
+>>> .ivu-tree-arrow {
+  color: #00FFFF;
+  height: 30px;
+  line-height: 30px;
+  width: 15px;
+}
+>>> .ivu-tree-children li {
+  width: 100%;
+}
+>>> .ivu-tree-title {
+  color: #fff;
+  width: 94%;
+  padding: 6px 4px;
+}
+>>> .ivu-tree-title:hover {
+    background-color: transparent;
+}
+>>> .ivu-tree-title-selected, >>> .ivu-tree-title-selected:hover {
+  background-color: #3565BC;
+  // background-color: transparent;
+  color: #fff;
+}
+>>> .ivu-tree-title img {
+  width: 18px;
+  height: 18px;
+}
+// >>> .ivu-tree .ivu-icon {// 禁止旋转
+//   -webkit-transform: rotate(0deg);
+//   transform: rotate(0deg);
+// }
+// >>> .ivu-tree .ivu-icon-ios-arrow-forward:before { //改变tree默认折叠的三角箭头
+//     background: url('../../assets/images/yu.png') no-repeat 0 3px;
+//     content: '';
+//     display: block;
+//     width: 16px;
+//     height: 16px;
+//     font-size: 16px;
+//     background-size: 16px;
+// }
+// >>> .ivu-tree .ivu-tree-arrow-open .ivu-icon-ios-arrow-forward:before { //改变tree默认展开的三角箭头
+//     background: url('../../assets/images/warning.png') no-repeat 0 0px;
+//     content: '';
+//     display: block;
+//     width: 16px;
+//     height: 16px;
+//     font-size: 16px;
+//     background-size: 16px;
+// }
+</style>

+ 3 - 3
src/components/common/index.js

@@ -7,7 +7,7 @@ import NoData from './NoData.vue'
 // import RollingTable from './RollingTable.vue'
 // import RollingDetailTable from './RollingDetailTable.vue'
 // import SelectType from './SelectType.vue'
-// import TreeList from './TreeList.vue'
+import TreeList from './TreeList.vue'
 // import AsideList from './AsideList.vue'
 // import TabsList from './TabsList.vue'
 // import SearchTable from './SearchTable.vue'
@@ -33,8 +33,8 @@ const Global = {
     // Vue.component('RollingDetailTable', RollingDetailTable)
     // // 下拉框组件
     // Vue.component('SelectType', SelectType)
-    // // 树形组件
-    // Vue.component('TreeList', TreeList)
+    // 树形组件
+    Vue.component('TreeList', TreeList)
     // // 表格搜索组件
     // // Vue.component('SearchTable', SearchTable)
     // Vue.component('AsideList', AsideList)

+ 1 - 2
src/libs/utils.js

@@ -20,7 +20,6 @@ const utils = {
     }
     const { menus } = this.storage('sw_user');
     let leftMenus = menus[0].childMenus;
-    
     if(id) {
       const menu = menus.find(item => item.menuId === id);
       leftMenus = menu.childMenus;
@@ -30,7 +29,7 @@ const utils = {
       return !item.childMenus
     })
     let currRouterName = noSubMenu[0].linkUrl;
-    return { currRouterName, leftMenus };
+    return { currRouterName, leftMenus};
   },
   removeSpace (str) { // 去掉字符串中間多余空白(保留一個空白)
     let repStr = ''

+ 205 - 20
src/login/Login.vue

@@ -1,40 +1,225 @@
-  },
 <template>
-  <div class="container" @click="login">
-    登录
-    <i class="iconfont icon-shezhi"></i>
+  <div class="login">
+     <div class="login-top">智慧城轨大数据管理平台</div>
+      <div class="login-body">
+        <div class="login-body-main">
+          <div class="login-body-title">登录入口</div>
+            <Form ref="loginForm" :model="loginForm" :rules="loginRules" class="loginForm">
+              <FormItem prop="userName">
+                <Input type="text" placeholder="输入用户名" v-model="loginForm.userName"  class="login-input">
+                  <i class="iconfont icon-people" slot="prefix"></i>
+                </Input>
+              </FormItem>
+              <FormItem prop="password">
+                <Input type="password" placeholder="输入密码" v-model="loginForm.password" class="login-input" @keyup.enter.native="handleLogin('loginForm')">
+                  <i class="iconfont icon-suoding" slot="prefix"></i>
+                </Input>
+              </FormItem>
+              <Button type="primary" @click="handleLogin('loginForm')" long class="login-btn" style="">登录</Button>
+            </Form>
+            <!-- <div class="forget-password">忘记密码?</div> -->
+            </div>
+      </div>
+      <!-- <Table :columns="columns1" :data="data1" class="aa" @click="login"></Table> -->
   </div>
 </template>
 <script>
-import moment from 'moment'
+import md5 from "js-md5";
+import moment from "moment";
+import utils from "../libs/utils";
 export default {
   name: "Login",
   components:{
   },
   data() {
     return {
+      loginForm: {
+        userName: '',
+        password: '',
+        vCode: 111111
+      },
+      loginRules: {
+          userName: [
+            { required: true, type: 'string', trigger: 'blur', message: '输入用户名' }
+          ],
+          password: [
+            { required: true, trigger: 'blur', message: '输入密码',trigger: 'blur' }
+          ],
+          // vCode: [
+          //   { required: true, trigger: 'blur', message: '请输入验证码',trigger: 'blur' }
+          // ]
+        },
+      columns1: [
+          {
+              title: 'Name',
+              key: 'name'
+          },
+          {
+              title: 'Age',
+              key: 'age'
+          },
+          {
+              title: 'Address',
+              key: 'address',
+             render: (h, params) => {
+              return h('div',[
+                h('i', {class: 'iconfont icon-shezhi'}),
+                h('i',{class: 'iconfont icon-shijian'}),
+                h('span',params.row.address),                
+              ])
+            }
+          }
+      ],
     };
   },
   mounted() {
-    console.log(moment().format('dddd'))
-     this.$get('metroapi/ridership/roadNetwork/inAndOut')
-      .then(res => {
-        
-      })
-      .catch(error => {
-        console.log(error)
-      })
-    // this.$get('api/equipment/list').then(res => {
-    //   console.log(res)
-		// })
+    // console.log(moment().format('dddd'))
   },
   methods: {
-    login () {
-      this.$router.push("/mainPage");
-    }  
+     handleLogin(name) {
+      this.$refs[name].validate((valid) => {
+        if (valid) {
+          const { userName, password, vCode } = this.loginForm;
+          const mdTime = moment().format("YYYY-MM-DD");
+          const tomdpsw ="userName:" + userName + "-userPwd:" + password + "-time:" + mdTime;
+          const formtmdpsw = md5(tomdpsw);
+          let that = this;
+          this.$post('metroapi/login', { userName, feature: formtmdpsw, vCode }).then(res => {
+              if (res.httpCode == 1) {
+                utils.storage("sw_user", {
+                  user: userName,
+                  menus: res.data.menus,
+                  userId: res.data.userId
+                });
+                that.$Message.info(res.msg);
+                setTimeout(() => {
+                  that.$router.push("/mainPage");
+                  sessionStorage.setItem("id", 0);
+                }, 1000);
+              } else {
+                that.$Message.info(res.msg);
+              }
+            }
+          );
+        }
+      })
+    } 
   }
 };
 </script>
 <style scoped lang="stylus">
-
+.login {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  background: url('../assets/images/loginBg.png') no-repeat center;
+  background-size: 100% 100%;
+}
+.login-top {
+  width: 100%;
+  height: 130px;
+  text-align: center;
+  line-height: 130px;
+  font-size: 44px;
+  font-weight: 700;
+  color: rgba(47, 206, 241, 0.7);
+  background: url('../assets/images/titleBg.png') no-repeat center;
+  background-size: 100% 100%;
+}
+.login-body {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.login-body-main {
+  width: 965px;
+  height: 554px;
+  background: url('../assets/images/mainBox.png') no-repeat center;
+  background-size: 100% 100%;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+}
+.login-body-title {
+  font-size: 30px;
+  color: #2BA3FF;
+  text-align: center;
+  line-height: 70px;
+}
+.loginForm {
+  flex: 1;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-end;
+  padding-right: 50px;
+}
+>>> .ivu-form-item {
+  margin-bottom: 25px;
+}
+.login-input {
+ width: 378px;
+ height: 58px;
+ border: 1px solid #5DB5FC;
+}
+>>> .ivu-form-item-error .login-input {
+  border: 1px solid #ed4014;
+}
+>>> .ivu-input-icon {
+  height: 56px;
+  line-height: 56px;
+}
+>>> .ivu-input-prefix, .ivu-input-suffix {
+  width: 58px;
+  background: #064CAC;
+}
+>>> .ivu-input-prefix i, .ivu-input-suffix i {
+   line-height: 56px;
+   color: #fff;
+   font-size: 28px;
+}
+>>> .ivu-input {
+  height: 56px;
+  border-radius: 0;
+  background-color: rgba(0, 0, 0, 0.2);
+  border: 1px solid transparent;
+  color: #F5F5F5;
+}
+>>> .ivu-input-with-prefix {
+  padding-left: 70px;
+}
+ >>> input:-webkit-autofill , textarea:-webkit-autofill, select:-webkit-autofill {
+	-webkit-text-fill-color: #fff !important;
+	-webkit-box-shadow: 0 0 0px 1000px transparent  inset !important;
+  background-color: rgba(0, 0, 0, 0.2);
+  background-image: none;
+  transition: background-color 50000s ease-in-out 0s; //背景色透明  生效时长  过渡效果  启用时延迟的时间
+}
+/deep/ .ivu-input::-webkit-input-placeholder{
+  color: #285EC7;
+}
+/deep/ .ivu-input::-moz-placeholder{   /* Mozilla Firefox 19+ */
+  color: #285EC7;
+}
+/deep/ .ivu-input::-moz-placeholder{    /* Mozilla Firefox 4 to 18 */
+  color: #285EC7;
+}
+/deep/ .ivu-input::-ms-input-placeholder{  /* Internet Explorer 10-11 */
+  color: #285EC7;
+}
+.login-btn {
+  width: 378px;
+  height: 60px;
+  background: #0055D4;
+  border-radius: 6px;
+  font-size: 26px;
+  color: #B5E1F7;
+  margin-top: 5px;
+}
+>>> .ivu-btn-primary:hover {
+  background-color: #076fbe;
+}
 </style>

+ 2 - 2
src/main.js

@@ -1,13 +1,13 @@
 import Vue from 'vue'
 import App from './App.vue'
 import router from './router'
+import './libs/flexible.js'; //自适应方案核心: 阿里可伸缩布局方案 lib-flexible px转rem:px2rem,它有webpack的px2rem-loader 这两项加起来可以实现PC端分辨率适配
 import ViewUI from 'view-design';
 import 'view-design/dist/styles/iview.css';
 import './assets/styles/common.css';
-import './assets/iconfont/iconfont.css'
+import './assets/iconfont/iconfont.css';
 import store from './store'
 // import 'lib-flexible'
-import './libs/flexible.js' //自适应方案核心: 阿里可伸缩布局方案 lib-flexible px转rem:px2rem,它有webpack的px2rem-loader 这两项加起来可以实现PC端分辨率适配
 import {get,post,patch,put} from './libs/http.js';
 //定义全局变量
 Vue.prototype.$post = post

+ 87 - 8
src/router/index.js

@@ -6,6 +6,13 @@ const Login = ()=>import("@/login/Login.vue")
 const MainPage = ()=>import('@/views/MainPage.vue')
 const HomePage = ()=>import('@/views/homecomponents/HomePage.vue')
 const EquipmentMonitor = ()=>import('@/views/homecomponents/EquipmentAnalysis/EquipmentMonitor.vue')
+const AlarmMonitor = ()=>import('@/views/homecomponents/EquipmentAnalysis/AlarmMonitor.vue')
+const AlarmHandling = ()=>import('@/views/homecomponents/EquipmentAnalysis/AlarmHandling.vue')
+const LineStationManage = ()=>import('@/views/homecomponents/BasicInfomation/LineStationManage.vue')
+const ApplicationManage = ()=>import('@/views/homecomponents/BasicInfomation/ApplicationManage.vue')
+const DeviceManage = ()=>import('@/views/homecomponents/BasicInfomation/DeviceManage.vue')
+const InstruManage = ()=>import('@/views/homecomponents/BasicInfomation/InstruManage.vue')
+const OperaTimeManage = ()=>import('@/views/homecomponents/BasicInfomation/OperaTimeManage.vue')
 Vue.use(VueRouter)
 
 const routes = [
@@ -18,13 +25,13 @@ const routes = [
     path: '/MainPage',
     component: MainPage,
     meta: { Auth: true }, // 添加该字段,表示进入这个路由是需要登录的
-    // beforeEnter: (to, from, next) => {
-    //   if (!utils.storage('sw_user')) {
-    //     next({ path: '/login' })
-    //     return false
-    //   }
-    //   next()
-    // },
+    beforeEnter: (to, from, next) => {
+      if (!utils.storage('sw_user')) {
+        next({ path: '/login' })
+        return false
+      }
+      next()
+    },
     children: [
       // 首页
       {
@@ -38,6 +45,57 @@ const routes = [
         name: 'EquipmentMonitor', 
         component: EquipmentMonitor
       },
+      {
+        path: 'AlarmMonitor', 
+        name: 'AlarmMonitor', 
+        component: AlarmMonitor
+      },
+      {
+        path: 'AlarmHandling', 
+        name: 'AlarmHandling', 
+        component: AlarmHandling
+      },
+      // 基础信息
+      {
+        path: 'LineStationManage', 
+        name: 'LineStationManage', 
+        component: LineStationManage
+      },
+      {
+        path: 'ApplicationManage', 
+        name: 'ApplicationManage', 
+        component: ApplicationManage
+      },
+      {
+        path: 'DeviceManage', 
+        name: 'DeviceManage', 
+        component: DeviceManage
+      },
+      {
+        path: 'InstruManage', 
+        name: 'InstruManage', 
+        component: InstruManage
+      },
+      {
+        path: 'OperaTimeManage', 
+        name: 'OperaTimeManage', 
+        component: OperaTimeManage
+      },
+      // {
+      //   path: 'BasicInfomation',
+      //   component: BasicInfomation,
+      //   children: [{
+      //     path: '',
+      //     name: 'StationManage',
+      //     component: StationManage
+      //   },
+      //   {
+      //     path: 'employee_search',
+      //     name: 'MoreSearch',
+      //     component: MoreSearch
+      //   }
+      //   ]
+      // },
     ]
   },
   { path: '*', redirect: '/' }
@@ -46,5 +104,26 @@ const routes = [
 const router = new VueRouter({
   routes
 })
-
+//全局前置守卫
+router.beforeEach(function (to, from, next) {
+  const isAuth = to.matched.some(m => m.meta.Auth)
+  if (isAuth) {
+    const isLogin = utils.storage('sw_user')
+    if (!isLogin) {
+      next({path: '/login'})
+    }
+    // window._axiosPromiseArr.forEach((ele,index) => {
+    //   ele.cancel() // 路由跳转之前,清空(终止)上一个页面正在请求的内容
+    //   // 清空请求的参数 清空请求的参数
+    //   delete window._axiosPromiseArr[index]
+    // })
+  }
+  next()
+})
+// 解决 Vue 重复点击相同路由 出现 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation 问题
+const originalPush = VueRouter.prototype.push
+VueRouter.prototype.push = function push(location, onResolve, onReject) {
+ if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
+ return originalPush.call(this, location).catch(err => err)
+}
 export default router

+ 50 - 11
src/views/MainPage.vue

@@ -1,10 +1,10 @@
 <template>
-  <div class="container">
-    <Head></Head>
+  <div class="page-container">
+    <Head @listenMenuId="getMenuId"></Head>
     <div class="container-bottom">
-      <Nav></Nav>
-      <Content></Content>
-      <!-- <home-page></home-page> -->
+      <Nav :menuId="menuId" v-show="menuId"></Nav>
+      <Content v-if="menuId"></Content>
+      <home-page v-if="!menuId "></home-page>
     </div>
   </div>
 </template>
@@ -20,19 +20,58 @@ export default {
   },
   data() {
     return {
+      menuId: 0,
+      menuName: []
     };
   },
+  watch: {
+    // 菜单头部浏览器前进或后退首页隐藏左边菜单
+    '$route' (to, from) {
+      if (to.path == '/mainPage') {
+        this.menuId = 0
+      }
+    }
+  },
   mounted() {
   },
   methods: {
-   
+   getMenuId: function(id,arr) {
+      this.menuId = id;
+      // if (menuName) {
+      //   this.menuName.push(menuName)
+      //   console.log('数组',this.menuName)
+      // }
+      sessionStorage.setItem('id', id);
+    },
+    getMenuName (arr) {
+      console.log(arr)
+      // this.menuName = arr
+    }
   }
 };
 </script>
 <style scoped lang="stylus">
-// .container-bottom {
-//   display: 1;
-//   display: flex;
-//   width: 100%;
-// }
+.page-container {
+  width: 100%;
+  height: 100%;
+}
+.container-bottom {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  height: calc(100% - 90px);
+  // height: 100%;
+}
+/deep/ .ivu-input::-webkit-input-placeholder{
+  color: #285EC7;
+}
+/deep/ .ivu-input::-moz-placeholder{   /* Mozilla Firefox 19+ */
+  color: #285EC7;
+}
+/deep/ .ivu-input::-moz-placeholder{    /* Mozilla Firefox 4 to 18 */
+  color: #285EC7;
+}
+/deep/ .ivu-input::-ms-input-placeholder{  /* Internet Explorer 10-11 */
+  color: #285EC7;
+}
 </style>

+ 488 - 0
src/views/homecomponents/BasicInfomation/ApplicationEquip.vue

@@ -0,0 +1,488 @@
+<template>
+  <div class="content-main common-scroll">
+    <div class="content-body">
+      <Row :gutter="8" style="width:100%;height:100%">
+        <i-col span="6" style="height:100%">
+          <div class="station-tree">
+            <div class="station-tree-body">
+              <div class="station-tree-top">
+                <Input suffix="ios-search" placeholder="请输入地铁站台名" search v-model="currentStation" class="common-search"  @on-search="iconChange"/>
+              </div>
+              <div class="station-tree-center">
+                <div class="station-tree-left common-scroll" v-show="showTree">
+                  <tree-list :defaultData="stationData" :currentStaData="currentStaData" :clickAllNode="true" v-if="stationData.length>0" @treeChange="treeChange" ref="tree"></tree-list>
+                </div>
+                <div class="station-tree-left-notree" v-show="!showTree">
+                  站点输入错误!
+                </div>
+                <div class="station-tree-right">
+                </div>
+              </div>
+            </div>
+          </div>
+        </i-col>
+        <i-col span="18" style="height:100%">
+          <div class="right-main">
+            <div class="manage-main-top">
+              <Button icon="ios-add" class="common-add-btn" @click="addClick">新增关联</Button>
+            </div>
+            <div class="manage-main-center">
+              <Table :columns="columns" :data="data1" class="common-table" :row-class-name="rowClassName"></Table>
+            </div>
+            <Page :total="tableTotal" :current="tableParams.pageNum" :page-size="tableParams.pageSize" @on-change="changePage" @on-page-size-change="sizeChange" show-elevator class="common-page"/>
+          </div>
+        </i-col>
+      </Row>
+    </div>
+     <Modal
+      v-model="showModal"
+      :title="title"
+      width="25"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <!-- :rules="ruleValidate"  -->
+      <Form class="common-form" ref="formOption" :model="formOption" :label-width="120">
+				<FormItem label="应用名称:" prop="lineName">
+           <Select v-model="formOption.lineName" placeholder="应用名称">
+              <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+				</FormItem>
+				<FormItem label="设备类型:" prop="stationName">
+           <Select v-model="formOption.station" placeholder="设备类型">
+              <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+        </FormItem>
+			</Form>
+      <div slot="footer">
+          <Button @click="modalCancel">取消</Button>
+          <Button type="primary" @click="modalOk">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="modalStatus"
+      title="确认解绑"
+      width="25"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <Icon type="ios-information-circle" class="modal-icon"  style="color:#E92E2E"></Icon>
+      <span class="modal-text">删除的同时将解绑所有运营数据,且数据不可恢复。请慎重操作。</span>
+      <div slot="footer">
+          <Button @click="commonCancel">取消</Button>
+          <Button type="primary" @click="commonOk">确定</Button>
+        </div>
+    </Modal>
+</div>
+</template>
+<script>
+import _ from 'lodash'
+export default {
+  name: "ApplicationEquip",
+  components:{
+  },
+  data() {
+    return {
+      currentStation: '合肥轨道交通',
+      currentStaData: [], // 当前搜索框搜索的站台数组对象,传给子组件,用来判断单选站台名当前选中状态
+      treeName: ['合肥轨道交通'], // 当前选中的一级二级站台名
+      preTreeName:['合肥轨道交通'],
+      showTree: true,// 是否显示树形组件
+		  stationData: [{disabled: true,
+        expand: true,
+        children: [],
+        id: 0,
+        parent: null,
+        selected: true,
+        stationId: null,}],
+        tableTotal: 100,
+        tableParams: {
+          pageNum: 1,
+          pageSize: 20
+        },
+        data1: [
+          {
+              name: 'John Brown',
+              age: 1,
+              address: 'New York No.',
+              date: '2016-10-03'
+          },
+          {
+              name: 'Jim Green',
+              age: 2,
+              address: 'London No.',
+              date: '2016-10-01'
+          },
+          {
+              name: 'Joe Black',
+              age: 3,
+              address: 'Sydney No.',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon Snow',
+              age: 2,
+              address: 'Ottawa No.',
+              date: '2016-10-04'
+          },
+          {
+              name: 'John Brown',
+              age: 1,
+              address: 'New York No.',
+              date: '2016-10-03'
+          },
+          {
+              name: 'Jim Green',
+              age: 2,
+              address: 'London No.',
+              date: '2016-10-01'
+          },
+          {
+              name: 'Joe Black',
+              age: 3,
+              address: 'Sydney No.',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon Snow',
+              age: 2,
+              address: 'Ottawa No.',
+              date: '2016-10-04'
+          },
+            {
+              name: 'Joe Black',
+              age: 3,
+              address: 'Sydney No',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon Snow',
+              age: 2,
+              address: '合肥城市轨道交通有限公司',
+              date: '2016-10-04'
+          },
+      ],
+      columns: [
+          {
+            title: '线路序号',
+            width: 100,
+            key: 'name',
+            align: 'center'
+          },
+          {
+            title: '线路名称',
+            key: 'age',
+            width: 100,
+            align: 'center'
+          },
+          {
+            title: '当前线路长度(km)',
+            key: 'address',
+            align: 'center'
+          },
+          {
+            title: '站点数量',
+            key: 'name',
+           align: 'center'
+          },
+          {
+            title: '运营机构',
+            key: 'address',
+            align: 'center',
+            ellipsis: true,
+            tooltip: true
+          },
+          {
+            title: '线路类型',
+            key: 'address',
+            align: 'center'
+          },
+          { title: "操作", key: "action", align: 'center',
+            render: (h, params) => {
+              return h('div',[
+                h('Tooltip', {
+                  props: { placement: 'top' },
+                }, [
+                    h('span', { slot: 'content', style: { whiteSpace: 'normal', wordBreak: 'break-all' } },'解绑'),
+                    h('i',{style: { cursor:'pointer',color:'#B8B532',fontSize:'20px',marginRight:'6px'},
+                      on: {
+                          click: () => {
+                            this.modalStatus = true
+                          }
+                        },
+                    class: 'iconfont icon-xiangqingmingxi'})]),       
+              ])
+            }
+          },
+      ],
+      formOption: {lineName: '',stationName:''},
+      typeList: [
+        {
+            value: 'New York',
+            label: 'New York'
+        },
+        {
+            value: 'London',
+            label: 'London'
+        },
+        {
+            value: 'Sydney',
+            label: 'Sydney'
+        },
+        {
+            value: 'Ottawa',
+            label: 'Ottawa'
+        },
+        {
+            value: 'Paris',
+            label: 'Paris'
+        },
+        {
+            value: 'Canberra',
+            label: 'Canberra'
+        }
+    ],
+    showModal: false,
+    title: '新增关联',
+    modalStatus: false,
+    };
+  },
+  mounted() {
+    this.$get('metroapi/equipment/energy/stationTree').then(res => {
+      if (res.httpCode == 1) {
+        this.stationData[0].children = this.getTree(res.data)
+        this.currentStaData = [{disabled: true,
+          expand: true,
+          children: [],
+          id: 0,
+          parent: null,
+          selected: true,
+          stationId: null,
+          title: "合肥轨道交通"}]
+      } else {
+        this.stationData = [{disabled: true,
+        expand: true,
+        children: [],
+        id: 0,
+        parent: true,
+        selected: true,
+        stationId: null,
+        title: "合肥轨道交通"}]
+      }
+		})
+  },
+  methods: {
+    getTree(arr) {
+      return arr.map((v,index) => {
+        v.disabled = false
+        v.selected = false
+        v.expand = false
+        if (v.title == '1号线') {
+          v.expand = true
+        }
+        if (v.children) v.children = this.getTree(v.children);
+        return v;
+      });
+    },
+    iconChange: _.throttle(function() {
+      this.currentStaData = []
+      this.treeName = []
+      this.showTree = false		
+      if(this.currentStation != ''){
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部
+      } else {
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部   
+      }
+      this.getPamData (this.currentStation)
+      this.stationData.forEach((item, index,itemArr) => {
+        item.expand = false;
+        item.disabled = false; 
+        item.selected = false;
+        if (item.title == this.currentStation) {
+            item.selected = true;
+            item.disabled = true; // disabled 是否禁止选中 
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.currentStaData.push(item)
+            this.preTreeName = this.treeName
+            this.showTree = true
+        }
+        item.children.forEach((val, i,valArr) => {
+          val.expand = false; //expand 是否展开直子节点 
+          val.disabled = false; // disabled 是否禁止选中
+          val.selected = false;
+          if (val.title == this.currentStation) {
+            val.selected = true;
+            val.disabled = true; // disabled 是否禁止选中 
+            val.expand = true;
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.treeName.push(val.title)
+            this.currentStaData.push(val)
+            this.preTreeName = this.treeName
+            this.showTree = true
+          }
+          val.children.forEach ((lastVal,lastIndex) => {
+            lastVal.selected = false; //expand 是否展开直子节点 
+            lastVal.disabled = false; 
+            lastVal.expand = false;
+            if (this.currentStation =='合肥轨道交通' || this.currentStation =='') {
+              itemArr[index].selected = true
+              itemArr[index].disabled = true
+              itemArr[index].expand = true
+              valArr[index].expand = true
+              this.showTree = true
+              this.currentStation = '合肥轨道交通'
+              this.treeName = ['合肥轨道交通']
+            }
+            if (lastVal.title == this.currentStation) {
+              lastVal.selected = true;
+              lastVal.disabled = true; // disabled 是否禁止选中 
+              lastVal.expand = true;
+              val.expand = true
+              item.expand = true
+              this.treeName.push(item.title)
+              this.treeName.push(val.title)
+              this.treeName.push(lastVal.title)
+              this.currentStaData.push(lastVal)
+              this.preTreeName = this.treeName
+              this.showTree = true
+            } 
+          })
+        });
+      });		
+      if (!this.showTree) {
+        this.treeName = this.preTreeName
+      }
+      this.$nextTick(()=> {
+        if (this.initActive == 'year') {
+          this.$refs.longForecast.getTitle(this.pamData)
+        } else {
+          this.$refs.forecast.getTitle(this.pamData)
+        }
+      })
+		}, 500),
+    treeChange(val,arr) {
+      this.currentStation = val
+      this.treeName = arr
+      this.preTreeName = arr
+		},
+     rowClassName(row, index) {
+      if (index % 2 == 0) {
+        return "ivu-table-stripe-even";
+      } else {
+        return "ivu-table-stripe-odd";
+      }
+    },
+    // 分页
+    changePage (val) {
+      this.tableParams.pageNum = val
+      // this.getTableData()
+    },
+    //跳转
+    sizeChange (val) {
+      this.tableParams.pageSize = val
+      // this.getTableData()
+    },
+    addClick () {
+      this.showModal = true
+      this.$refs.modalGrag.dragData.x = null
+      this.$refs.modalGrag.dragData.y = null
+    },
+    modalOk () {
+      this.showModal = false
+    },
+    modalCancel () {
+      this.showModal = false
+    },
+    commonOk () {
+      this.modalStatus = false
+    },
+    commonCancel () {
+      this.modalStatus = false
+    },
+  }
+};
+</script>
+<style scoped lang="stylus">
+.content-main {
+  width: 100%;
+  height: calc(100% - 50px);
+  overflow: auto;
+}
+.common-search {
+  width: 100%;
+}
+>>> .common-search .ivu-input {
+  background-color: #06214D;
+  border: 1px solid #2355A6;
+  border-radius: 15px;
+  color: #fff;
+  height: 32px;
+}
+>>> .common-search .ivu-input:focus {
+    border-color: #0185ea;
+}
+.content-body {
+  width: 100%;
+  height: 100%;
+  background: #06214D;
+}
+.station-tree {
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-body {
+  border: 1px solid #204384;
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-center {
+  height: calc(100% - 32px);
+  padding-top: 10px;
+  // display: flex;
+}
+.station-tree-left {
+  height: 100%;
+  overflow: hidden;
+  overflow-y: auto;
+}
+.station-tree-left-notree {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #fff;
+  fon-size: 14px;
+}
+.right-main {
+  height: 100%;
+  padding: 10px 0;
+  // padding: 16px;
+}
+.manage-main-top {
+  padding: 12px 0;
+  display: flex;
+  justify-content: flex-end;
+}
+.manage-main-center {
+  width: 100%;
+  height: calc(100% - 100px);
+}
+.common-table {
+  max-height: 100%;
+}
+>>> .common-table .ivu-table th {
+  height: 54px;
+ }
+ >>> .common-table .ivu-table td {
+  height: 54px;
+ }
+.common-page {
+  margin-top: 15px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 53 - 0
src/views/homecomponents/BasicInfomation/ApplicationManage.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="content-main">
+    <div class="content-body-wrap">
+     <div class="content-body">
+        <Tabs :value="currentTabs" @on-click="tabsClick" class="common-tabs">
+          <TabPane v-for="tab in tabsData" :key="tab.label" :label="tab.label" :name="tab.label"></TabPane>
+        </Tabs>
+        <application-station v-show="currentTabs == '应用管理'"></application-station>
+        <application-equip v-show="currentTabs == '应用-设备类型关联'"></application-equip>
+     </div>
+    </div>
+  </div>
+</template>
+<script>
+import ApplicationStation from './ApplicationStation.vue'
+import ApplicationEquip from './ApplicationEquip.vue'
+export default {
+  name: "ApplicationManage",
+   components:{
+    ApplicationStation,ApplicationEquip
+  },
+  data() {
+    return {
+      tabsData: [{label:'应用管理'},{label:'应用-设备类型关联'}],
+      currentTabs: '应用管理',
+    };
+  },
+  mounted() {
+  },
+  methods: {
+    tabsClick (name) {
+      this.currentTabs = name
+    },
+  }
+};
+</script>
+<style scoped lang="stylus">
+.content-main {
+  width: 100%;
+  height: calc(100% - 50px);
+  overflow: auto;
+}
+.content-body-wrap {
+  width: 100%;
+  height: 100%;
+  background: #06214D;
+}
+.content-body {
+  width: 100%;
+  height: 100%;
+  padding: 10px;
+}
+</style>

+ 546 - 0
src/views/homecomponents/BasicInfomation/ApplicationStation.vue

@@ -0,0 +1,546 @@
+<template>
+  <div>
+    <div class="search-list">
+      <div class="search-left">
+      <Select v-model="tableParams.level" placeholder="层级">
+          <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+      </Select>
+      <Select v-model="tableParams.lineName" placeholder="线路">
+          <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+      </Select>
+      <Select v-model="tableParams.stationName" placeholder="站点">
+          <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+      </Select>
+      <Select v-model="tableParams.equipmentCheck" placeholder="接入设备">
+          <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+      </Select>
+      <Select v-model="tableParams.instrumentCheck" placeholder="接入仪表">
+          <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+      </Select>
+      <Button type="primary" class="common-btn-search">
+        <Icon type="ios-search" style="margin-right:4px;font-size: 16px"/> 筛选
+      </Button>  
+    </div>
+      <div class="btn-container">
+        <Button icon="ios-add" class="common-add-btn" @click="addClick">新增线路</Button>
+      </div>
+    </div>
+    <div class="manage-main-center">
+      <Table :columns="columns" :data="data1" class="common-table" :row-class-name="rowClassName"></Table>
+    </div>
+    <Page :total="tableTotal" :current="tableParams.pageNum" :page-size="tableParams.pageSize" @on-change="changePage" @on-page-size-change="sizeChange" show-elevator class="common-page"/>
+    <Modal
+      v-model="showModal"
+      :title="title"
+      width="34"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <!-- :rules="ruleValidate"  -->
+      <Form class="common-form" ref="formOption" :model="formOption" :label-width="120">
+				<FormItem label="归属线路:" prop="lineName">
+           <Select v-model="formOption.lineName" placeholder="线路">
+              <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+				</FormItem>
+				<FormItem label="归属站点:" prop="stationName">
+           <Select v-model="formOption.station" placeholder="线路">
+              <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+        </FormItem>
+        <FormItem label="应用ID:" prop="station">
+          <span v-show="title=='新增应用'">系统自动生成,唯一不重复</span>
+          <span v-show="title=='编辑应用'"></span>
+        </FormItem>
+        <FormItem label="应用名称:" prop="station">
+          <Input v-model="formOption.station" maxlength="100" show-word-limit />  
+        </FormItem>
+        <FormItem label="层级:" prop="station">
+          <Select v-model="formOption.station" placeholder="线路">
+              <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
+          </Select>
+        </FormItem>
+        <FormItem label="服务器名称:" prop="station">
+          <Input v-model="formOption.station" maxlength="20" show-word-limit />  
+        </FormItem>
+        <FormItem label="IP地址:" prop="station" v-show="title == '新增线路'">
+          <Input v-model="formOption.station" /> 
+        </FormItem>
+			</Form>
+      <div slot="footer">
+          <Button @click="modalCancel">取消</Button>
+          <Button type="primary" @click="modalOk">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="modalStatus"
+      :title="commonTitle"
+      width="30"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <Icon type="ios-information-circle" :style="{ color: activeColor}" class="modal-icon"></Icon>
+      <span class="modal-text">{{modalTitle}}</span>
+      <div slot="footer">
+          <Button @click="commonCancel">取消</Button>
+          <Button type="primary" @click="commonOk">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="detailStatus"
+      title="应用详情"
+      width="45"
+      ref="modalGrag"
+      draggable
+      footer-hide
+      :mask-closable="false"
+      class-name="common-modal">
+       <Tabs :value="currentModalTabs" @on-click="tabsClick" class="common-tabs">
+        <TabPane v-for="tab in tabsModalData" :key="tab.label" :label="tab.label" :name="tab.label"></TabPane>
+      </Tabs>
+        <div v-if="currentModalTabs =='基础信息'" class="modal-tabs-item">
+          <div v-for="(item,index) in detailLabel" :key="index">
+          <div class="common-modal-content">
+            <div class="modal-content-item" v-for="(val,i) in item.arr" :key="i" :class="{'modal-content-item-last': val.name == '说明'}">
+              <span class="modal-content-item-name">
+              {{val.name}}
+              </span>
+              <span class="modal-content-item-value">4号线</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <Table :columns="columns" :data="data1" class="common-table modal-tabs-item" :row-class-name="rowClassName" v-if="currentModalTabs =='关联设备类型'"></Table>
+      <Table :columns="columns" :data="data1" class="common-table modal-tabs-item" :row-class-name="rowClassName" v-if="currentModalTabs =='关联仪表类型'"></Table>
+    </Modal>
+  </div>
+</template>
+<script>
+export default {
+  name: "ApplicationStation",
+  components:{
+  },
+  data() {
+    return {
+       tableParams: {
+        level: '',
+        lineName: '',
+        stationName: '',
+        equipmentCheck: '',
+        instrumentCheck: '',
+        pageSize: 1,
+        pageNum: 10
+      },
+      tableTotal: 100,
+      cityList: [
+          {
+              value: 'New York',
+              label: 'New York'
+          },
+          {
+              value: 'London',
+              label: 'London'
+          },
+          {
+              value: 'Sydney',
+              label: 'Sydney'
+          },
+          {
+              value: 'Ottawa',
+              label: 'Ottawa'
+          },
+          {
+              value: 'Paris',
+              label: 'Paris'
+          },
+          {
+              value: 'Canberra',
+              label: 'Canberra'
+          }
+      ],
+       data1: [
+          {
+              name: 'John',
+              age: 1,
+              address: 'New York No.',
+              date: '2016-10-03'
+          },
+          {
+              name: 'Jim',
+              age: 2,
+              address: 'London No.',
+              date: '2016-10-01'
+          },
+          {
+              name: 'Joe',
+              age: 3,
+              address: 'Sydney No.',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon',
+              age: 2,
+              address: 'Ottawa No.',
+              date: '2016-10-04'
+          },
+          {
+              name: 'John',
+              age: 1,
+              address: 'New York No.',
+              date: '2016-10-03'
+          },
+          {
+              name: 'Jim',
+              age: 2,
+              address: 'London No.',
+              date: '2016-10-01'
+          },
+          {
+              name: 'Joe',
+              age: 3,
+              address: 'Sydney No.',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon',
+              age: 2,
+              address: 'Ottawa No.',
+              date: '2016-10-04'
+          },
+            {
+              name: 'Joe',
+              age: 3,
+              address: 'Sydney No',
+              date: '2016-10-02'
+          },
+          {
+              name: 'Jon',
+              age: 2,
+              address: '合肥城市轨道交通有限公司',
+              date: '2016-10-04'
+          },
+      ],
+      columns: [
+          {
+            title: '线路序号',
+            width: 100,
+            key: 'name',
+            align: 'center'
+          },
+          {
+            title: '线路名称',
+            key: 'age',
+            width: 100,
+            align: 'center'
+          },
+          {
+            title: '当前线路长度(km)',
+            key: 'address',
+            align: 'center'
+          },
+          {
+            title: '站点数量',
+            key: 'name',
+           align: 'center'
+          },
+          {
+            title: '运营机构',
+            key: 'address',
+            align: 'center',
+            ellipsis: true,
+            tooltip: true
+          },
+          {
+            title: '线路类型',
+            key: 'address',
+            align: 'center'
+          },
+           {
+            title: '启用状态',
+            key: 'age',
+            align: 'center',
+            width: 120,
+            render: (h, params) => {
+            const parisEnb = params.row.age == 1 ? true:false
+              return h('div', [                             
+                h('i-switch', {
+                  props: { value: parisEnb,'true-color': '#57C44F',
+                  },
+                  on: {
+                    input: function (event) { 
+                      console.log(event)
+                      params.row.isEnabled = event 
+                    },
+                    'on-change': (val)=> {
+                      console.log(params.row)
+                      console.log('click')
+                    }
+                  },
+                  nativeOn:{
+                      "mousedown":(event)=>{ // 监听组件原生事件mousedown,此事件在click之前触发
+                       console.log(params.row)
+                       this.rowObj =  params.row
+                      if (!parisEnb) {
+                        this.commonTitle = '确认启用'
+                        this.activeColor = '#57C44F'
+                        this.activeClass = 'icon-qiyong'
+                        this.modalTitle = '启用后此线路统计数据将在各管理模块及前端显示页面生效。'
+                        this.modalStatus = true
+                      } else {
+                        this.commonTitle = '确认关闭'
+                        this.activeColor = '#E92E2E'
+                        this.activeClass = 'icon-guanbi'
+                        this.modalTitle = '关闭后线路下所有站点将同时关闭,线路及站点统计数据不可见。'
+                        this.modalStatus = true
+                      }
+                        // thatValue.switchOneInfo = {
+                        //   name:params.row.name,
+                        //   is_show:params.row.is_show
+                        // }
+                      },
+                    }
+                }),
+              ])
+            }
+          },
+          { title: "操作", key: "action", align: 'center',
+            render: (h, params) => {
+              return h('div',[
+                h('Tooltip', {
+                  props: { placement: 'top' },
+                }, [
+                    h('span', { slot: 'content', style: { whiteSpace: 'normal', wordBreak: 'break-all' } },'详情'),
+                    h('i',{style: { cursor:'pointer',color:'#B8B532',fontSize:'20px',marginRight:'6px'},
+                      on: {
+                          click: () => {
+                            this.detailStatus = true
+                          }
+                        },
+                    class: 'iconfont icon-xiangqingmingxi'})]),
+                h('Tooltip', {
+                  props: { placement: 'top' },
+                }, [
+                h('span', { slot: 'content', style: { whiteSpace: 'normal', wordBreak: 'break-all' } },'编辑'),
+                h('i',{style: { cursor:'pointer',color:'#64ACFE',fontSize:'20px',marginRight:'6px'},
+                  on: {
+                      click: () => {
+                        this.title = '编辑应用'
+                        this.showModal = true
+                      }
+                    },
+                class: 'iconfont icon-bianji'})]),
+                h('Tooltip', {
+                  props: { placement: 'top' },
+                }, [
+                h('span', { slot: 'content', style: { whiteSpace: 'normal', wordBreak: 'break-all' } },'编辑'),
+                h('i',{style: { cursor:'pointer',color:'#E92E2E',fontSize:'20px',marginRight:'6px'},
+                  on: {
+                      click: () => {
+                        this.commonTitle = '确认删除'
+                        this.modalTitle = '只能删除没有关联设备类型和仪表类型的应用,删除不影响已产生的操作和记录。'
+                        this.modalStatus = true
+                      }
+                    },
+                class: 'iconfont icon-shanchu'}),                  
+                ])        
+              ])
+            }
+          },
+      ],
+      typeList: [
+          {
+              value: 'New York',
+              label: 'New York'
+          },
+          {
+              value: 'London',
+              label: 'London'
+          },
+          {
+              value: 'Sydney',
+              label: 'Sydney'
+          },
+          {
+              value: 'Ottawa',
+              label: 'Ottawa'
+          },
+          {
+              value: 'Paris',
+              label: 'Paris'
+          },
+          {
+              value: 'Canberra',
+              label: 'Canberra'
+          }
+      ],
+      tableTotal: 100,
+      showModal: false,
+      detailStatus: false, 
+      modalStatus: false,
+      title: '新增线路',
+      commonTitle: "确认删除",
+      activeColor: '#E92E2E',
+      activeClass: '',
+      modalTitle: '',
+      formOption: {line: null,station: null,equipmentName: 1,type:'',switch:false},
+      ruleValidate: {
+        line: [{
+          type: 'number',
+          message: '请选择线路',
+          trigger: 'change'
+        }],
+        station: [{
+          required: true,
+          type: 'number',
+          message: '请选择站点',
+          trigger: 'change'
+        }]
+      }, 
+      currentModalTabs:'基础信息',
+      tabsModalData: [{label:'基础信息'},{label:'关联设备类型'},{label:'关联仪表类型'}],
+      detailLabel: [{name:'基础信息',arr:[{name: '线路名称',value:0},{name: '线路序号',value:0},{name: '上级节点',value:0},{name: '启用状态',value:0},{name: '运营机构',value:0},{name: '线路类型',value:0},{name: '说明',value:0}]}]
+    };
+  },
+  mounted() {
+  },
+  methods: {
+    rowClassName(row, index) {
+      if (index % 2 == 0) {
+        return "ivu-table-stripe-even";
+      } else {
+        return "ivu-table-stripe-odd";
+      }
+    },
+    // 分页
+    changePage (val) {
+      this.tableParams.pageNum = val
+      // this.getTableData()
+    },
+    //跳转
+    sizeChange (val) {
+      this.tableParams.pageSize = val
+      // this.getTableData()
+    },
+    addClick () {
+      this.title = '新增应用'
+      this.showModal = true
+      this.$refs.modalGrag.dragData.x = null
+      this.$refs.modalGrag.dragData.y = null
+    },
+    modalOk () {
+      this.showModal = false
+    },
+    modalCancel () {
+      this.showModal = false
+    },
+    commonOk () {
+      this.modalStatus = false
+    },
+    commonCancel () {
+      this.modalStatus = false
+    },
+    tabsClick (name) {
+      this.currentModalTabs = name
+    }
+    
+  }
+};
+</script>
+<style scoped lang="stylus">
+.search-list {
+  display: flex;
+  justify-content: space-between;
+  padding: 10px 0;
+}
+.search-left {
+  display: flex;
+  align-items: center;
+   .ivu-select {
+     width: 160px;
+     padding-right: 10px;
+     height: 32px;
+   }
+   .ivu-select-single .ivu-select-selection {
+     height: 100%;
+   }
+}
+.manage-main-center {
+  width: 100%;
+  height: calc(100% - 150px);
+}
+.common-table {
+  max-height: 100%;
+}
+>>> .common-table .ivu-table th {
+  height: 56px;
+ }
+ >>> .common-table .ivu-table td {
+  height: 55.5px;
+ }
+.common-page {
+  margin-top: 15px;
+  display: flex;
+  justify-content: flex-end;
+}
+>>> .modal-tabs-item {
+  margin-top: 10px;
+}
+>>> .common-modal-content {
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  margin-bottom: 15px;
+  border-right: 1px solid #21437B;
+}
+>>> .modal-content-item {
+  width: 50%;
+  display: flex;
+}
+>>> .modal-content-item-last {
+  width: 100%;
+}
+>>> .modal-content-item-name {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #13305F;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-value {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #06214D;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-last .modal-content-item-name{
+  width: 25%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+}
+>>> .modal-content-item-last .modal-content-item-value{
+  width: 75%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+  line-height: 22px;
+}
+</style>

+ 246 - 0
src/views/homecomponents/BasicInfomation/DeviceManage.vue

@@ -0,0 +1,246 @@
+<template>
+ <div class="content-main common-scroll">
+    <div class="content-body">
+      <Row :gutter="8" style="width:100%;height:100%">
+        <i-col span="6" style="height:100%">
+          <div class="station-tree">
+            <div class="station-tree-body">
+              <div class="station-tree-top">
+                <Input suffix="ios-search" placeholder="请输入地铁站台名" search v-model="currentStation" class="common-search"  @on-search="iconChange"/>
+              </div>
+              <div class="station-tree-center">
+                <div class="station-tree-left common-scroll" v-show="showTree">
+                  <tree-list :defaultData="stationData" :currentStaData="currentStaData" :clickAllNode="true" v-if="stationData.length>0" @treeChange="treeChange" ref="tree"></tree-list>
+                </div>
+                <div class="station-tree-left-notree" v-show="!showTree">
+                  站点输入错误!
+                </div>
+                <div class="station-tree-right">
+                </div>
+              </div>
+            </div>
+          </div>
+        </i-col>
+        <i-col span="18" style="height:100%">
+          <div class="right-main">
+            <Tabs :value="currentTabs" @on-click="tabsClick" class="common-tabs">
+              <TabPane v-for="tab in tabsData" :key="tab.label" :label="tab.label" :name="tab.label"></TabPane>
+            </Tabs>
+            <line-manage></line-manage>
+          </div>
+        </i-col>
+      </Row>
+    </div>
+  </div>
+</template>
+<script>
+import _ from 'lodash'
+import LineManage from './LineManage.vue'
+export default {
+  name: "DeviceManage",
+  components:{
+    LineManage
+  },
+  data() {
+    return {
+      currentStation: '合肥轨道交通',
+      currentStaData: [], // 当前搜索框搜索的站台数组对象,传给子组件,用来判断单选站台名当前选中状态
+      treeName: ['合肥轨道交通'], // 当前选中的一级二级站台名
+      preTreeName:['合肥轨道交通'],
+      showTree: true,// 是否显示树形组件
+		  stationData: [{disabled: true,
+        expand: true,
+        children: [],
+        id: 0,
+        parent: null,
+        selected: true,
+        stationId: null,
+        title: "合肥轨道交通"}],
+      tabsData: [{label:'线路管理'},{label:'站点管理'}],
+      currentTabs: '线路管理'
+    };
+  },
+  mounted() {
+    this.$get('metroapi/lineStation/lineStationTree').then(res => {
+				if (res.httpCode == 1) {
+          this.stationData = res.data
+          console.log(this.stationData)
+				// 	this.stationData[0].children = this.getTree(res.data)
+				// 	this.currentStaData = [{disabled: true,
+				// 		expand: true,
+				// 		children: [],
+				// 		id: 0,
+				// 		parent: null,
+				// 		selected: true,
+				// 		stationId: null,
+				// 		title: "合肥轨道交通"}]
+				// } else {
+				// 	this.stationData = [{disabled: true,
+				// 	expand: true,
+				// 	children: [],
+				// 	id: 0,
+				// 	parent: true,
+				// 	selected: true,
+				// 	stationId: null,
+				// 	title: "合肥轨道交通"}]
+				}
+		})
+  },
+  methods: {
+    getTree(arr) {
+      return arr.map((v,index) => {
+        v.disabled = false
+        v.selected = false
+        v.expand = false
+        if (v.title == '1号线') {
+          v.expand = true
+        }
+        if (v.children) v.children = this.getTree(v.children);
+        return v;
+      });
+    },
+    iconChange: _.throttle(function() {
+      this.currentStaData = []
+      this.treeName = []
+      this.showTree = false		
+      if(this.currentStation != ''){
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部
+      } else {
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部   
+      }
+      this.getPamData (this.currentStation)
+      this.stationData.forEach((item, index,itemArr) => {
+        item.expand = false;
+        item.disabled = false; 
+        item.selected = false;
+        if (item.title == this.currentStation) {
+            item.selected = true;
+            item.disabled = true; // disabled 是否禁止选中 
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.currentStaData.push(item)
+            this.preTreeName = this.treeName
+            this.showTree = true
+        }
+        item.children.forEach((val, i,valArr) => {
+          val.expand = false; //expand 是否展开直子节点 
+          val.disabled = false; // disabled 是否禁止选中
+          val.selected = false;
+          if (val.title == this.currentStation) {
+            val.selected = true;
+            val.disabled = true; // disabled 是否禁止选中 
+            val.expand = true;
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.treeName.push(val.title)
+            this.currentStaData.push(val)
+            this.preTreeName = this.treeName
+            this.showTree = true
+          }
+          val.children.forEach ((lastVal,lastIndex) => {
+            lastVal.selected = false; //expand 是否展开直子节点 
+            lastVal.disabled = false; 
+            lastVal.expand = false;
+            if (this.currentStation =='合肥轨道交通' || this.currentStation =='') {
+              itemArr[index].selected = true
+              itemArr[index].disabled = true
+              itemArr[index].expand = true
+              valArr[index].expand = true
+              this.showTree = true
+              this.currentStation = '合肥轨道交通'
+              this.treeName = ['合肥轨道交通']
+            }
+            if (lastVal.title == this.currentStation) {
+              lastVal.selected = true;
+              lastVal.disabled = true; // disabled 是否禁止选中 
+              lastVal.expand = true;
+              val.expand = true
+              item.expand = true
+              this.treeName.push(item.title)
+              this.treeName.push(val.title)
+              this.treeName.push(lastVal.title)
+              this.currentStaData.push(lastVal)
+              this.preTreeName = this.treeName
+              this.showTree = true
+            } 
+          })
+        });
+      });		
+      if (!this.showTree) {
+        this.treeName = this.preTreeName
+      }
+      this.$nextTick(()=> {
+        if (this.initActive == 'year') {
+          this.$refs.longForecast.getTitle(this.pamData)
+        } else {
+          this.$refs.forecast.getTitle(this.pamData)
+        }
+      })
+		}, 500),
+    treeChange(val,arr) {
+      this.currentStation = val
+      this.treeName = arr
+      this.preTreeName = arr
+		},
+    tabsClick (name) {
+      this.currentTabs = name
+    }
+  }
+};
+</script>
+<style scoped lang="stylus">
+.content-main {
+  width: 100%;
+  height: calc(100% - 50px);
+  overflow: auto;
+}
+.common-search {
+  width: 100%;
+}
+>>> .common-search .ivu-input {
+  background-color: #06214D;
+  border: 1px solid #2355A6;
+  border-radius: 15px;
+  color: #fff;
+  height: 32px;
+}
+>>> .common-search .ivu-input:focus {
+    border-color: #0185ea;
+}
+.content-body {
+  width: 100%;
+  height: 100%;
+  background: #06214D;
+}
+.station-tree {
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-body {
+  border: 1px solid #204384;
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-center {
+  height: calc(100% - 32px);
+  padding-top: 10px;
+  // display: flex;
+}
+.station-tree-left {
+  height: 100%;
+  overflow: hidden;
+  overflow-y: auto;
+}
+.station-tree-left-notree {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #fff;
+  fon-size: 14px;
+}
+.right-main {
+  height: 100%;
+  padding: 10px 0;
+}
+</style>

+ 24 - 0
src/views/homecomponents/BasicInfomation/InstruManage.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="container">
+    仪表管理
+  </div>
+</template>
+<script>
+export default {
+  name: "InstruManage",
+  components:{
+  },
+  data() {
+    return {
+    };
+  },
+  mounted() {
+  },
+  methods: {
+   
+  }
+};
+</script>
+<style scoped lang="stylus">
+
+</style>

+ 498 - 0
src/views/homecomponents/BasicInfomation/LineManage.vue

@@ -0,0 +1,498 @@
+<template>
+  <div class="manage-main">
+    <div class="manage-main-top">
+      <Button icon="ios-add" class="common-add-btn" @click="addClick">新增线路</Button>
+    </div>
+    <div class="manage-main-center">
+      <Table :columns="columns" :data="tableData" class="common-table" :row-class-name="rowClassName" :loading="loading">
+        <template slot="loading">
+            <Loading-animation></Loading-animation>
+        </template>
+         <template slot-scope="{ row }" slot="action">
+          <div>
+           <Tooltip content="详情" placement="top">
+              <i class="iconfont icon-xiangqingmingxi" style="cursor:pointer;color:#B8B532;fontSize:20px;marginRight:6px" @click="detailClick(row)"></i>
+           </Tooltip>
+           <Tooltip content="编辑" placement="top">
+              <i class="iconfont icon-bianji" style="cursor:pointer;color:#64ACFE;fontSize:20px;marginRight:6px" @click="editClick(row)"></i>
+           </Tooltip>
+           <Tooltip content="删除" placement="top">
+              <i class="iconfont icon-shanchu" style="cursor:pointer;color:#E92E2E;fontSize:20px;marginRight:6px" @click="delClick(row)"></i>
+           </Tooltip>
+          </div>
+        </template>
+      </Table>
+    </div>
+    <Page :total="tableTotal" :current="tableParams.pageNum" :page-size="tableParams.pageSize" @on-change="changePage" @on-page-size-change="sizeChange" show-elevator class="common-page"/>
+    <Modal
+      v-model="showModal"
+      :title="title"
+      width="34"
+      ref="modalGrag"
+      draggable
+      @on-visible-change="modalChange"
+      :mask-closable="false"
+      class-name="common-modal">
+      <Form class="common-form" ref="formOption" :model="formOption" :rules="ruleValidate" :label-width="120">
+				<FormItem label="上级节点:">
+          <span>合肥轨道交通</span>
+				</FormItem>
+				<FormItem label="线路名称:" prop="lineName">
+          <Input v-model="formOption.lineName" maxlength="20" show-word-limit />
+        </FormItem>
+        	<FormItem label="线路序号:" prop="lineSerial">
+          <InputNumber :max="99" :min="1" v-model="formOption.lineSerial" placeholder="请输入1~99,序号越小显示越靠前"></InputNumber>
+        </FormItem>
+        <FormItem label="线路类型:" prop="lineType">
+           <Select v-model="formOption.lineType" placeholder="请选择线路类型">
+              <Option v-for="item in lineTypeData" :value="item.id" :key="item.id">{{ item.value }}</Option>
+          </Select>
+        </FormItem>
+        <FormItem label="线路长度(km):" prop="lineLength">
+          <Input type="number" placeholder="保留小数点后2位" v-model="formOption.lineLength" @input.native="checkNumber" />
+        </FormItem>
+        <FormItem label="运营机构:" prop="operatingGroup">
+          <Input v-model="formOption.operatingGroup" maxlength="20" show-word-limit />
+        </FormItem>
+        <FormItem label="说明:" prop="remark">
+          <Input v-model="formOption.remark" type="textarea" :rows="6" maxlength="200" show-word-limit />
+        </FormItem>
+        <FormItem label="启用状态:" prop="station" v-show="title == '新增线路'">
+          <i-switch true-color="#57C44F" v-model="formOption.switch" disabled></i-switch>
+          <span style="color: #718EBD;margin-left:6px">关</span>
+          <span style="color: #718EBD;margin-left:12px">(所有新增线路均为关闭,需在列表打开)</span>
+        </FormItem>
+			</Form>
+      <div slot="footer">
+          <Button @click="modalCancel">取消</Button>
+          <Button type="primary" @click="modalOk('formOption')">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="modalStatus"
+      :title="commonTitle"
+      width="25"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <i :class="'iconfont '+ activeClass" :style="{ color: activeColor}" class="modal-icon" v-show="commonTitle!='确认删除'"></i>
+      <Icon type="ios-information-circle" :style="{ color: activeColor}" class="modal-icon" v-show="commonTitle=='确认删除'"></Icon>
+      <span class="modal-text">{{modalTitle}}</span>
+      <div slot="footer">
+          <Button @click="commonCancel">取消</Button>
+          <Button type="primary" @click="commonOk">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="detailStatus"
+      title="线路详情"
+      width="45"
+      ref="modalGrag"
+      draggable
+      footer-hide
+      :mask-closable="false"
+      class-name="common-modal">
+      <div v-for="(item,index) in detailLabel" :key="index">
+        <div class="common-modal-top">
+        <span class="common-modal-top-text">{{item.name}}</span>
+        </div>
+        <div class="common-modal-content">
+          <div class="modal-content-item" v-for="(val,i) in item.arr" :key="i" :class="{'modal-content-item-last': val.name == '说明'}">
+            <span class="modal-content-item-name">
+            {{val.name}}
+            </span>
+            <span class="modal-content-item-value">4号线</span>
+          </div>
+        </div>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+export default {
+  name: "LineManage",
+  components:{
+  },
+  data() {
+    return {
+      rowObj: {},
+      loading: false,
+      tableParams: {
+        lineName: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      tableTotal: 0,
+      tableData: [],
+      showModal: false,
+      detailStatus: false, 
+      modalStatus: false,
+      title: '新增线路',
+      commonTitle: "确认删除",
+      activeColor: '#E92E2E',
+      activeClass: '',
+      modalTitle: '',
+      formOption: {lineName: '',lineSerial: null,lineType:null, lineLength:'',operatingGroup:'',remark:''},
+      ruleValidate: {
+        lineName: [{
+          required: true,
+          message: '请输入线路名称',
+          trigger: 'blur'
+        }],
+        lineSerial: [{
+          required: true,
+          type:'number',
+          message: '请输入线路序号',
+          trigger: 'blur'
+        }]
+      }, 
+      lineTypeData: [],
+      columns: [
+        {
+          title: '线路序号',
+          key: 'lineSerial',
+          align: 'center',
+          width: 100,
+        },
+        {
+          title: '线路名称',
+          key: 'lineName',
+          align: 'center',
+          width: 100,
+        },
+        {
+          title: '当前线路长度(km)',
+          key: 'lineLength',
+          align: 'center',
+        },
+        {
+          title: '站点数量',
+          key: 'stationCount',
+          align: 'center',
+        },
+        {
+          title: '运营机构',
+          key: 'operatingGroup',
+          align: 'center',
+        },
+        {
+          title: '线路类型',
+          key: 'lineTypeValue',
+          align: 'center',
+        },
+        {
+          title: '启用状态',
+          key: 'enabled',
+          align: 'center',
+          width: 120,
+          render: (h, params) => {
+            return h('div', [                             
+              h('i-switch', {
+                props: { value: params.row.enabled,'true-color': '#57C44F', trueValue:1,falseValue: 0
+                },
+                nativeOn:{
+                    "mousedown":(event)=>{ // 监听组件原生事件mousedown,此事件在click之前触发
+                      this.rowObj =  params.row
+                      if (params.row.enabled == 0) {
+                        this.commonTitle = '确认启用'
+                        this.activeColor = '#57C44F'
+                        this.activeClass = 'icon-qiyong'
+                        this.modalTitle = '启用后此线路统计数据将在各管理模块及前端显示页面生效。'
+                        this.modalStatus = true
+                      } else {
+                        this.commonTitle = '确认关闭'
+                        this.activeColor = '#E92E2E'
+                        this.activeClass = 'icon-guanbi'
+                        this.modalTitle = '关闭后线路下所有站点将同时关闭,线路及站点统计数据不可见。'
+                        this.modalStatus = true
+                      }
+                    },
+                  }
+              }),
+            ])
+            }
+          },
+        {
+          title: '操作',
+          align: 'center',
+          slot: 'action',
+          width: 120,
+        }
+      ],
+      detailLabel: [{name:'基础信息',arr:[{name: '线路名称',value:0},{name: '线路序号',value:0},{name: '上级节点',value:0},{name: '启用状态',value:0},{name: '运营机构',value:0},{name: '线路类型',value:0},{name: '说明',value:0}]}]
+    };
+  },
+  mounted() {
+    this.getLineType()
+    this.getTableData()
+  },
+  methods: {
+      checkNumber:function(withdrawAmount){
+        this.formOption.lineLength= (this.formOption.lineLength.match(/^\d*(\.?\d{0,2})/g)[0]) || null                  
+    },
+    rowClassName(row, index) {
+      if (index % 2 == 0) {
+        return "ivu-table-stripe-even";
+      } else {
+        return "ivu-table-stripe-odd";
+      }
+    },
+    // 分页
+    changePage (val) {
+      this.tableParams.pageNum = val
+      // this.getTableData()
+    },
+    //跳转
+    sizeChange (val) {
+      this.tableParams.pageSize = val
+      // this.getTableData()
+    },
+    // 获取线路类型
+    getLineType  () {
+      this.$get('metroapi/dic/queryDictionary', {name:'线路类型'}).then(res=>{
+        if (res.httpCode == 1 ){
+          this.lineTypeData = res.data
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+    addClick () {
+      this.title = '新增线路'
+      this.showModal = true
+      this.$refs.modalGrag.dragData.x = null
+      this.$refs.modalGrag.dragData.y = null
+    },
+    detailClick (row) {   
+      this.rowObj = row
+      this.detailStatus = true
+    },
+    editClick (row) {
+      this.rowObj = row
+      this.formOption = JSON.parse(JSON.stringify(row));
+      this.title = '编辑线路'
+      this.showModal = true
+    },
+    delClick (row) {
+      this.rowObj = row
+      this.commonTitle = '确认删除'
+      this.activeColor = '#E92E2E'
+      this.activeClass = ''
+      this.modalTitle = '只能删除没有站点的线路,删除不影响已产生的操作和记录。'
+      this.modalStatus = true
+    },
+    getTableData () {
+      this.loading = true
+      this.$get('metroapi/lineStation/queryLine', this.tableParams).then(res=>{
+        this.loading = false
+          if ( res.httpCode == 1 ){
+            this.tableData = res.data.data
+            this.tableTotal = res.data.count
+          } else {
+            this.$Message.info(res.msg)
+          }
+        })
+    },
+    modalChange () {
+     this.$refs.formOption.resetFields(); 
+    },
+    modalOk (formName) {
+      if (this.title == '新增线路') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            this.$post('metroapi/lineStation/addLine', this.formOption).then(res=>{
+              if ( res.httpCode == 1 ){
+                this.showModal = false
+                this.$Message.info(res.msg)
+                this.getTableData()
+              } else {
+                this.$Message.info(res.msg)
+              }
+            })
+          } else {
+            this.addModal = true
+          }
+       })
+      } else {
+      //   this.$refs[formName].validate((valid) => {
+      //     if (valid) {
+      //       this.$post('metroapi/lineStation/addLine', this.formOption).then(res=>{
+      //         if ( res.httpCode == 1 ){
+      //           this.showModal = false
+      //           this.$Message.info(res.msg)
+      //           // this.getTableData()
+      //         } else {
+      //           this.$Message.info(res.msg)
+      //         }
+      //       })
+      //     } else {
+      //       this.addModal = true
+      //     }
+      //  })
+      }
+    },
+    modalCancel () {
+      this.showModal = false
+    },
+    commonOk () {
+      if (this.commonTitle == '确认启用') {
+        this.rowObj.enabled = 1
+        let params = {
+          lineId: this.rowObj.id,
+          enabled: this.rowObj.enabled
+        }
+        this.getSwitchStatus(params)
+      } else if (this.commonTitle == '确认关闭') {
+        this.rowObj.enabled = 0
+        let params = {
+          lineId: this.rowObj.id,
+          enabled: this.rowObj.enabled
+        }
+        this.getSwitchStatus(params)
+      } else {
+        let params = {
+          lineId: this.rowObj.id
+        }
+        this.delData(params)
+      }
+    },
+    commonCancel () {
+      this.modalStatus = false
+    },
+    // 启用 关闭/接口
+    getSwitchStatus (params) {
+      this.$get('metroapi/lineStation/enableLine',params).then(res=>{
+        if (res.httpCode == 1 ){
+          this.modalStatus = false
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+    // 删除 关闭/接口
+    delData (params) {
+      this.$get('metroapi/lineStation/delLine',params).then(res=>{
+        if (res.httpCode == 1 ){
+          this.modalStatus = false
+          this.getTableData()
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+  }
+};
+</script>
+<style scoped lang="stylus">
+.manage-main {
+ width: 100%;
+ height: calc(100% - 50px);
+ display: flex;
+ flex-direction: column;
+ position: relative;
+}
+.manage-main-top {
+  padding: 12px 0;
+  display: flex;
+  justify-content: flex-end;
+}
+.manage-main-center {
+  width: 100%;
+  height: calc(100% - 100px);
+}
+.common-table {
+  max-height: 100%;
+}
+>>> .common-table .ivu-table th {
+  height: 50px;
+ }
+ >>> .common-table .ivu-table td {
+  height: 50px;
+ }
+ >>> .ivu-spin-fix {
+   top: 50px;
+ }
+.common-page {
+  margin-top: 15px;
+  display: flex;
+  justify-content: flex-end;
+}
+/* 对话框里的input里的placeholder样式修改 */
+/deep/ .ivu-input::-webkit-input-placeholder , /deep/ .ivu-input-number-input::-webkit-input-placeholder{
+  color: #718EBD;
+}
+/deep/ .ivu-input::-moz-placeholder, /deep/ .ivu-input-number-input::-webkit-input-placeholder{   /* Mozilla Firefox 19+ */
+  color: #718EBD;
+}
+/deep/ .ivu-input::-moz-placeholde, /deep/ .ivu-input-number-input::-webkit-input-placeholderr{    /* Mozilla Firefox 4 to 18 */
+ color: #718EBD;
+}
+/deep/ .ivu-input::-ms-input-placeholder, /deep/ .ivu-input-number-input::-webkit-input-placeholder{  /* Internet Explorer 10-11 */
+  color: #718EBD;
+}
+>>> .common-modal-top-text {
+  font-size: 14px;
+  font-weight: bold;
+  color: #29A0FF;
+  line-height: 42px;
+  border-left: 3px solid #1590F1;
+  padding-left: 12px;
+}
+>>> .common-modal-content {
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  margin-bottom: 15px;
+  border-right: 1px solid #21437B;
+}
+>>> .modal-content-item {
+  width: 50%;
+  display: flex;
+}
+>>> .modal-content-item-last {
+  width: 100%;
+}
+>>> .modal-content-item-name {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #13305F;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-value {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #06214D;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-last .modal-content-item-name{
+  width: 25%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+}
+>>> .modal-content-item-last .modal-content-item-value{
+  width: 75%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+  line-height: 22px;
+}
+</style>

+ 242 - 0
src/views/homecomponents/BasicInfomation/LineStationManage.vue

@@ -0,0 +1,242 @@
+<template>
+ <div class="content-main common-scroll">
+    <div class="content-body">
+      <Tabs :value="currentTabs" @on-click="tabsClick" class="common-tabs">
+        <TabPane v-for="tab in tabsData" :key="tab.label" :label="tab.label" :name="tab.label"></TabPane>
+      </Tabs>
+      <line-manage v-show="currentTabs=='线路管理'"></line-manage>
+      <Row :gutter="8" style="width:100%;height: calc(100% - 50px)" v-show="currentTabs=='站点管理'">
+        <i-col span="6" style="height:100%">
+          <div class="station-tree">
+            <div class="station-tree-body">
+              <div class="station-tree-top">
+                <Input suffix="ios-search" placeholder="请输入地铁站台名" search v-model="currentStation" class="common-search"  @on-search="iconChange"/>
+              </div>
+              <div class="station-tree-center">
+                <div class="station-tree-left common-scroll" v-show="showTree">
+                  <tree-list :defaultData="stationData" :currentStaData="currentStaData" :clickAllNode="true" v-if="stationData.length>0" @treeChange="treeChange" ref="tree"></tree-list>
+                </div>
+                <div class="station-tree-left-notree" v-show="!showTree">
+                  站点输入错误!
+                </div>
+                <div class="station-tree-right">
+                </div>
+              </div>
+            </div>
+          </div>
+        </i-col>
+        <i-col span="18" style="height:100%">
+          <div class="right-main">
+            <station-manage></station-manage>
+          </div>
+        </i-col>
+      </Row>
+    </div>
+  </div>
+</template>
+<script>
+import _ from 'lodash'
+import LineManage from './LineManage.vue'
+import StationManage from './StationManage.vue'
+export default {
+  name: "LineStationManage",
+  components:{
+    LineManage,StationManage
+  },
+  data() {
+    return {
+      currentStation: '',
+      currentStaData: [], // 当前搜索框搜索的站台数组对象,传给子组件,用来判断单选站台名当前选中状态
+      treeName: ['合肥轨道交通'], // 当前选中的一级二级站台名
+      preTreeName:['合肥轨道交通'],
+      showTree: true,// 是否显示树形组件
+		  stationData: [],
+      tabsData: [{label:'线路管理'},{label:'站点管理'}],
+      currentTabs: '线路管理'
+    };
+  },
+  mounted() {
+    this.$get('metroapi/lineStation/lineStationTree').then(res => {
+				if (res.httpCode == 1) {
+          this.stationData = res.data
+          console.log(this.stationData)
+				// 	this.stationData[0].children = this.getTree(res.data)
+				// 	this.currentStaData = [{disabled: true,
+				// 		expand: true,
+				// 		children: [],
+				// 		id: 0,
+				// 		parent: null,
+				// 		selected: true,
+				// 		stationId: null,
+				// 		title: "合肥轨道交通"}]
+				// } else {
+				// 	this.stationData = [{disabled: true,
+				// 	expand: true,
+				// 	children: [],
+				// 	id: 0,
+				// 	parent: true,
+				// 	selected: true,
+				// 	stationId: null,
+				// 	title: "合肥轨道交通"}]
+				}
+		})
+  },
+  methods: {
+    getTree(arr) {
+      return arr.map((v,index) => {
+        v.disabled = false
+        v.selected = false
+        v.expand = false
+        if (v.title == '1号线') {
+          v.expand = true
+        }
+        if (v.children) v.children = this.getTree(v.children);
+        return v;
+      });
+    },
+    iconChange: _.throttle(function() {
+      this.currentStaData = []
+      this.treeName = []
+      this.showTree = false		
+      if(this.currentStation != ''){
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部
+      } else {
+        document.querySelector(".tree-scroll").scrollTo(0, 0); // 滚动条回到顶部   
+      }
+      this.getPamData (this.currentStation)
+      this.stationData.forEach((item, index,itemArr) => {
+        item.expand = false;
+        item.disabled = false; 
+        item.selected = false;
+        if (item.title == this.currentStation) {
+            item.selected = true;
+            item.disabled = true; // disabled 是否禁止选中 
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.currentStaData.push(item)
+            this.preTreeName = this.treeName
+            this.showTree = true
+        }
+        item.children.forEach((val, i,valArr) => {
+          val.expand = false; //expand 是否展开直子节点 
+          val.disabled = false; // disabled 是否禁止选中
+          val.selected = false;
+          if (val.title == this.currentStation) {
+            val.selected = true;
+            val.disabled = true; // disabled 是否禁止选中 
+            val.expand = true;
+            item.expand = true;
+            this.treeName.push(item.title)
+            this.treeName.push(val.title)
+            this.currentStaData.push(val)
+            this.preTreeName = this.treeName
+            this.showTree = true
+          }
+          val.children.forEach ((lastVal,lastIndex) => {
+            lastVal.selected = false; //expand 是否展开直子节点 
+            lastVal.disabled = false; 
+            lastVal.expand = false;
+            if (this.currentStation =='合肥轨道交通' || this.currentStation =='') {
+              itemArr[index].selected = true
+              itemArr[index].disabled = true
+              itemArr[index].expand = true
+              valArr[index].expand = true
+              this.showTree = true
+              this.currentStation = '合肥轨道交通'
+              this.treeName = ['合肥轨道交通']
+            }
+            if (lastVal.title == this.currentStation) {
+              lastVal.selected = true;
+              lastVal.disabled = true; // disabled 是否禁止选中 
+              lastVal.expand = true;
+              val.expand = true
+              item.expand = true
+              this.treeName.push(item.title)
+              this.treeName.push(val.title)
+              this.treeName.push(lastVal.title)
+              this.currentStaData.push(lastVal)
+              this.preTreeName = this.treeName
+              this.showTree = true
+            } 
+          })
+        });
+      });		
+      if (!this.showTree) {
+        this.treeName = this.preTreeName
+      }
+      this.$nextTick(()=> {
+        if (this.initActive == 'year') {
+          this.$refs.longForecast.getTitle(this.pamData)
+        } else {
+          this.$refs.forecast.getTitle(this.pamData)
+        }
+      })
+		}, 500),
+    treeChange(val,arr) {
+      this.currentStation = val
+      this.treeName = arr
+      this.preTreeName = arr
+		},
+    tabsClick (name) {
+      this.currentTabs = name
+    }
+  }
+};
+</script>
+<style scoped lang="stylus">
+.content-main {
+  width: 100%;
+  height: calc(100% - 50px);
+  overflow: auto;
+}
+.content-body {
+  width: 100%;
+  height: 100%;
+  background: #06214D;
+  padding: 10px;
+}
+.common-search {
+  width: 100%;
+}
+>>> .common-search .ivu-input {
+  background-color: #06214D;
+  border: 1px solid #2355A6;
+  border-radius: 15px;
+  color: #fff;
+  height: 32px;
+}
+>>> .common-search .ivu-input:focus {
+    border-color: #0185ea;
+}
+.station-tree {
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-body {
+  border: 1px solid #204384;
+  height: 100%;
+  padding: 10px;
+}
+.station-tree-center {
+  height: calc(100% - 32px);
+  padding-top: 10px;
+  // display: flex;
+}
+.station-tree-left {
+  height: 100%;
+  overflow: hidden;
+  overflow-y: auto;
+}
+.station-tree-left-notree {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #fff;
+  fon-size: 14px;
+}
+.right-main {
+  height: 100%;
+  padding: 10px 0;
+}
+</style>

+ 24 - 0
src/views/homecomponents/BasicInfomation/OperaTimeManage.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="container">
+    侧边栏
+  </div>
+</template>
+<script>
+export default {
+  name: "OperaTimeManage",
+  components:{
+  },
+  data() {
+    return {
+    };
+  },
+  mounted() {
+  },
+  methods: {
+   
+  }
+};
+</script>
+<style scoped lang="stylus">
+
+</style>

+ 497 - 0
src/views/homecomponents/BasicInfomation/StationManage.vue

@@ -0,0 +1,497 @@
+<template>
+  <div class="manage-main">
+    <div class="manage-main-top">
+      <Button icon="ios-add" class="common-add-btn" @click="addClick">新增站点</Button>
+    </div>
+    <div class="manage-main-center">
+      <Table :columns="columns" :data="tableData" class="common-table" :row-class-name="rowClassName" :loading="loading">
+        <template slot="loading">
+            <Loading-animation></Loading-animation>
+        </template>
+         <template slot-scope="{ row }" slot="action">
+          <div>
+           <Tooltip content="详情" placement="top">
+              <i class="iconfont icon-xiangqingmingxi" style="cursor:pointer;color:#B8B532;fontSize:20px;marginRight:6px" @click="detailClick(row)"></i>
+           </Tooltip>
+           <Tooltip content="编辑" placement="top">
+              <i class="iconfont icon-bianji" style="cursor:pointer;color:#64ACFE;fontSize:20px;marginRight:6px" @click="editClick(row)"></i>
+           </Tooltip>
+           <Tooltip content="删除" placement="top">
+              <i class="iconfont icon-shanchu" style="cursor:pointer;color:#E92E2E;fontSize:20px;marginRight:6px" @click="delClick(row)"></i>
+           </Tooltip>
+          </div>
+        </template>
+      </Table>
+    </div>
+    <Page :total="tableTotal" :current="tableParams.pageNum" :page-size="tableParams.pageSize" @on-change="changePage" @on-page-size-change="sizeChange" show-elevator class="common-page"/>
+    <Modal
+      v-model="showModal"
+      :title="title"
+      width="34"
+      ref="modalGrag"
+      draggable
+      @on-visible-change="modalChange"
+      :mask-closable="false"
+      class-name="common-modal">
+      <Form class="common-form" ref="formOption" :model="formOption" :rules="ruleValidate" :label-width="120">
+				<FormItem label="上级节点:">
+          <span>合肥轨道交通</span>
+				</FormItem>
+				<FormItem label="站点名称:" prop="lineName">
+          <Input v-model="formOption.lineName" maxlength="20" show-word-limit />
+        </FormItem>
+        	<FormItem label="站点序号:" prop="lineSerial">
+          <InputNumber :max="99" :min="1" v-model="formOption.lineSerial" placeholder="请输入1~99,序号越小显示越靠前"></InputNumber>
+        </FormItem>
+        <FormItem label="站点类型:" prop="lineType">
+           <Select v-model="formOption.lineType" placeholder="请选择站点类型">
+              <Option v-for="item in lineTypeData" :value="item.id" :key="item.id">{{ item.value }}</Option>
+          </Select>
+        </FormItem>
+        <FormItem label="运营机构:" prop="operatingGroup">
+          <Input v-model="formOption.operatingGroup" maxlength="20" show-word-limit />
+        </FormItem>
+        <FormItem label="说明:" prop="remark">
+          <Input v-model="formOption.remark" type="textarea" :rows="6" maxlength="200" show-word-limit />
+        </FormItem>
+        <FormItem label="启用状态:" prop="station" v-show="title == '新增站点'">
+          <i-switch true-color="#57C44F" v-model="formOption.switch" disabled></i-switch>
+          <span style="color: #718EBD;margin-left:6px">关</span>
+          <span style="color: #718EBD;margin-left:12px">(所有新增站点均为关闭,需在列表打开)</span>
+        </FormItem>
+			</Form>
+      <div slot="footer">
+          <Button @click="modalCancel">取消</Button>
+          <Button type="primary" @click="modalOk('formOption')">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="modalStatus"
+      :title="commonTitle"
+      width="25"
+      ref="modalGrag"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <i :class="'iconfont '+ activeClass" :style="{ color: activeColor}" class="modal-icon" v-show="commonTitle!='确认删除'"></i>
+      <Icon type="ios-information-circle" :style="{ color: activeColor}" class="modal-icon" v-show="commonTitle=='确认删除'"></Icon>
+      <span class="modal-text">{{modalTitle}}</span>
+      <div slot="footer">
+          <Button @click="commonCancel">取消</Button>
+          <Button type="primary" @click="commonOk">确定</Button>
+        </div>
+    </Modal>
+    <Modal
+      v-model="detailStatus"
+      title="站点详情"
+      width="45"
+      ref="modalGrag"
+      draggable
+      footer-hide
+      :mask-closable="false"
+      class-name="common-modal">
+      <div v-for="(item,index) in detailLabel" :key="index">
+        <div class="common-modal-top">
+        <span class="common-modal-top-text">{{item.name}}</span>
+        </div>
+        <div class="common-modal-content">
+          <div class="modal-content-item" v-for="(val,i) in item.arr" :key="i" :class="{'modal-content-item-last': val.name == '说明'}">
+            <span class="modal-content-item-name">
+            {{val.name}}
+            </span>
+            <span class="modal-content-item-value">4号线</span>
+          </div>
+        </div>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+export default {
+  name: "StationManage",
+  components:{
+  },
+  data() {
+    return {
+      rowObj: {},
+      loading: false,
+      tableParams: {
+        stationName: '',
+        pageNum: 1,
+        pageSize: 20
+      },
+      tableTotal: 0,
+      tableData: [],
+      showModal: false,
+      detailStatus: false, 
+      modalStatus: false,
+      title: '新增站点',
+      commonTitle: "确认删除",
+      activeColor: '#E92E2E',
+      activeClass: '',
+      modalTitle: '',
+      formOption: {lineName: '',lineSerial: null,lineType:null, operatingGroup:'',remark:''},
+      ruleValidate: {
+        lineName: [{
+          required: true,
+          message: '请输入站点名称',
+          trigger: 'blur'
+        }],
+        lineSerial: [{
+          required: true,
+          type:'number',
+          message: '请输入站点序号',
+          trigger: 'blur'
+        }]
+      }, 
+      lineTypeData: [],
+      columns: [
+        {
+          title: '站点序号',
+          key: 'lineSerial',
+          align: 'center',
+          width: 100,
+        },
+        {
+          title: '站点名称',
+          key: 'stationName',
+          align: 'center',
+          width: 100,
+        },
+         {
+          title: '所属线路',
+          key: 'lineName',
+          align: 'center',
+        },
+        {
+          title: '是否换乘站',
+          key: 'transfer',
+          align: 'center',
+        },
+        {
+          title: '站点类型',
+          key: 'stationType',
+          align: 'center',
+        },
+        {
+          title: '层数',
+          key: 'address',
+          align: 'floor',
+        },
+        {
+          title: '建筑面积',
+          key: 'address',
+          align: 'area',
+        },
+        {
+          title: '启用状态',
+          key: 'enabled',
+          align: 'center',
+          width: 120,
+          render: (h, params) => {
+            return h('div', [                             
+              h('i-switch', {
+                props: { value: params.row.enabled,'true-color': '#57C44F', trueValue:1,falseValue: 0
+                },
+                nativeOn:{
+                    "mousedown":(event)=>{ // 监听组件原生事件mousedown,此事件在click之前触发
+                      this.rowObj =  params.row
+                      if (params.row.enabled == 0) {
+                        this.commonTitle = '确认启用'
+                        this.activeColor = '#57C44F'
+                        this.activeClass = 'icon-qiyong'
+                        this.modalTitle = '启用后此站点统计数据将在各管理模块及前端显示页面生效。'
+                        this.modalStatus = true
+                      } else {
+                        this.commonTitle = '确认关闭'
+                        this.activeColor = '#E92E2E'
+                        this.activeClass = 'icon-guanbi'
+                        this.modalTitle = '关闭后站点下所有站点将同时关闭,站点及站点统计数据不可见。'
+                        this.modalStatus = true
+                      }
+                    },
+                  }
+              }),
+            ])
+            }
+          },
+        {
+          title: '操作',
+          align: 'center',
+          slot: 'action',
+          width: 120,
+        }
+      ],
+      detailLabel: [{name:'基础信息',arr:[{name: '站点名称',value:0},{name: '站点序号',value:0},{name: '上级节点',value:0},{name: '启用状态',value:0},{name: '运营机构',value:0},{name: '站点类型',value:0},{name: '说明',value:0}]}]
+    };
+  },
+  mounted() {
+    this.getLineType()
+    this.getTableData()
+  },
+  methods: {
+    rowClassName(row, index) {
+      if (index % 2 == 0) {
+        return "ivu-table-stripe-even";
+      } else {
+        return "ivu-table-stripe-odd";
+      }
+    },
+    // 分页
+    changePage (val) {
+      this.tableParams.pageNum = val
+      // this.getTableData()
+    },
+    //跳转
+    sizeChange (val) {
+      this.tableParams.pageSize = val
+      // this.getTableData()
+    },
+    // 获取站点类型
+    getLineType  () {
+      this.$get('metroapi/dic/queryDictionary', {name:'站点类型'}).then(res=>{
+        if (res.httpCode == 1 ){
+          this.lineTypeData = res.data
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+    addClick () {
+      this.title = '新增站点'
+      this.showModal = true
+      this.$refs.modalGrag.dragData.x = null
+      this.$refs.modalGrag.dragData.y = null
+    },
+    detailClick (row) {   
+      this.rowObj = row
+      this.detailStatus = true
+    },
+    editClick (row) {
+      this.rowObj = row
+      this.formOption = JSON.parse(JSON.stringify(row));
+      this.title = '编辑站点'
+      this.showModal = true
+    },
+    delClick (row) {
+      this.rowObj = row
+      this.commonTitle = '确认删除'
+      this.activeColor = '#E92E2E'
+      this.activeClass = ''
+      this.modalTitle = '只能删除没有站点的站点,删除不影响已产生的操作和记录。'
+      this.modalStatus = true
+    },
+    getTableData () {
+      this.loading = true
+      this.$get('metroapi/lineStation/queryStation', this.tableParams).then(res=>{
+        this.loading = false
+          if ( res.httpCode == 1 ){
+            this.tableData = res.data.data
+            this.tableTotal = res.data.count
+          } else {
+            this.$Message.info(res.msg)
+          }
+        })
+    },
+    modalChange () {
+     this.$refs.formOption.resetFields(); 
+    },
+    modalOk (formName) {
+      if (this.title == '新增站点') {
+        this.$refs[formName].validate((valid) => {
+          if (valid) {
+            this.$post('metroapi/lineStation/addLine', this.formOption).then(res=>{
+              if ( res.httpCode == 1 ){
+                this.showModal = false
+                this.$Message.info(res.msg)
+                this.getTableData()
+              } else {
+                this.$Message.info(res.msg)
+              }
+            })
+          } else {
+            this.addModal = true
+          }
+       })
+      } else {
+      //   this.$refs[formName].validate((valid) => {
+      //     if (valid) {
+      //       this.$post('metroapi/lineStation/addLine', this.formOption).then(res=>{
+      //         if ( res.httpCode == 1 ){
+      //           this.showModal = false
+      //           this.$Message.info(res.msg)
+      //           // this.getTableData()
+      //         } else {
+      //           this.$Message.info(res.msg)
+      //         }
+      //       })
+      //     } else {
+      //       this.addModal = true
+      //     }
+      //  })
+      }
+    },
+    modalCancel () {
+      this.showModal = false
+    },
+    commonOk () {
+      if (this.commonTitle == '确认启用') {
+        this.rowObj.enabled = 1
+        let params = {
+          lineId: this.rowObj.id,
+          enabled: this.rowObj.enabled
+        }
+        this.getSwitchStatus(params)
+      } else if (this.commonTitle == '确认关闭') {
+        this.rowObj.enabled = 0
+        let params = {
+          lineId: this.rowObj.id,
+          enabled: this.rowObj.enabled
+        }
+        this.getSwitchStatus(params)
+      } else {
+        let params = {
+          lineId: this.rowObj.id
+        }
+        this.delData(params)
+      }
+    },
+    commonCancel () {
+      this.modalStatus = false
+    },
+    // 启用 关闭/接口
+    getSwitchStatus (params) {
+      this.$get('metroapi/lineStation/enableLine',params).then(res=>{
+        if (res.httpCode == 1 ){
+          this.modalStatus = false
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+    // 删除 关闭/接口
+    delData (params) {
+      this.$get('metroapi/lineStation/delLine',params).then(res=>{
+        if (res.httpCode == 1 ){
+          this.modalStatus = false
+          this.getTableData()
+        } else {
+          this.$Message.info(res.msg)
+        }
+      })
+    },
+  }
+};
+</script>
+<style scoped lang="stylus">
+.manage-main {
+ width: 100%;
+ height: calc(100% - 50px);
+ display: flex;
+ flex-direction: column;
+ position: relative;
+}
+.manage-main-top {
+  padding: 12px 0;
+  display: flex;
+  justify-content: flex-end;
+}
+.manage-main-center {
+  width: 100%;
+  height: calc(100% - 100px);
+}
+.common-table {
+  max-height: 100%;
+}
+>>> .common-table .ivu-table th {
+  height: 50px;
+ }
+ >>> .common-table .ivu-table td {
+  height: 50px;
+ }
+ >>> .ivu-spin-fix {
+   top: 50px;
+ }
+.common-page {
+  margin-top: 15px;
+  display: flex;
+  justify-content: flex-end;
+}
+/* 对话框里的input里的placeholder样式修改 */
+/deep/ .ivu-input::-webkit-input-placeholder , /deep/ .ivu-input-number-input::-webkit-input-placeholder{
+  color: #718EBD;
+}
+/deep/ .ivu-input::-moz-placeholder, /deep/ .ivu-input-number-input::-webkit-input-placeholder{   /* Mozilla Firefox 19+ */
+  color: #718EBD;
+}
+/deep/ .ivu-input::-moz-placeholde, /deep/ .ivu-input-number-input::-webkit-input-placeholderr{    /* Mozilla Firefox 4 to 18 */
+ color: #718EBD;
+}
+/deep/ .ivu-input::-ms-input-placeholder, /deep/ .ivu-input-number-input::-webkit-input-placeholder{  /* Internet Explorer 10-11 */
+  color: #718EBD;
+}
+>>> .common-modal-top-text {
+  font-size: 14px;
+  font-weight: bold;
+  color: #29A0FF;
+  line-height: 42px;
+  border-left: 3px solid #1590F1;
+  padding-left: 12px;
+}
+>>> .common-modal-content {
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  margin-bottom: 15px;
+  border-right: 1px solid #21437B;
+}
+>>> .modal-content-item {
+  width: 50%;
+  display: flex;
+}
+>>> .modal-content-item-last {
+  width: 100%;
+}
+>>> .modal-content-item-name {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #13305F;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-value {
+  width: 50%;
+  height: 45px;
+  line-height: 45px;
+  background: #06214D;
+  border: 1px solid #21437B;
+  border-bottom: none;
+  border-right: none;
+  font-size: 14px;
+  color: #F5F5F5;
+  padding-left: 20px;
+}
+>>> .modal-content-item-last .modal-content-item-name{
+  width: 25%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+}
+>>> .modal-content-item-last .modal-content-item-value{
+  width: 75%;
+  height: auto;
+  min-height: 45px;
+  border-bottom: 1px solid #21437B;
+  display: flex;
+  align-items: center;
+  line-height: 22px;
+}
+</style>

+ 58 - 3
src/views/homecomponents/Content.vue

@@ -1,18 +1,36 @@
 <template>
-  <div class="container">
-    内容
+  <div class="content">
+    <div class="content-top">
+      <span class="first-menu-name menu-item" :class="menuName.length==1 ? 'menu-name': ''">{{menuName[0]}}</span>
+      <span v-show="menuName[1]" class="arrow">></span>
+      <span class="menu-item" :class="menuName.length==2 ? 'menu-name': ''">{{menuName[1]}}</span>
+      <span v-show="menuName[2]" class="arrow">></span>
+      <span class="menu-item" :class="menuName.length==3 ? 'menu-name': ''">{{menuName[2]}}</span>
+    </div>
+    <router-view class="content-wrap"></router-view>
   </div>
 </template>
 <script>
+import utils from '../../libs/utils'
 export default {
   name: "Content",
   components:{
   },
   data() {
     return {
+      menuName: []
     };
   },
+  watch: {
+      '$route' (to, from) {
+        this.menuName = JSON.parse(sessionStorage.getItem('menuNameArr'))
+        console.log('watch',this.menuName.length)
+        console.log(this.menuName)
+      }
+    },
   mounted() {
+    this.menuName = JSON.parse(sessionStorage.getItem('menuNameArr'))
+    console.log('mounted',this.menuName.length)
   },
   methods: {
    
@@ -20,5 +38,42 @@ export default {
 };
 </script>
 <style scoped lang="stylus">
-
+.content {
+  width: 100%;
+  height: 100%;
+  background: #060D2C;
+  overflow: hidden;
+}
+.content-top {
+  width: 100%;
+  height: 50px;
+  display: flex;
+  align-items: center;
+  position: relative;
+  z-index: 10;
+  background: #06214D;
+  font-size: 14px;
+}
+.first-menu-name {
+  border-left: 3px solid #0185EA;
+  padding-left: 6px;
+  margin-left: 15px;
+  color: #F5F5F5;
+}
+.arrow {
+  margin: 0 10px;
+  color: #F5F5F5;
+}
+.menu-item {
+  color: #F5F5F5;
+}
+.menu-name {
+  color: #4FAFF9;
+  margin-right: 10px;
+  text-decoration: underline;
+}
+.content-wrap {
+  padding: 10px;
+  // background: red;
+}
 </style>

+ 24 - 0
src/views/homecomponents/EquipmentAnalysis/AlarmHandling.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="container">
+    侧边栏
+  </div>
+</template>
+<script>
+export default {
+  name: "AlarmHandling",
+  components:{
+  },
+  data() {
+    return {
+    };
+  },
+  mounted() {
+  },
+  methods: {
+   
+  }
+};
+</script>
+<style scoped lang="stylus">
+
+</style>

+ 24 - 0
src/views/homecomponents/EquipmentAnalysis/AlarmMonitor.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="container">
+    侧边栏
+  </div>
+</template>
+<script>
+export default {
+  name: "AlarmMonitor",
+  components:{
+  },
+  data() {
+    return {
+    };
+  },
+  mounted() {
+  },
+  methods: {
+   
+  }
+};
+</script>
+<style scoped lang="stylus">
+
+</style>

+ 195 - 10
src/views/homecomponents/Head.vue

@@ -1,29 +1,214 @@
 <template>
-  <div class="container all">
-    头部
-  </div>
+  <header class="header navbar">
+    <ul class="menu-list">
+      <li class="logo" @click="onMenu(0)">
+        <img src="@/assets/images/logo.png"/>
+          <!-- <img src="@/assets/images/logo_m.png" @click="onMenu(0)"/> -->
+      </li>
+      <li class="nav-item header-item" :class="!activeId ? 'active' : ''" @click="onMenu(0)">
+        <i class="iconfont icon-shouye"></i>首页
+      </li>
+      <li class="nav-item header-item" v-for="item of menus" :key="item.menuId" :class="activeId === item.menuId ? 'active' : ''" @click="onMenu(item.menuId , item.menuName)">
+        <i :class="'iconfont '+ item.imageUrl" style="vertical-align: middle;"></i>{{item.menuName}}
+      </li>
+    </ul>
+    <div class="menu-right">
+       <i class="iconfont icon-xiaoxi"></i>
+       <div class="portrait">
+         <img src="@/assets/images/headPortrait.png" >
+         <p>
+           <span class="portrait-name">{{userName}}</span>
+           <span class="portrait-role">{{roleName}}</span>
+         </p>
+       </div>
+       <div class="sign-out" @click="signOut">
+        <i class="iconfont icon-084tuichu"></i><span class="sign-out-text">退出</span>
+       </div>
+    </div>
+    <!-- 确认退出 -->
+    <Modal
+      v-model="signOutModal"
+      title="退出"
+      width="400"
+      ref="modalGragSign"
+      draggable
+      :mask-closable="false"
+      class-name="common-modal">
+      <Icon type="ios-information-circle" class="modal-icon" style="color: #ff8432;"></Icon>
+      <span class="modal-text">确认退出</span>
+      <div slot="footer">
+          <Button @click="signOutCancel">取消</Button>
+          <Button type="primary" @click="signOutOk">确定</Button>
+        </div>
+    </Modal>
+   </header>
 </template>
 <script>
+import utils from '../../libs/utils';
 export default {
   name: "Head",
   components:{
   },
   data() {
     return {
+      menus: [],
+      roleName: '',
+      userName: utils.storage('sw_user').user,
+      activeId: 0,
+      signOutModal: false,
+      menuNameArr: []
     };
   },
+  watch: {
+      '$route' (to, from) {
+        // 菜单头部浏览器前进或后退
+        let arr = utils.storage('sw_user').menus;
+        arr.forEach((item,i) => {
+          if (item.childMenus) {
+            item.childMenus.forEach((val,index)=> {
+              if (val.linkUrl == to.path) {
+              this.activeId = val.parentMenuId
+              this.$emit('listenMenuId', this.activeId);
+              sessionStorage.setItem('routname', to.path);
+              this.$router.push( to.path );
+              }
+            })
+          }
+        })
+        // 菜单头部浏览器前进或后退首页选中首页菜单
+        if (to.path == '/mainPage') {
+           this.activeId = 0
+        }
+      }
+    },
   mounted() {
+    this.menus = utils.storage('sw_user').menus
+    this.roleName = this.getCookie('role_name')
+    const ID = sessionStorage.getItem('id')
+    this.activeId = parseInt(ID)
+    this.$emit('listenMenuId', parseInt(ID));
   },
   methods: {
-   
-  }
+    // 获取cookie里某个参数的值
+    getCookie(name) {
+      let cookieValue = null;
+      if (document.cookie && document.cookie !== '') {
+          let cookies = document.cookie.split(';');
+          for (let i = 0; i < cookies.length; i++) {
+              let cookie = cookies[i].trim();
+              // 判断这个cookie的参数名是不是我们想要的
+              if (cookie.substring(0, name.length + 1) === (name + '=')) {
+                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                  break;
+              }
+          }
+      }
+      return cookieValue;
+    },
+    onMenu: function(id,menuName) {
+      let menuNameArr = []
+      menuNameArr[0] = menuName
+      if(this.activeId === id) {
+          return ;
+        }
+        this.activeId = id;
+        const { currRouterName } = utils.toRouter(id);
+        this.$emit('listenMenuId', id);
+        this.menus.forEach((item)=> {
+          if (item.menuId == id) {
+           menuNameArr[1] = item.childMenus[0].menuName
+          }
+        })
+        sessionStorage.setItem('routname', currRouterName);
+        sessionStorage.setItem('menuNameArr',JSON.stringify(menuNameArr));
+        this.$router.push( currRouterName );
+    },
+    signOut () {
+      this.signOutModal = true
+      this.$refs.modalGragSign.dragData.x = null
+      this.$refs.modalGragSign.dragData.y = null
+    },
+    signOutOk () {
+      utils.removeSessionData();
+      this.$router.push('/');
+      this.signOutModal = false
+    },
+    signOutCancel () {
+      this.signOutModal = false
+    },
+  },  
 };
 </script>
 <style scoped lang="stylus">
-.all {
-  width: 100px;
-  height: 200px;
+.header {
+  width: 100%;
+  height: 90px;
+  background: linear-gradient(180deg, #06215F, #0D429E);
+  display: flex;
+}
+.menu-list {
+  height: 100%;
+  display: flex;
+  flex: 1;
+  align-items: center;
+}
+.logo {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  margin-right: 30px;
+}
+.nav-item {
+  width: 96px;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  font-size: 14px;
+  font-weight: bold;
+  color: #F1F1F1;
+  cursor: pointer;
+}
+.active {
+  background: linear-gradient(0deg, rgba(1, 133, 234, 0.6), rgba(21, 51, 107, 0.06));
+  border-bottom: 3px solid #259FF8;
+}
+.menu-right {
+  display: flex;
+  align-items: center;
+  color: #FFFFFF;
+}
+.portrait {
+  display: flex;
+  align-items: center;
+  height: 100%;
+  padding-left: 12px;
+  p {
+    display: flex;
+    flex-direction: column;
+    margin-left: 12px;
+    .portrait-name {
+      font-size: 16px;
+    }
+    .portrait-role {
+      font-size: 12px;
+    }
+  }
+}
+.sign-out {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  padding: 0 35px;
+  cursor: pointer;
+}
+.sign-out-text {
+  font-size: 16px;
+  padding-left: 12px;
+}
+>>> .iconfont {
+  font-size: 30px;
+  color: #F1F1F1;
 }
-// .container
-//   height: 100px
 </style>

+ 133 - 3
src/views/homecomponents/Nav.vue

@@ -1,24 +1,154 @@
 <template>
-  <div class="container">
-    侧边栏
+  <div class="nav">
+    <Menu ref='leftMenu' accordion :active-name="activeName" @on-select='getPathName' @on-open-change="getOpenChange" :open-names="openname">
+      <div class="menuli" v-for="item of data" :key="item.menuId">
+        <MenuItem :name="item.linkUrl" :to="item.linkUrl" v-if="!item.childMenus"  >
+        <i class="iconfont" :class="item.imageUrl"></i>{{item.menuName}}
+        </MenuItem>
+        <Submenu :key="item.menuId" :name="item.menuName" v-if="item.childMenus" class="menu-submenu-title">
+          <template slot="title">
+            <i class="iconfont" :class="item.imageUrl" style="margin-right:6px"></i>{{item.menuName}}
+          </template>
+          <MenuItem class="menuli" v-for="item1 of item.childMenus" :key="item1.menuId" :name="item1.linkUrl" :to="item1.linkUrl">
+            {{item1.menuName}}
+          </MenuItem>
+        </Submenu>
+      </div>
+    </Menu>
   </div>
 </template>
 <script>
+import utils from '../../libs/utils';
 export default {
   name: "Nav",
+  props: ['menuId'],
   components:{
   },
   data() {
+    const {currRouterName, leftMenus} = utils.toRouter();
     return {
+      data: leftMenus,
+      activeName: currRouterName,
+      menus: [],
+      activeId: 0,
+      openname: [],
+      // menuNameArr: []
     };
   },
+  watch: {
+      menuId: function (id, oldId) {
+       const {currRouterName, leftMenus} = utils.toRouter(id);
+        if(sessionStorage.getItem('routname')){
+          this.activeName = sessionStorage.getItem('routname')
+        } else {
+          this.activeName = currRouterName;
+        }
+        this.data = leftMenus;
+        // 设置子级菜单关闭
+        // this.openname = []
+        if (oldId == 0) {
+          this.data.forEach((val,inx)=> {
+            if (val.childMenus) {
+               val.childMenus.forEach((v,i) => {
+                if (v.linkUrl == this.activeName) {
+                  this.openname = [val.menuName]  // 页面刷新记住子集菜单展开或关闭
+                }
+               })
+            }
+          })
+        } else {
+          this.openname = [] // 默认关闭子级菜单
+        }
+        // Update the DOM by 
+        // if (this.$store.state.app.siderbar.opened) {
+          this.$nextTick(() => {
+            this.$refs.leftMenu.updateOpened();
+            this.$refs.leftMenu.updateActiveName();
+          })
+        // }
+      },
+       // 菜单左侧浏览器前进或后退
+      '$route' (to, from) {  
+        this.activeName = to.path
+      }
+    },
   mounted() {
+    this.menus= utils.storage('sw_user').menus;
   },
   methods: {
+    //选择菜单(MenuItem)时触发
+    getPathName(routname){
+      let menuNameArr = []
+      this.activeName = routname
+      this.menus.forEach((item,i) => {
+        if (item.childMenus) {
+          item.childMenus.forEach((val,index) => {
+            if (val.linkUrl == routname) {
+                this.activeId = val.parentMenuId 
+                menuNameArr.push(item.menuName) 
+                menuNameArr.push(val.menuName)
+            }
+            if (val.childMenus) {
+              val.childMenus.forEach((last,lastIndex) => {
+                if (last.linkUrl == routname) {
+                  menuNameArr.push(item.menuName) 
+                  menuNameArr.push(val.menuName)
+                  menuNameArr.push(last.menuName)
+                }
+              })
+            }
+          })
+        }
+     })
+     this.$emit('getMenuName',this.menuNameArr);
+     sessionStorage.setItem('routname', routname);
+     sessionStorage.setItem('menuNameArr',JSON.stringify(menuNameArr));
+    },
+    //当 展开/收起 子菜单时触发
+    getOpenChange(name) {
+        // 设置子级菜单展开
+      this.openname = name
+    },
    
   }
 };
 </script>
 <style scoped lang="stylus">
-
+.nav {
+  width: 250px;
+  // height: calc(100vh - 90px);
+  height: 100%;
+  background: linear-gradient(0deg, #162D60, #153876, #091B44);
+}
+>>> .ivu-menu {
+  width: 100% !important;
+  background: #122750;
+  color: #F2F2F2;
+  font-size: 16px;
+}
+>>> .ivu-menu .menuli{
+   height: 55px;
+}
+>>> .ivu-menu .ivu-menu-item {
+  font-size: 16px;
+  height: 100%;
+}
+>>> .ivu-menu-vertical .ivu-menu-item:hover, .ivu-menu-vertical .ivu-menu-submenu-title:hover { 
+  background: #2E4E89;
+  color: #F2F2F2;
+}
+.ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu) {
+  background: #0185EA;
+  color: #F2F2F2;
+  font-size: 16px;
+}
+>>> .ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu):after {
+  width: 0;
+}
+>>> .ivu-menu-vertical.ivu-menu-light:after  {
+  width: 0;
+}
+>>> .iconfont {
+  font-size: 18px;
+}
 </style>

+ 25 - 4
vue.config.js

@@ -4,10 +4,10 @@ module.exports = {
       host:'0.0.0.0',
       port:8000, // 服务端口 
       // port:8080,
-      open: true,//配置自动启动浏览器 
+      open: false,//配置自动启动浏览器 
       proxy: { // 设置代理
       '/metroapi': {
-        target: 'http://192.168.20.58:8086',//
+        target: 'http://192.168.20.247:8088',// http://192.168.20.58:8086
         changeOrigin: true, //允许跨域
         pathRewrite: {
             '^/metroapi': ''
@@ -34,9 +34,30 @@ module.exports = {
         .options({
           remUnit: 192,
           remPrecision: 8
-        }) // remUnit: 192代表以1920px为整体,如果设计稿的尺寸是750px,这里的值为75
+        })
         .end()
-    }
+    },
+    css: {
+      loaderOptions: {
+          postcss: {
+              plugins: [
+                  require('postcss-plugin-px2rem')({
+                      rootValue: 192, //换算基数, 默认100  ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多上px了。
+                      unitPrecision: 10, //允许REM单位增长到的十进制数字。
+                      //propWhiteList: [],  //默认值是一个空数组,这意味着禁用白名单并启用所有属性。
+                      // propBlackList: [], //黑名单
+                      exclude: /(node_module)/, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)\/如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
+                      // selectorBlackList: [], //要忽略并保留为px的选择器
+                      // ignoreIdentifier: false,  //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
+                      // replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
+                      mediaQuery: false, //(布尔值)允许在媒体查询中转换px。
+                      minPixelValue: 0 //设置要替换的最小像素值(3px会被转rem)。 默认 0
+                  }),
+              ]
+          },
+      }
+  }
+    
     // chainWebpack: (config) => {
     //   config.entry('main').add('babel-polyfill');
     // },

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů