소스 검색

底层框架优化/路由配置修改/请求拦截配置调整

fanghuisheng 1 주 전
부모
커밋
f228532dc0

+ 6 - 1
.eslintrc.js

@@ -5,11 +5,16 @@ module.exports = {
   },
   extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier'],
   parserOptions: {
-    parser: 'babel-eslint',
+    parser: '@babel/eslint-parser', // 解析 Vue 中的 ES6+ 语法
+    ecmaVersion: 'latest',
+    sourceType: 'module'
   },
   rules: {
     "prettier/prettier": "off",
     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
     'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
   },
+  plugins: [
+    'vue' // 启用 Vue 插件
+  ],
 }

+ 1 - 1
.gitignore

@@ -1,7 +1,7 @@
 .DS_Store
 node_modules
 dist
-# .history
+.history
 package-lock.json
 sh.exe.stackdump
 .browserslistrc

+ 0 - 1
mock/index.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 导入所有 controller 模块,npm run serve时在node环境中自动输出controller文件夹下Mock接口,请勿修改。
  */
 

+ 0 - 2
mock/utils/index.js

@@ -3,7 +3,6 @@ const { join } = require('path')
 const fs = require('fs')
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 随机生成图片url。
  * @param width
  * @param height
@@ -14,7 +13,6 @@ function handleRandomImage(width = 50, height = 50) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 处理所有 controller 模块,npm run serve时在node环境中自动输出controller文件夹下Mock接口,请勿修改。
  * @returns {[]}
  */

+ 15 - 12
package.json

@@ -13,7 +13,7 @@
     "deploy": "start ./deploy.sh"
   },
   "dependencies": {
-    "ant-design-vue": "2.0.0-rc.9",
+    "ant-design-vue": "4.2.6",
     "axios": "^0.21.1",
     "clipboard": "^2.0.6",
     "core-js": "^3.8.3",
@@ -24,16 +24,16 @@
     "js-cookie": "^3.0.0-rc.1",
     "mockjs": "^1.1.0",
     "remixicon": "^2.5.0",
-    "video.js": "^7.17.0",
-    "videojs-contrib-hls": "^5.15.0",
+    "hls.js": "^1.4.12",
+    "video.js": "^8.23.3",
     "vue": "^3.2.18",
     "vue-router": "^4.0.3",
     "vuex": "^4.0.0"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "^4.5.9",
-    "@vue/cli-plugin-eslint": "^4.5.9",
-    "@vue/cli-service": "^4.5.9",
+    "@vue/cli-plugin-babel": "^5.0.8",
+    "@vue/cli-plugin-eslint": "^5.0.8",
+    "@vue/cli-service": "^5.0.8",
     "@vue/compiler-sfc": "^3.0.5",
     "@vue/eslint-config-prettier": "^6.0.0",
     "babel-eslint": "^11.0.0-beta.2",
@@ -43,21 +43,24 @@
     "eslint": "^7.19.0",
     "eslint-plugin-prettier": "^3.3.1",
     "eslint-plugin-vue": "^7.5.0",
-    "filemanager-webpack-plugin": "^3.1.0",
+    "filemanager-webpack-plugin": "^6.1.3",
     "image-webpack-loader": "^8.1.0",
     "less": "^4.1.1",
-    "less-loader": "^7.3.0",
+    "less-loader": "^10.2.0",
     "lint-staged": "^10.5.3",
-    "node-sass": "^4.14.1",
+    "node-sass": "^6.0.1",
+    "path-browserify": "^1.0.1",
     "prettier": "^2.2.1",
     "sass": "^1.42.1",
-    "sass-loader": "^8.0.2",
+    "sass-loader": "^12.6.0",
     "stylelint": "^13.9.0",
     "stylelint-config-prettier": "^8.0.2",
     "stylelint-config-recess-order": "^2.3.0",
-    "svg-sprite-loader": "^5.2.1",
+    "svg-sprite-loader": "^6.0.11",
     "vab-config": "0.0.8",
-    "webpackbar": "^5.0.0-3"
+    "webpack": "^5.99.9",
+    "webpack-cli": "^4.10.0",
+    "webpackbar": "^5.0.2"
   },
   "gitHooks": {
     "pre-commit": "lint-staged"

+ 4 - 33
src/App.vue

@@ -1,37 +1,8 @@
 <template>
   <router-view />
 </template>
-<script>
-import { defineComponent, watchEffect } from 'vue'
-// import {useRouter} from 'vue-router'
-
-import store from '@/store'
-
-export default defineComponent({
-  setup() {
-    // let router = useRouter();
-
-    watchEffect((fn, options) => {
-      fn, options
-      var hasToken = store.getters['user/accessToken']
-
-      if (!hasToken) {
-        // router.push({
-        //   path: '/login',
-        // })
-      }
-
-      if (hasToken) {
-        store.commit('publicSiteList') //获取站点下拉信息
-      }
-    })
-    return {
-      store,
-    }
-  },
-})
-</script>
-
-<style lang="less">
-@import '~@/vab/styles/vab.less';
+<script></script>
+<style lang="scss">
+  @import '@/assets/css/variables.module.scss';
+  @import '@/assets/css/index.scss';
 </style>

+ 147 - 27
src/assets/css/index.scss

@@ -1,8 +1,27 @@
-// @import './variables.scss';
-// @import './mixin.scss';
-// @import './transition.scss';
-// @import './element-variables.scss';
-// @import './sidebar.scss';
+html {
+    body {
+        * {
+            box-sizing: border-box;
+        }
+
+        /* ant-input-search搜索框 */
+        .ant-input-search {
+            max-width: 250px;
+        }
+
+        /* ant-pagination分页 */
+        .ant-pagination {
+            margin-top: $vab-margin;
+            text-align: center;
+
+            &.ant-table-pagination {
+                float: none !important;
+                margin-top: $vab-margin;
+            }
+        }
+    }
+}
+
 body {
     height: 100%;
     -moz-osx-font-smoothing: grayscale;
@@ -117,7 +136,7 @@ ul li {
 }
 
 .delete-text {
-    color: #F80000!important
+    color: #F80000 !important
 }
 
 .remarksTxt {
@@ -138,16 +157,17 @@ ul li {
 
 .filter-container {
     width: 100%;
-    height: 100%;
     display: flex;
     -webkit-box-pack: justify;
     -webkit-justify-content: space-between;
     -ms-flex-pack: justify;
     justify-content: space-between;
     vertical-align: middle;
+
     .el-button+.el-button {
-        margin-left: 30px!important;
+        margin-left: 30px !important;
     }
+
     .filter-item {
         margin-right: 30px;
         display: inline-block;
@@ -155,6 +175,11 @@ ul li {
     }
 }
 
+.ant-layout-header {
+    height: $vab-header-height !important;
+    line-height: $vab-header-height !important;
+}
+
 .el-input__inner {
     height: 36px;
     line-height: 36px
@@ -165,7 +190,7 @@ ul li {
 }
 
 .el-table--small {
-    font-size: 14px!important
+    font-size: 14px !important
 }
 
 .el-table td,
@@ -192,6 +217,7 @@ ul li {
     padding: 10px 20px 30px 20px;
     text-align: center;
     position: relative;
+
     .goBack {
         position: absolute;
         left: 0;
@@ -229,7 +255,7 @@ ul li {
 .basic-info-page,
 .powerScore {
     .el-form-item {
-        margin-left: 0px!important
+        margin-left: 0px !important
     }
 }
 
@@ -267,6 +293,7 @@ ul li {
 }
 
 .planOutage {
+
     .el-date-editor.el-input,
     .el-date-editor.el-input__inner {
         width: 100%;
@@ -297,16 +324,16 @@ ul li {
 }
 
 .el-upload-list--picture-card .el-upload-list__item {
-    width: 92px!important;
-    height: 92px!important;
-    line-height: 92px!important;
+    width: 92px !important;
+    height: 92px !important;
+    line-height: 92px !important;
     text-align: center
 }
 
 .el-upload-list--picture-card .el-upload-list__item-thumbnail {
-    width: 90px!important;
-    height: 90px!important;
-    line-height: 90px!important;
+    width: 90px !important;
+    height: 90px !important;
+    line-height: 90px !important;
 }
 
 .avatar {
@@ -320,9 +347,11 @@ ul li {
     .el-form-item__content {
         width: 270px
     }
+
     .el-form-item__label {
-        width: 150px!important
+        width: 150px !important
     }
+
     .el-form-item__content {
         // margin-left: 150px!important
     }
@@ -337,6 +366,7 @@ ul li {
     .el-button+.el-button {
         margin-left: 20px !important;
     }
+
     .el-input {
         margin: 0 20px 0 0;
     }
@@ -362,12 +392,12 @@ ul li {
 // 告警管理渐变背景色
 .alarmingTable {
     a {
-        margin-right: 0!important;
+        margin-right: 0 !important;
     }
 }
 
 .alarmingManage .el-table .cell {
-    text-align: left!important;
+    text-align: left !important;
 }
 
 .gradualBg {
@@ -382,7 +412,7 @@ ul li {
 }
 
 .gradualBg.transparent {
-    background: linear-gradient(to right, transparent, transparent)!important;
+    background: linear-gradient(to right, transparent, transparent) !important;
 }
 
 //告警详情弹框组件
@@ -390,17 +420,20 @@ ul li {
     .el-form-item:not(.user-layout .el-form-item) {
         margin-bottom: 0
     }
+
     .deviceTit {
         font-size: 16px;
         color: #409EFF;
         padding: 20px 0
     }
+
     .basicTit {
         color: #4074e7;
         line-height: 49px;
         height: 49px;
         font-size: 16px
     }
+
     .basicTit:before {
         content: "";
         width: 3px;
@@ -411,9 +444,11 @@ ul li {
         display: inline-block;
         background: #4074e7;
     }
+
     .topInfo {
         position: relative;
         overflow: hidden;
+
         .lubo {
             // position: absolute;
             // right: 0px;
@@ -421,6 +456,7 @@ ul li {
             float: right;
             margin-bottom: 20px;
         }
+
         .handleStatus {
             position: absolute;
             right: 0px;
@@ -475,7 +511,7 @@ ul li {
 
 //评估报告
 .defaultCursor:hover {
-    cursor: default!important;
+    cursor: default !important;
 }
 
 .assePage .blanceChartTit {
@@ -484,6 +520,7 @@ ul li {
     display: flex;
     justify-content: space-between;
     vertical-align: middle;
+
     span {
         display: inline-block
     }
@@ -495,17 +532,21 @@ ul li {
         text-align: center;
         font-weight: bold
     }
+
     .assNum {
         font-size: 18px;
         color: #2EAEFF;
         margin-bottom: 10px;
     }
+
     .greenRate {
         color: #04A522
     }
+
     .assTxt {
         font-size: 14px
     }
+
     .assSmallbox {
         padding: 10px 0;
         text-align: center;
@@ -539,13 +580,14 @@ ul li {
     height: 40px;
     // line-height: 40px;
     width: 236px;
-    font-size: 16px!important;
+    font-size: 16px !important;
     // background: #6dc6ff;
     // color: #fff
 }
 
 .assCard {
-    min-height: 356px!important;
+    min-height: 356px !important;
+
     .noDataImg {
         width: 40%;
         margin-top: 40px;
@@ -556,21 +598,25 @@ ul li {
     text-align: left;
     margin: 0;
     padding: 15px 20px 0;
+
     li:not(:last-child) {
         border-bottom: 1px solid #F0F0F0;
     }
+
     li {
         line-height: 40px;
         display: flex;
         justify-content: space-between;
         vertical-align: middle;
         font-size: 14px;
+
         div {
             display: inline-block;
             white-space: nowrap;
             overflow: hidden;
             text-overflow: ellipsis;
         }
+
         span {
             color: #04A522;
             background: #F4F4F4;
@@ -582,6 +628,7 @@ ul li {
             width: 58px;
             margin-top: 10px;
         }
+
         span.overLimit {
             color: #F80000
         }
@@ -592,6 +639,7 @@ ul li {
     font-weight: bold;
     text-align: center;
     margin: 30px;
+
     .el-button {
         font-size: 16px;
         margin-left: 10px;
@@ -625,12 +673,14 @@ ul li {
 .loopHarmonicPanel {
     height: 591px;
     overflow: hidden;
+
     .el-row {
-        margin-bottom: 0!important;
+        margin-bottom: 0 !important;
     }
 }
 
 .loopUnbanlanceCard {
+
     // height: calc(100% - 100px);
     ul {
         padding: 0;
@@ -638,12 +688,15 @@ ul li {
         font-size: 14px;
         margin-top: 20px
     }
+
     li {
         display: flex;
+
         >div {
             margin: 2px 4px;
             line-height: 14px;
         }
+
         >div:first-child {
             // min-width: 64px;
         }
@@ -668,25 +721,30 @@ ul li {
 }
 
 .voltagePanel {
+
     .el-table--small th,
     .el-table--small td {
         padding: 15px 0
     }
+
     .uList p {
         margin-right: 10px;
         padding: 8px 0
     }
+
     .shangXian {
         padding: 20px 0 0;
         display: flex;
         width: 300px;
         margin-left: 40px;
         text-align: center;
+
         div {
             width: 50%;
             text-align: center;
             position: relative
         }
+
         div:first-child:after {
             position: absolute;
             top: 0;
@@ -701,6 +759,7 @@ ul li {
             background-color: rgba(0, 0, 0, 0);
             opacity: .2;
         }
+
         div:last-child:before {
             position: absolute;
             top: 0;
@@ -719,13 +778,16 @@ ul li {
 
 .frequencyPanel {
     text-align: center;
+
     .frequencyTit {
         color: #F80000;
         font-weight: bold
     }
+
     .frequencyTit2 {
         font-weight: bold;
         margin: 10px auto;
+
         span {
             color: #fff;
             background: #21c393;
@@ -738,14 +800,17 @@ ul li {
             width: 58px;
         }
     }
+
     .frequencyBox .grid-content {
-        min-height: 50px!important;
+        min-height: 50px !important;
         border-radius: 0;
         background: #f0f0f0;
         border: none;
     }
+
     .rightSplitRed {
         position: relative;
+
         i {
             position: absolute;
             position: absolute;
@@ -753,10 +818,12 @@ ul li {
             bottom: -11px;
             color: #f1673d
         }
+
         i:after {
             display: none
         }
     }
+
     .greenShadow {
         position: absolute;
         width: 118px;
@@ -771,6 +838,7 @@ ul li {
         background-image: gradient(linear, 0 0, 100% 100%, color-stop(.25, hsla(0, 0%, 100%, .2)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, hsla(0, 0%, 100%, .2)), color-stop(.75, hsla(0, 0%, 100%, .2)), color-stop(.75, transparent), to(transparent));
         background-size: 8px 8px
     }
+
     .rightSplitRed .grid-content:after {
         position: absolute;
         bottom: -3px;
@@ -782,9 +850,11 @@ ul li {
         content: "";
         background-color: rgba(0, 0, 0, 0);
     }
+
     .frequencyBox .grid-content {
         border-right: 1px dashed #aaa
     }
+
     .frequencyBox .el-col:last-child .grid-content {
         border-right: none
     }
@@ -797,10 +867,12 @@ ul li {
 }
 
 .powerPanel {
+
     .el-table--small th,
     .el-table--small td {
         padding: 15px 0
     }
+
     .uList p {
         margin-right: 10px;
         padding: 8px 0
@@ -815,12 +887,14 @@ ul li {
 // 工单管理
 .workManage {
     .tab-section .el-button {
-        margin-left: 0!important;
+        margin-left: 0 !important;
         padding: 10px 20px;
     }
+
     .el-checkbox {
         margin-left: 20px
     }
+
     img.jianxiu {
         width: 18px;
         position: relative;
@@ -842,7 +916,7 @@ ul li {
 
 .alarmStatusDialog {
     .el-radio__input.is-checked+.el-radio__label {
-        color: #606266!important
+        color: #606266 !important
     }
 }
 
@@ -859,48 +933,58 @@ ul li {
 // 工单详情
 .handleDetailPage {
     padding: 20px 0;
+
     .basicTit {
         color: #4074e7;
         line-height: 49px;
         height: 49px;
         font-size: 16px;
+
         >span {
             display: inline-block;
             margin-right: 10px
         }
     }
+
     .handleTestBlock {
         padding: 0 20px 20px 20px;
         border-bottom: 3px solid #1890ff;
     }
+
     .jianxiuSec {
         >div {
             display: table-cell;
             vertical-align: top;
         }
+
         .left-img img {
             width: 115px;
             height: 115px;
             margin-right: 20px
         }
+
         .right-des {
             position: relative;
+
             .tit {
                 font-weight: bold;
                 margin: 10px 0
             }
+
             .bottomStatus {
                 position: absolute;
                 bottom: 0;
             }
         }
     }
+
     .desSec {
         span {
             display: inline-block;
             margin-right: 20px
         }
     }
+
     .siteBlock,
     .companyBlock {
         display: inline-block;
@@ -911,6 +995,7 @@ ul li {
         margin-left: 10px;
         text-align: center;
         position: relative;
+
         /*自己的50% */
         >div {
             width: 140px;
@@ -920,22 +1005,27 @@ ul li {
             /* 定位父级的50% */
             top: 50%;
             transform: translate(-50%, -50%);
+
             p:last-child {
                 font-size: 18px;
                 margin-top: 30px
             }
         }
     }
+
     .handlerBlock {
         padding: 20px;
         border-bottom: 1px solid #E5E5E5;
         ;
+
         div {
             margin-bottom: 10px;
         }
+
         i {
             font-size: 16px;
         }
+
         .record {
             span {
                 color: cornflowerblue;
@@ -944,15 +1034,18 @@ ul li {
                 cursor: pointer
             }
         }
+
         b {
             margin: 0 5px;
             display: inline-block;
         }
+
         .imgSquare {
             border: 1px solid #ddd;
             width: 100px;
             height: 100px;
             margin-left: 40px;
+
             img {
                 width: 80%;
                 margin-left: 10%;
@@ -977,43 +1070,54 @@ ul li {
 // 运维统计
 .operStatisticsPage {
     padding: 0;
+
     .el-tabs__content {
         overflow: hidden;
         position: absolute;
         top: -10px;
         left: 614px;
     }
+
     .customBlock {
         position: relative;
+
         .customPicker {
             position: absolute;
             right: 0;
             bottom: 0
         }
     }
+
     .operStatisticsInner {
         padding: 20px;
+
         .bg-purple {
             // background: #d3dce6;
             border: 1px solid #e5e5e5;
         }
+
         .staitcDataSec {
             .staitcDataItem {
                 // text-align: center;
                 padding: 20px 10px;
                 height: 110px;
+
                 .imgBlock {
                     text-align: right;
+
                     img {
                         // max-width: 90%
                     }
                 }
+
                 .staticBlock {
                     // text-align: center
                 }
+
                 p {
                     margin-bottom: 0
                 }
+
                 .num {
                     font-size: 26px;
                     color: #49B8F6;
@@ -1022,6 +1126,7 @@ ul li {
                 }
             }
         }
+
         .panelTit {
             padding: 10px 14px;
             margin-bottom: 10px;
@@ -1029,18 +1134,23 @@ ul li {
             background: #FAFAFA;
             font-weight: bold;
         }
+
         .workPanel {
             height: 311px;
+
             .workPanelChart {
                 height: calc(100% - 60px)
             }
         }
+
         .siteWorkPanel {
             height: 311px;
+
             .siteWorkChart {
                 height: calc(100% - 60px)
             }
         }
+
         .staticPanel {
             height: 365px;
         }
@@ -1055,21 +1165,26 @@ ul li {
         justify-content: space-around;
         line-height: 36px
     }
+
     .el-radio-button {
         width: 100%
     }
+
     .el-radio-button__inner {
         width: 100%;
         // line-height: 40px;
         padding: 13px 15px
     }
+
     .el-radio-button__inner {
         border-left: 1px solid #dcdfe6;
         text-align: left;
         position: relative; // border-bottom: none;
+
         img {
             margin-right: 5px
         }
+
         i {
             position: absolute;
             right: 10px;
@@ -1078,17 +1193,21 @@ ul li {
             opacity: 0
         }
     }
+
     .el-radio-button__inner:hover {
         color: #444;
         background: #f1f7fc;
+
         // border-color: #f1f7fc;
         i {
             opacity: 1;
         }
     }
+
     .el-radio-button:last-child .el-radio-button__inner {
         // border-bottom: 1px solid #dcdfe6;
     }
+
     .el-radio-button__original-radio:checked+.el-radio-button__inner {
         background: #BDE5FF;
         border-color: #BDE5FF;
@@ -1099,6 +1218,7 @@ ul li {
 
 // 用户管理弹框
 .userManageDialog {
+
     .el-date-editor.el-input,
     .el-date-editor.el-input__inner {
         width: 240px !important;

+ 7 - 0
src/assets/css/variables.module.scss

@@ -0,0 +1,7 @@
+$vab-color-blue: #1890ff;
+
+$vab-margin: 20px;
+$vab-padding: 20px;
+$vab-header-height: 54px;
+$vab-breadcrumb-height: 37px;
+$vab-public-height: calc(100vh - 130px);

+ 2 - 0
src/config/default/setting.config.js

@@ -75,5 +75,7 @@ const setting = {
     donation: false,
     //画廊布局和综合布局时,是否点击一级菜单默认开启第一个二级菜单
     openFirstMenu: true,
+    //在发送请求前显示加载提示框,等请求结束后关闭它
+    loadingInstance: null,
 }
 module.exports = setting

+ 151 - 154
src/layout/index.vue

@@ -53,182 +53,179 @@
   </a-layout>
 </template>
 <script>
-import VabLogo from './vab-logo'
-import VabAvatar from './vab-avatar'
-import VabMenu from './vab-menu'
-import VabTabs from './vab-tabs'
-import VabContent from './vab-content'
-import { mapActions, mapGetters } from 'vuex'
-import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'
+  import VabLogo from './vab-logo'
+  import VabAvatar from './vab-avatar'
+  import VabMenu from './vab-menu'
+  import VabTabs from './vab-tabs'
+  import VabContent from './vab-content'
+  import { mapActions, mapGetters } from 'vuex'
+  import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'
 
-export default {
-  components: {
-    VabLogo,
-    VabAvatar,
-    VabMenu,
-    VabTabs,
-    VabContent,
-    MenuUnfoldOutlined,
-    MenuFoldOutlined,
-  },
-  data() {
-    return {
-      selectedKeys: [],
-      openKeys: [],
-    }
-  },
-  computed: {
-    ...mapGetters({
-      collapse: 'settings/collapse',
-      routes: 'routes/routes',
-      device: 'settings/device',
-    }),
-    classObj() {
+  export default {
+    components: {
+      VabLogo,
+      VabAvatar,
+      VabMenu,
+      VabTabs,
+      VabContent,
+      MenuUnfoldOutlined,
+      MenuFoldOutlined,
+    },
+    data() {
       return {
-        'vab-mobile': this.device === 'mobile',
-        'vab-collapse': this.collapse,
+        selectedKeys: [],
+        openKeys: [],
       }
     },
-  },
-  watch: {
-    $route: {
-      handler({ path, matched }) {
-        matched[0].children.length > 1
-          ? (this.selectedKeys = [path])
-          : (this.selectedKeys = [matched[0].path])
-        this.openKeys = [matched[0].path]
+    computed: {
+      ...mapGetters({
+        collapse: 'settings/collapse',
+        routes: 'routes/routes',
+        device: 'settings/device',
+      }),
+      classObj() {
+        return {
+          'vab-mobile': this.device === 'mobile',
+          'vab-collapse': this.collapse,
+        }
       },
-      immediate: true,
     },
-  },
-  beforeMount() {
-    window.addEventListener('resize', this.handleLayouts)
-  },
-  beforeUnmount() {
-    window.removeEventListener('resize', this.handleLayouts)
-  },
-  mounted() {
-    this.handleLayouts()
-  },
-  methods: {
-    ...mapActions({
-      toggleDevice: 'settings/toggleDevice',
-      handleFoldSideBar: 'settings/foldSideBar',
-      toggleCollapse: 'settings/toggleCollapse',
-    }),
-    handleLayouts() {
-      const width = document.body.getBoundingClientRect().width
-      if (this.width !== width) {
-        const isMobile = width - 1 < 992
-        this.toggleDevice(isMobile ? 'mobile' : 'desktop')
-        this.width = width
-      }
+    watch: {
+      $route: {
+        handler({ path, matched }) {
+          matched[0].children.length > 1
+            ? (this.selectedKeys = [path])
+            : (this.selectedKeys = [matched[0].path])
+          this.openKeys = [matched[0].path]
+        },
+        immediate: true,
+      },
+    },
+    beforeMount() {
+      window.addEventListener('resize', this.handleLayouts)
+    },
+    beforeUnmount() {
+      window.removeEventListener('resize', this.handleLayouts)
+    },
+    mounted() {
+      this.handleLayouts()
+    },
+    methods: {
+      ...mapActions({
+        toggleDevice: 'settings/toggleDevice',
+        handleFoldSideBar: 'settings/foldSideBar',
+        toggleCollapse: 'settings/toggleCollapse',
+      }),
+      handleLayouts() {
+        const width = document.body.getBoundingClientRect().width
+        if (this.width !== width) {
+          const isMobile = width - 1 < 992
+          this.toggleDevice(isMobile ? 'mobile' : 'desktop')
+          this.width = width
+        }
+      },
     },
-  },
-}
+  }
 </script>
-<style lang="less">
-.vab-layout-wrap {
-  height: 100%;
+<style lang="scss">
+  .vab-layout-wrap {
+    height: 100%;
 
-  .vab-sider {
-    background-color: #fff;
-    position: fixed;
-    left: 0;
-    height: 100vh;
-    overflow: auto;
-    .vab-menu {
-      overflow-y: auto;
-      height: calc(100vh - @vab-header-height);
-      li {
-        margin-top: 0px;
+    .vab-sider {
+      background-color: #fff;
+      position: fixed;
+      left: 0;
+      height: 100vh;
+      overflow: auto;
+      .vab-menu {
+        overflow-y: auto;
+        height: calc(100vh - $vab-header-height);
+      }
+      .vab-menu::-webkit-scrollbar {
+        display: none;
       }
     }
-    .vab-menu::-webkit-scrollbar {
-      display: none;
-    }
-  }
-  .vab-layout {
-    height: 100%;
-    overflow: auto;
-    padding-left: 220px;
-    transition: all 0.2s;
-    background-color: #f0f3f4;
-  }
-  .vab-mobile-layout {
-    padding-left: 0;
-    transition: all 0.2s;
-  }
-  .vab-collapse {
-    .vab-logo .anticon + span {
-      display: inline-block;
-      max-width: 0;
-      opacity: 0;
+    .vab-layout {
+      height: 100%;
+      overflow: auto;
+      padding-left: 220px;
       transition: all 0.2s;
+      background-color: #f0f3f4;
     }
-    & + .vab-layout {
-      padding-left: 81px;
+    .vab-mobile-layout {
+      padding-left: 0;
       transition: all 0.2s;
     }
-  }
-  .vab-mask {
-    position: fixed;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    left: 0;
-    z-index: 998;
-    width: 100%;
-    height: 100vh;
-    overflow: hidden;
-    background: #000;
-    opacity: 0.5;
-  }
-  .vab-mobile {
-    position: fixed !important;
-    z-index: 999;
-    &.vab-collapse {
-      width: 0 !important;
-      min-width: 0 !important;
-      max-width: 0 !important;
-      * {
-        display: none !important;
-        width: 0 !important;
-        min-width: 0 !important;
-        max-width: 0 !important;
-      }
-      .ant-menu-item,
-      .ant-menu-submenu {
-        display: none !important;
-        width: 0 !important;
-        min-width: 0 !important;
-        max-width: 0 !important;
+    .vab-collapse {
+      .vab-logo .anticon + span {
+        display: inline-block;
+        max-width: 0;
+        opacity: 0;
+        transition: all 0.2s;
       }
       & + .vab-layout {
-        padding-left: 0px !important;
+        padding-left: 81px;
         transition: all 0.2s;
       }
     }
-  }
-  .vab-header {
-    padding: 0;
-    background: #fff;
-    .ant-col + .ant-col {
-      display: flex;
-      justify-content: flex-end;
-      padding: 0 @vab-padding;
+    .vab-mask {
+      position: fixed;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      left: 0;
+      z-index: 998;
+      width: 100%;
+      height: 100vh;
+      overflow: hidden;
+      background: #000;
+      opacity: 0.5;
+    }
+    .vab-mobile {
+      position: fixed !important;
+      z-index: 999;
+      &.vab-collapse {
+        width: 0 !important;
+        min-width: 0 !important;
+        max-width: 0 !important;
+        * {
+          display: none !important;
+          width: 0 !important;
+          min-width: 0 !important;
+          max-width: 0 !important;
+        }
+        .ant-menu-item,
+        .ant-menu-submenu {
+          display: none !important;
+          width: 0 !important;
+          min-width: 0 !important;
+          max-width: 0 !important;
+        }
+        & + .vab-layout {
+          padding-left: 0px !important;
+          transition: all 0.2s;
+        }
+      }
     }
-    .trigger {
-      height: @vab-header-height;
-      padding: 0 @vab-padding;
-      font-size: 18px;
-      line-height: @vab-header-height;
-      cursor: pointer;
-      transition: color 0.3s;
-      &:hover {
-        color: #1890ff;
+    .vab-header {
+      padding: 0;
+      background: #fff;
+      .ant-col + .ant-col {
+        display: flex;
+        justify-content: flex-end;
+        padding: 0 $vab-padding;
+      }
+      .trigger {
+        height: $vab-header-height;
+        padding: 0 $vab-padding;
+        font-size: 18px;
+        line-height: $vab-header-height;
+        cursor: pointer;
+        transition: color 0.3s;
+        &:hover {
+          color: #1890ff;
+        }
       }
     }
   }
-}
 </style>

+ 68 - 70
src/layout/vab-avatar/index.vue

@@ -1,19 +1,9 @@
 <template>
   <div class="vab-avatar" style="display: flex">
-    <span
-      style="
-        height: 54px;
-        line-height: 54px;
-        margin-right: 30px;
-        font-size: 17px;
-      "
-    >
-      {{ time }}
-    </span>
+    <span class="time">{{ time }}</span>
     <a-dropdown>
       <span class="ant-dropdown-link">
         <!-- <a-avatar :src="avatar" /> -->
-
         <img
           src="https://i.gtimg.cn/club/item/face/img/2/15922_100.gif"
           alt=""
@@ -21,8 +11,8 @@
             background: #ccc;
             width: 32px;
             height: 32px;
-            line-height:32px;
-            border-radius:50%;
+            line-height: 32px;
+            border-radius: 50%;
           "
         />
         {{ username }}
@@ -38,66 +28,74 @@
 </template>
 
 <script>
-import { recordRoute } from '@/config'
-import { DownOutlined } from '@ant-design/icons-vue'
-import { useStore } from 'vuex'
-
-import { mapGetters } from 'vuex'
-export default {
-  name: 'VabAvatar',
-  components: { DownOutlined },
-  computed: {
-    ...mapGetters({
-      avatar: 'https://i.gtimg.cn/club/item/face/img/2/15922_100.gif',
-      username: 'user/username',
-    }),
-  },
-  data() {
-    return {
-      time: '',
-    }
-  },
-  mounted() {
-    const store = useStore()
-    setInterval(() => {
-      store.commit('getTimeAll')
-      var time = store.state.Time_All
-      this.time =
-        time[0] +
-        '年' +
-        (time[1] < 9 ? '0' + (time[1] + 1) : time[1] + 1) +
-        '月' +
-        (time[2] < 10 ? '0' + time[2] : time[2]) +
-        '日 ' +
-        (time[3] < 10 ? '0' + time[3] : time[3]) +
-        ':' +
-        (time[4] < 10 ? '0' + time[4] : time[4]) +
-        ':' +
-        (time[5] < 10 ? '0' + time[5] : time[5])
-    }, 0)
-  },
-  methods: {
-    async logout() {
-      await this.$store.dispatch('user/logout')
-      if (recordRoute) {
-        // const fullPath = this.$route.fullPath
-        // this.$router.push(`/login?redirect=${fullPath}`)
+  import { recordRoute } from '@/config'
+  import { DownOutlined } from '@ant-design/icons-vue'
+  import { useStore } from 'vuex'
 
-        this.$router.push('/login')
-      } else {
-        this.$router.push('/login')
+  import { mapGetters } from 'vuex'
+  export default {
+    name: 'VabAvatar',
+    components: { DownOutlined },
+    computed: {
+      ...mapGetters({
+        avatar: 'https://i.gtimg.cn/club/item/face/img/2/15922_100.gif',
+        username: 'user/username',
+      }),
+    },
+    data() {
+      return {
+        time: '',
       }
     },
-  },
-}
+    mounted() {
+      const store = useStore()
+      setInterval(() => {
+        store.commit('getTimeAll')
+        var time = store.state.Time_All
+        this.time =
+          time[0] +
+          '年' +
+          (time[1] < 9 ? '0' + (time[1] + 1) : time[1] + 1) +
+          '月' +
+          (time[2] < 10 ? '0' + time[2] : time[2]) +
+          '日 ' +
+          (time[3] < 10 ? '0' + time[3] : time[3]) +
+          ':' +
+          (time[4] < 10 ? '0' + time[4] : time[4]) +
+          ':' +
+          (time[5] < 10 ? '0' + time[5] : time[5])
+      }, 0)
+    },
+    methods: {
+      async logout() {
+        await this.$store.dispatch('user/logout')
+
+        if (recordRoute) {
+          // const fullPath = this.$route.fullPath
+          // this.$router.push(`/login?redirect=${fullPath}`)
+
+          this.$router.push('/login')
+        } else {
+          this.$router.push('/login')
+        }
+      },
+    },
+  }
 </script>
-<style lang="less">
-.vab-avatar {
-  .ant-dropdown-link {
-    display: block;
-    min-height: @vab-header-height;
-    cursor: pointer;
-    line-height: @vab-header-height;
+<style lang="scss">
+  .vab-avatar {
+    .time {
+      height: $vab-header-height;
+      line-height: $vab-header-height;
+      margin-right: 30px;
+      font-size: 17px;
+    }
+
+    .ant-dropdown-link {
+      display: block;
+      min-height: $vab-header-height;
+      cursor: pointer;
+      line-height: $vab-header-height;
+    }
   }
-}
 </style>

+ 9 - 9
src/layout/vab-content/index.vue

@@ -24,7 +24,7 @@ export default {
 }
 </script>
 
-<style lang="less">
+<style lang="scss">
 .fade-transform-leave-active,
 .fade-transform-enter-active {
   transition: all 0.2s;
@@ -43,20 +43,20 @@ export default {
 .vab-content {
   overflow-y: auto;
   // min-height: calc(
-  //   100vh - @vab-header-height - @vab-padding - @vab-padding - @vab-padding -
-  //     @vab-padding
+  //   100vh - $vab-header-height - $vab-padding - $vab-padding - $vab-padding -
+  //     $vab-padding
   // ) !important;
   // max-height: calc(
-  //   100vh - @vab-header-height - @vab-padding - @vab-padding - @vab-padding -
-  //     @vab-padding
+  //   100vh - $vab-header-height - $vab-padding - $vab-padding - $vab-padding -
+  //     $vab-padding
   // ) !important;
-  // padding: @vab-padding;
-  margin: @vab-margin;
+  // padding: $vab-padding;
+  margin: $vab-margin;
   // background: #fff;
   .error-container {
     height: calc(
-      100vh - @vab-header-height - @vab-padding - @vab-padding - @vab-padding -
-        @vab-padding - @vab-padding - @vab-margin
+      100vh - $vab-header-height - $vab-padding - $vab-padding - $vab-padding -
+        $vab-padding - $vab-padding - $vab-margin
     ) !important;
   }
 }

+ 26 - 25
src/layout/vab-logo/index.vue

@@ -10,31 +10,32 @@
 </template>
 
 <script>
-import { computed } from 'vue'
-import { useStore, mapGetters } from 'vuex'
+  import { computed } from 'vue'
+  import { useStore, mapGetters } from 'vuex'
 
-export default {
-  name: 'VabLogo',
-  computed: {
-    ...mapGetters({
-      collapse: 'settings/collapse',
-      routes: 'routes/routes',
-      device: 'settings/device',
-    }),
-  },
-  setup() {
-    const store = useStore()
-    return {
-      collapsed: false,
-      logo: computed(() => store.getters['settings/logo']),
-      title: computed(() => store.getters['settings/title']),
-    }
-  },
-}
+  export default {
+    name: 'VabLogo',
+    computed: {
+      ...mapGetters({
+        collapse: 'settings/collapse',
+        routes: 'routes/routes',
+        device: 'settings/device',
+      }),
+    },
+    setup() {
+      const store = useStore()
+      return {
+        collapsed: false,
+        logo: computed(() => store.getters['settings/logo']),
+        title: computed(() => store.getters['settings/title']),
+      }
+    },
+  }
 </script>
-<style lang="less" scoped>
-.vab-logo {
-  text-align: center;
-  margin: 10px 5px;
-}
+<style lang="scss" scoped>
+  .vab-logo {
+    height: $vab-header-height;
+    line-height: $vab-header-height;
+    text-align: center;
+  }
 </style>

+ 2 - 2
src/layout/vab-menu/components/MenuItem.vue

@@ -1,5 +1,5 @@
 <template>
-  <a-menu-item :key="routeChildren.path" @click.capture="handleLink" >
+  <a-menu-item :key="routeChildren.path" @click.capture="handleLink">
     <span class="anticon">
       <!-- <vab-icon :icon="routeChildren.meta.icon"></vab-icon> -->
       <svg-icon :iconClass="routeChildren.meta.icon"></svg-icon>
@@ -13,7 +13,7 @@
   // import VabIcon from '@/layout/vab-icon'
   export default {
     name: 'MenuItem',
-    components: {  },
+    components: {},
     props: {
       item: {
         type: Object,

+ 5 - 5
src/layout/vab-tabs/index.vue

@@ -197,14 +197,14 @@ export default {
   },
 }
 </script>
-<style lang="less">
+<style lang="scss">
 .vab-tabs {
-  padding: 0 @vab-margin;
+  padding: 0 $vab-margin;
   background: #ffffff;
   overflow: hidden;
   &-left-panel {
     float: left;
-    width: calc(100% - 52px - @vab-margin - @vab-margin);
+    width: calc(100% - 52px - $vab-margin - $vab-margin);
   }
   &-right-panel {
     float: left;
@@ -234,8 +234,8 @@ export default {
     }
   }
   // .el-breadcrumb {
-  //   height: @vab-breadcrumb-height;
-  //   line-height: @vab-breadcrumb-height;
+  //   height: $vab-breadcrumb-height;
+  //   line-height: $vab-breadcrumb-height;
   // }
   .el-breadcrumb {
     height:36px;

+ 9 - 52
src/main.js

@@ -3,72 +3,29 @@ import Antd from 'ant-design-vue'
 import App from './App'
 import router from './router'
 import store from './store'
-import 'ant-design-vue/dist/antd.css'
+import 'ant-design-vue/dist/reset.css'
 import '@/vab'
-
 import 'default-passive-events'
 
 // 引入 ElementUI
 import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
 import zhCn from 'element-plus/lib/locale/lang/zh-cn' // 中文
-import '@/assets/css/index.scss'
-import '@/assets/css/global.scss'
 import * as echarts from 'echarts';
 
 import '@/assets/icons'
 import SvgIcon from "@/components/SvgIcon"
 
 import 'video.js/dist/video-js.css'
+import './permissions.js'
 
-/**
- * @author chuzhixin 1204505056@qq.com
- * @description 正式环境默认使用mock,正式项目记得注释后再打包
- */
-// if (process.env.NODE_ENV === 'production') {
-//   const { mockXHR } = require('@/utils/static')
-//   mockXHR()
-// }
-
-var app = createApp(App)
+const app = createApp(App)
 
 app.config.globalProperties.$echarts = echarts
 
-app
-    .component("svg-icon", SvgIcon)
-    .use(store)
-    .use(router)
-    .use(ElementPlus, { locale: zhCn, size: 'small' })
-    .use(Antd)
-    .mount('#app')
-
-
-/**
- * @需添加路由拦截 --登录后执行
- */
-
-
-router.beforeEach((to) => {
-    // console.log(to.meta.title)
-    store.commit('getAuthorities', to.meta.title)
-    // console.log('store.state.authorities')
-    // console.log(store.state.authorities)
-
-    if (to.path != '/login') {
-        store.commit("publicSiteList");
-        store.commit('publicDeviceList')
-    }
-    if (to.path == '/home') {
-        if (window.location.host.indexOf('localhost') != -1) {
-            window.location.href = "http://localhost:8081/vuefiv#/home";
-        } else if (window.location.host.indexOf('pcdev.ewoogi.com') != -1) {
-            window.location.href = "https://pcdev.ewoogi.com/vuefiv#/home";
-        } else {
-            window.location.href = "https://wx.ewoogi.com/panel/#/home";
-        }
-    }
-})
-
-router.afterEach((to) => {
-    to
-})
+app.use(router)
+app.use(store)
+app.use(ElementPlus, { locale: zhCn, size: 'small' })
+app.use(Antd)
+app.component("svg-icon", SvgIcon)
+app.mount('#app')

+ 37 - 31
src/vab/plugins/permissions.js → src/permissions.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 路由守卫,目前两种模式:all模式与intelligence模式
  */
 import router from '@/router'
@@ -12,37 +11,42 @@ import {
     routesWhiteList,
 } from '@/config'
 
-router.beforeEach(async(to, from, next) => {
-
+router.beforeEach(async (to, from, next) => {
     let hasToken = store.getters['user/accessToken']
 
+    if (to.path !== '/login') store.commit('getAuthorities', to.meta.title)
     if (!loginInterception) hasToken = true
-    console.log(localStorage.getItem('accessToken'))
-    console.log(localStorage.getItem('accessToken'))
+
     if (hasToken) {
         if (to.path === '/login') {
             next({ path: '/' })
+        } else if (to.path == '/home') {
+            if (window.location.host.indexOf('localhost') != -1) {
+                window.location.href = "http://localhost:8081/vuefiv#/home";
+            } else if (window.location.host.indexOf('pcdev.ewoogi.com') != -1) {
+                window.location.href = "https://pcdev.ewoogi.com/vuefiv#/home";
+            } else {
+                window.location.href = "https://wx.ewoogi.com/panel/#/home";
+            }
         } else {
-
             const hasRoles =
                 store.getters['acl/admin'] ||
                 store.getters['acl/role'].length > 0 ||
                 store.getters['acl/ability'].length > 0
+
             if (hasRoles) {
-                // console.log('to.matched')
-                // console.log(to.matched)
                 if (to.matched.length === 0) {
-                    // alert('没有匹配')
                     next('/404') // 判断此跳转路由的来源路由是否存在,存在的情况跳转到来源路由,否则跳转到404页面
+                    return;
                 }
                 next()
             } else {
                 try {
+                    //loginInterception为false(关闭登录拦截时)时,创建虚拟角色
                     if (loginInterception) {
                         await store.dispatch('user/getUserInfo')
                     } else {
-                        //loginInterception为false(关闭登录拦截时)时,创建虚拟角色
-                        await store.dispatch('user/setVirtualRoles')
+                        await store.dispatch('user/setVirtualRoles');
                     }
 
                     let accessRoutes = []
@@ -53,45 +57,47 @@ router.beforeEach(async(to, from, next) => {
                     }
 
                     accessRoutes.forEach((item) => {
+                        if (!router.hasRoute(item.name)) { // 假设路由配置有唯一 name
+                            router.addRoute(item);
+                        }
+                    });
 
-                        router.addRoute(item)
-                    })
-
-                    if (accessRoutes[1].path != '/') {
-                        next(accessRoutes[1].path)
-
+                    // 确保 accessRoutes 有效且处理边界情况
+                    if (accessRoutes.length > 0) {
+                        // 优先使用目标路由 to,若无效则跳转到第一个有效路由
+                        next({ path: to.matched.length > 0 ? to.path : accessRoutes[0].path, replace: true });
                     } else {
-
-
-                        next({...to, replace: true })
-
+                        // 无动态路由时,跳转到默认页(如首页)
+                        next({ path: '/', replace: true });
                     }
 
                 } catch {
                     await store.dispatch('user/resetAll')
                     if (recordRoute)
-                        next({
-                            path: '/login',
-                            query: { redirect: to.path },
-                            replace: true,
-                        })
+                        next({ path: '/login', query: { redirect: to.path }, replace: true, })
                     else next({ path: '/login', replace: true })
                 }
             }
+
+            // 获取公共数据
+            await store.commit("publicSiteList")
+            await store.commit('publicDeviceList')
         }
     } else {
-
-        routesWhiteList
-        // next({ path: '/login', replace: true })
         if (routesWhiteList.indexOf(to.path) !== -1) {
             next()
         } else {
-            if (recordRoute)
+            if (recordRoute) {
                 next({ path: '/login', query: { redirect: to.path }, replace: true })
-            else next({ path: '/login', replace: true })
+            } else {
+                next({ path: '/login', replace: true })
+            }
         }
     }
+
+
 })
+
 router.afterEach((to) => {
     document.title = getPageTitle(to.meta.title)
 })

+ 117 - 140
src/router/index.js

@@ -1,73 +1,46 @@
 import { createRouter, createWebHashHistory } from 'vue-router'
 import Layout from '@/layout'
 
-export const constantRoutes = [{
+export const constantRoutes = [
+    {
         path: '/login',
         component: () =>
-            import ('@/views/login'),
+            import('@/views/login'),
         hidden: true,
     },
     {
         path: '/403',
         name: '403',
         component: () =>
-            import ('@/views/403'),
+            import('@/views/403'),
         hidden: true,
     },
-
     {
         path: '/401',
         name: '401',
         component: () =>
-            import ('@/views/401'),
+            import('@/views/401'),
         hidden: true,
     },
     {
         path: '/404',
         name: '404',
         component: () =>
-            import ('@/views/404'),
+            import('@/views/404'),
+        hidden: true,
+    },
+    {
+        path: '/*',
+        redirect: '/404',
         hidden: true,
     },
     // { path: '*', redirect: '/404', hidden: true }
 ]
-export const asyncRoutes = [
-
-    // {
-    //     path: '/',
-    //     component: Layout,
-    //     redirect: '/index',
-    //     meta: {
-    //         title: '首页',
-    //         icon: 'home',
-    //         affix: true,
-    //     },
-    //     children: [{
-    //         path: 'index',
-    //         name: 'Index',
-    //         component: () =>
-    //             import ('@/views/index'),
-    //         meta: {
-    //             title: '首页',
-    //             icon: 'home',
-    //             affix: true,
-    //         },
-    //     }, ],
-    // },
-
-
-    // {
-    //     path: 'external-link',
-    //     component: Layout,
-    //     children: [{
-    //         path: '/home',
-    //         meta: { title: '首页', icon: 'home', }
-    //     }]
-    // },
 
+export const asyncRoutes = [
     {
         path: '/',
-        redirect: '/alarmManage/index',
+        redirect: '/',
         meta: {
             title: '告警管理',
             icon: 'alarmManage',
@@ -79,32 +52,12 @@ export const asyncRoutes = [
                 title: '告警管理',
                 icon: 'alarmManage',
             },
-            path: '/alarmManage/index',
+            path: '/',
             component: () =>
-                import ('@/views/alarmManage/index'),
-        }, ]
+                import('@/views/alarmManage/index'),
+        },]
     },
-    // {
-    //     path: '/alarmManage',
-    //     redirect: '/alarmManage/index',
-    //     meta: {
-    //         title: '告警管理',
-    //         icon: 'alarmManage',
-    //         affix: true,
-    //     },
-    //     component: Layout,
-    //     children: [{
-    //         meta: {
-    //             title: '告警管理',
-    //             icon: 'alarmManage',
-    //             affix: true,
-    //         },
-    //         path: 'alarmManage',
-    //         component: () =>
-    //             import ('@/views/alarmManage/index'),
-
-    //     }, ]
-    // },
+    
     {
         path: '/siteManage',
         redirect: '/siteManage/index',
@@ -120,7 +73,7 @@ export const asyncRoutes = [
             },
             path: '/siteManage',
             component: () =>
-                import ('@/views/siteManage/index'),
+                import('@/views/siteManage/index'),
             hidden: true
         }]
     },
@@ -140,7 +93,7 @@ export const asyncRoutes = [
             },
             path: '/stationManage',
             component: () =>
-                import ('@/views/stationManage/index'),
+                import('@/views/stationManage/index'),
             hidden: true
         }]
     },
@@ -168,7 +121,7 @@ export const asyncRoutes = [
             },
             path: '/deviceManage',
             component: () =>
-                import ('@/views/deviceManage/powerEquip'),
+                import('@/views/deviceManage/powerEquip'),
             hidden: true
         }]
     },
@@ -203,56 +156,77 @@ export const asyncRoutes = [
      * demandAnalysis 需量分析
      * consumConfig 能耗分析配置
      */
-
-
     {
         meta: { icon: 'dataManage', title: '数据管理', },
         path: '/dataManage',
         component: Layout,
         redirect: '/dataManage/sameAnalysis/index',
         children: [{
-                meta: { icon: 'sameAnalysis', title: '同比分析报表', },
-                path: 'sameAnalysis',
-                component: () =>
-                    import ('@/views/dataManage/sameAnalysis/index'),
-            },
-            {
-                meta: { icon: 'chainAnalysis', title: '环比分析报表', },
-                path: 'chainAnalysis',
-                component: () =>
-                    import ('@/views/dataManage/chainAnalysis/index'),
-            },
+            meta: { icon: 'sameAnalysis', title: '同比分析报表', },
+            path: 'sameAnalysis',
+            component: () =>
+                import('@/views/dataManage/sameAnalysis/index'),
+        },
+        {
+            meta: { icon: 'chainAnalysis', title: '环比分析报表', },
+            path: 'chainAnalysis',
+            component: () =>
+                import('@/views/dataManage/chainAnalysis/index'),
+        },
+        // {
+        //     meta: { icon: 'handOpera', title: '手动抄表', },
+        //     title: 'index-layout.menu.dataManage.handOpera',
+        //     path: 'handOpera',
+        //     component: () =>
+        //         import ('@/views/dataManage/handOpera/index.vue'),
+        // },
+        {
+            meta: { icon: 'energyReport', title: '用能月报', },
+            title: 'index-layout.menu.dataManage.energyReport',
+            path: 'energyReport',
+            component: () =>
+                import('@/views/dataManage/energyReport/index'),
+        },
+        {
+            meta: { icon: 'demandAnalysis', title: '需量分析', },
+            title: 'index-layout.menu.dataManage.demandAnalysis',
+            path: 'demandAnalysis',
+            component: () =>
+                import('@/views/dataManage/demandAnalysis/index'),
+        },
             // {
-            //     meta: { icon: 'handOpera', title: '手动抄表', },
-            //     title: 'index-layout.menu.dataManage.handOpera',
-            //     path: 'handOpera',
+            //     meta: { icon: 'consumConfig', title: '能耗分析配置', },
+            //     title: 'index-layout.menu.dataManage.consumConfig',
+            //     path: 'consumConfig',
             //     component: () =>
-            //         import ('@/views/dataManage/handOpera/index.vue'),
-            // },
+            //         import ('@/views/dataManage/consumConfig/index.vue'),
+            // }
+        ]
+    },
+
+
+    {
+        meta: { icon: 'energyManage', title: '能源管理', },
+        path: '/energyManage',
+        component: Layout,
+        redirect: '/energyManage/totalEnergyC/index',
+        children: [
             {
-                meta: { icon: 'energyReport', title: '用能月报', },
-                title: 'index-layout.menu.dataManage.energyReport',
-                path: 'energyReport',
+                meta: { icon: 'totalEnergyC', title: '总能耗', },
+                path: 'totalEnergyC',
                 component: () =>
-                    import ('@/views/dataManage/energyReport/index'),
+                    import('@/views/energyManage/totalEnergyC/index'),
             },
             {
-                meta: { icon: 'demandAnalysis', title: '需量分析', },
-                title: 'index-layout.menu.dataManage.demandAnalysis',
-                path: 'demandAnalysis',
+                meta: { icon: 'totalEnergyC', title: '同比分析报表', },
+                path: 'totalEnergyC1',
                 component: () =>
-                    import ('@/views/dataManage/demandAnalysis/index'),
+                    import('@/views/energyManage/totalEnergyC/index'),
             },
-            // {
-            //     meta: { icon: 'consumConfig', title: '能耗分析配置', },
-            //     title: 'index-layout.menu.dataManage.consumConfig',
-            //     path: 'consumConfig',
-            //     component: () =>
-            //         import ('@/views/dataManage/consumConfig/index.vue'),
-            // }
         ]
     },
 
+
     /**
      * powerQuality 电能质量
      * harmonicReport 谐波报表
@@ -266,29 +240,29 @@ export const asyncRoutes = [
         component: Layout,
         redirect: '/powerQuality/harmonicReport/index',
         children: [{
-                meta: { icon: 'harmonicReport', title: '谐波报表', },
-                path: 'harmonicReport',
-                component: () =>
-                    import ('@/views/powerQuality/harmonicReport/index'),
-            },
-            {
-                meta: { icon: 'realTimeMonitoring', title: '实时监测' },
-                path: 'realTimeMonitoring',
-                component: () =>
-                    import ('@/views/powerQuality/realTimeMonitoring/index'),
-            },
-            {
-                meta: { icon: 'asseReport', title: '评估报告', },
-                path: 'asseReport',
-                component: () =>
-                    import ('@/views/powerQuality/asseReport/index'),
-            },
-            {
-                meta: { icon: 'unbalanceAnalysis', title: '三相不平衡分析', },
-                path: 'unbalanceAnalysis',
-                component: () =>
-                    import ('@/views/powerQuality/unbalanceAnalysis/index'),
-            },
+            meta: { icon: 'harmonicReport', title: '谐波报表', },
+            path: 'harmonicReport',
+            component: () =>
+                import('@/views/powerQuality/harmonicReport/index'),
+        },
+        {
+            meta: { icon: 'realTimeMonitoring', title: '实时监测' },
+            path: 'realTimeMonitoring',
+            component: () =>
+                import('@/views/powerQuality/realTimeMonitoring/index'),
+        },
+        {
+            meta: { icon: 'asseReport', title: '评估报告', },
+            path: 'asseReport',
+            component: () =>
+                import('@/views/powerQuality/asseReport/index'),
+        },
+        {
+            meta: { icon: 'unbalanceAnalysis', title: '三相不平衡分析', },
+            path: 'unbalanceAnalysis',
+            component: () =>
+                import('@/views/powerQuality/unbalanceAnalysis/index'),
+        },
 
         ]
     },
@@ -329,7 +303,7 @@ export const asyncRoutes = [
             meta: { title: '计划停电', icon: 'planOutage', },
             path: '/planOutage',
             component: () =>
-                import ('@/views/planOutage/index'),
+                import('@/views/planOutage/index'),
             hidden: true
         }],
     },
@@ -439,17 +413,17 @@ export const asyncRoutes = [
         component: Layout,
         redirect: '/systemManage/userManage/index',
         children: [{
-                meta: { title: '用户管理', icon: 'userManage', },
-                path: 'userManage',
-                component: () =>
-                    import ('@/views/systemManage/userManage/index'),
-            },
-            {
-                meta: { title: '权限管理', icon: 'rolePermission', },
-                path: 'rolePermission',
-                component: () =>
-                    import ('@/views/systemManage/rolePermission/index'),
-            },
+            meta: { title: '用户管理', icon: 'userManage', },
+            path: 'userManage',
+            component: () =>
+                import('@/views/systemManage/userManage/index'),
+        },
+        {
+            meta: { title: '权限管理', icon: 'rolePermission', },
+            path: 'rolePermission',
+            component: () =>
+                import('@/views/systemManage/rolePermission/index'),
+        },
         ]
     },
 
@@ -508,16 +482,19 @@ export const asyncRoutes = [
     //         },
     //     ],
     // },
-    {
-        path: '/*',
-        redirect: '/404',
-        hidden: true,
-    },
+
 ]
 
 const router = createRouter({
     history: createWebHashHistory(),
     routes: constantRoutes,
+    scrollBehavior(to, from, savedPosition) {
+        if (savedPosition) {
+            return savedPosition
+        } else {
+            return { top: 0 }
+        }
+    },
 })
 
 export default router

+ 0 - 8
src/store/index.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 导入所有 vuex 模块,自动加入namespaced:true,用于解决vuex命名冲突,请勿修改。
  */
 import { createStore } from 'vuex'
@@ -80,7 +79,6 @@ export default createStore({
                     }
                 })
         },
-
         /**
          * @公共左侧树状设备
          * @param {*} state 
@@ -118,8 +116,6 @@ export default createStore({
             }
 
         },
-
-
         /**
          * @公共按钮权限
          * @param {*} state 
@@ -141,10 +137,6 @@ export default createStore({
                 })
 
         },
-
-
-
-
         /**
          * @公共api请求参数siteId
          * @param {*}} state 

+ 8 - 18
src/store/modules/routes.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 路由拦截状态管理,目前两种模式:all模式与intelligence模式,其中partialRoutes是菜单暂未使用
  */
 import { asyncRoutes, constantRoutes } from '@/router'
@@ -27,7 +26,6 @@ const mutations = {
 }
 const actions = {
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description intelligence模式设置路由
      * @param {*} { commit }
      * @returns
@@ -38,7 +36,6 @@ const actions = {
         return [...asyncRoutes]
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description all模式设置路由
      * @param {*} { commit }
      * @returns
@@ -52,7 +49,6 @@ const actions = {
 
         } else {
             store.state.auth = 1
-
         }
 
         data.unshift({
@@ -62,20 +58,15 @@ const actions = {
                 path: '/home',
                 meta: { title: '首页', icon: 'home', }
             }]
-        }, )
-        data.forEach(function(item) {
-                if (item.children.length > 1) {
-                    item.children.forEach(function(i) {
-                        i.meta.icon = ''
-                    })
-                }
-            })
-            // console.log('data')
-            // console.log(data)
-
+        },)
+        data.forEach(function (item) {
+            if (item.children.length > 1) {
+                item.children.forEach(function (i) {
+                    i.meta.icon = ''
+                })
+            }
+        })
 
-        // if (data[data.length - 1].path !== '*')
-        //     data.push({ path: '/*', redirect: '/404', hidden: true })
 
         const asyncRoutes = convertRouter(data)
         const finallyRoutes = filterRoutes([...constantRoutes, ...asyncRoutes])
@@ -83,7 +74,6 @@ const actions = {
         return [...asyncRoutes]
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 画廊布局、综合布局设置路由
      * @param {*} { commit }
      * @param accessedRoutes 画廊布局、综合布局设置路由

+ 0 - 1
src/store/modules/settings.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 所有全局配置的状态管理,如无必要请勿修改
  */
 import defaultSettings from '@/config'

+ 0 - 13
src/store/modules/tagsBar.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description tagsBar多标签页逻辑,前期借鉴了很多开源项目发现都有个共同的特点很繁琐并不符合框架设计的初衷,后来在github用户cyea的启发下完成了重构,请勿修改
  */
 
@@ -11,7 +10,6 @@ const getters = {
 }
 const mutations = {
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 添加标签页
    * @param {*} state
    * @param {*} route
@@ -26,7 +24,6 @@ const mutations = {
     state.visitedRoutes.push(Object.assign({}, route))
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页
    * @param {*} state
    * @param {*} route
@@ -38,7 +35,6 @@ const mutations = {
     })
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页以外其它全部多标签页
    * @param {*} state
    * @param {*} route
@@ -50,7 +46,6 @@ const mutations = {
     )
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页左边全部多标签页
    * @param {*} state
    * @param {*} route
@@ -64,7 +59,6 @@ const mutations = {
     })
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页右边全部多标签页
    * @param {*} state
    * @param {*} route
@@ -78,7 +72,6 @@ const mutations = {
     })
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除全部多标签页
    * @param {*} state
    * @param {*} route
@@ -90,7 +83,6 @@ const mutations = {
 }
 const actions = {
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 添加标签页
    * @param {*} { commit }
    * @param {*} route
@@ -99,7 +91,6 @@ const actions = {
     commit('addVisitedRoute', route)
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页
    * @param {*} { commit }
    * @param {*} route
@@ -108,7 +99,6 @@ const actions = {
     commit('delVisitedRoute', route)
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页以外其它全部多标签页
    * @param {*} { commit }
    * @param {*} route
@@ -117,7 +107,6 @@ const actions = {
     commit('delOthersVisitedRoutes', route)
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页左边全部多标签页
    * @param {*} { commit }
    * @param {*} route
@@ -126,7 +115,6 @@ const actions = {
     commit('delLeftVisitedRoutes', route)
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除当前标签页右边全部多标签页
    * @param {*} { commit }
    * @param {*} route
@@ -135,7 +123,6 @@ const actions = {
     commit('delRightVisitedRoutes', route)
   },
   /**
-   * @author chuzhixin 1204505056@qq.com
    * @description 删除全部多标签页
    * @param {*} { commit }
    */

+ 4 - 28
src/store/modules/user.js

@@ -1,14 +1,9 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 登录、获取用户信息、退出登录、清除accessToken逻辑,不建议修改
  */
 import { getUserInfo, login, logout } from '@/api/user'
-import {
-    getAccessToken,
-    removeAccessToken,
-    setAccessToken,
-} from '@/utils/accessToken'
-import { title, tokenName } from '@/config'
+import { getAccessToken, removeAccessToken, setAccessToken } from '@/utils/accessToken'
+import { tokenName } from '@/config'
 import { message, notification } from 'ant-design-vue'
 import store from '..'
 
@@ -24,7 +19,6 @@ const getters = {
 }
 const mutations = {
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 设置accessToken
      * @param {*} state
      * @param {*} accessToken
@@ -34,7 +28,6 @@ const mutations = {
         setAccessToken(accessToken)
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 设置用户名
      * @param {*} state
      * @param {*} username
@@ -43,7 +36,6 @@ const mutations = {
         state.username = username
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 设置头像
      * @param {*} state
      * @param {*} avatar
@@ -54,7 +46,6 @@ const mutations = {
 }
 const actions = {
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 登录拦截放行时,设置虚拟角色
      * @param {*} { commit, dispatch }
      */
@@ -64,7 +55,6 @@ const actions = {
         commit('setUsername', 'admin(未开启登录拦截)')
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 登录
      * @param {*} { commit }
      * @param {*} userInfo
@@ -76,24 +66,14 @@ const actions = {
             commit('setAccessToken', accessToken)
             const hour = new Date().getHours()
             const thisTime =
-                hour < 8 ?
-                '早上好' :
-                hour <= 11 ?
-                '上午好' :
-                hour <= 13 ?
-                '中午好' :
-                hour < 18 ?
-                '下午好' :
-                '晚上好'
+                hour < 8 ? '早上好' : hour <= 11 ? '上午好' :
+                    hour <= 13 ? '中午好' : hour < 18 ? '下午好' : '晚上好'
 
-            title
             if (store.state.auth == 1) {
                 notification.open({
-                    // message: `欢迎登录${title}`,
                     message: `登录成功`,
                     description: `${thisTime}!`,
                 })
-
             }
 
         } else {
@@ -101,7 +81,6 @@ const actions = {
         }
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 获取用户信息接口 这个接口非常非常重要,如果没有明确底层前逻辑禁止修改此方法,错误的修改可能造成整个框架无法正常使用
      * @param {*} { commit, dispatch, state }
      * @returns
@@ -130,7 +109,6 @@ const actions = {
     },
 
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 退出登录
      * @param {*} { dispatch }
      */
@@ -139,7 +117,6 @@ const actions = {
         await dispatch('resetAll')
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 重置accessToken、roles、ability、router等
      * @param {*} { commit, dispatch }
      */
@@ -152,7 +129,6 @@ const actions = {
         removeAccessToken()
     },
     /**
-     * @author chuzhixin 1204505056@qq.com
      * @description 设置token
      */
     setAccessToken({ commit }, accessToken) {

+ 0 - 3
src/utils/accessToken.js

@@ -2,7 +2,6 @@ import { storage, tokenTableName } from '@/config'
 import cookie from 'js-cookie'
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 获取accessToken
  * @returns {string|ActiveX.IXMLDOMNode|Promise<any>|any|IDBRequest<any>|MediaKeyStatus|FormDataEntryValue|Function|Promise<Credential | null>}
  */
@@ -23,7 +22,6 @@ export function getAccessToken() {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 存储accessToken
  * @param accessToken
  * @returns {void|*}
@@ -45,7 +43,6 @@ export function setAccessToken(accessToken) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 移除accessToken
  * @returns {void|Promise<void>}
  */

+ 12 - 25
src/utils/index.js

@@ -1,12 +1,9 @@
-import { devDependencies } from '../../package.json'
-if (!devDependencies['vab-config']) document.body.innerHTML = ''
-    /**
-     * @author chuzhixin 1204505056@qq.com
-     * @description 格式化时间
-     * @param time
-     * @param cFormat
-     * @returns {string|null}
-     */
+/**
+ * @description 格式化时间
+ * @param time
+ * @param cFormat
+ * @returns {string|null}
+ */
 export function parseTime(time, cFormat) {
     if (arguments.length === 0) {
         return null
@@ -81,7 +78,6 @@ export function parseTime2(time, cFormat) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 格式化时间
  * @param time
  * @param option
@@ -126,7 +122,6 @@ export function formatTime(time, option) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 将url请求参数转为json格式
  * @param url
  * @returns {{}|any}
@@ -139,16 +134,15 @@ export function paramObj(url) {
     return JSON.parse(
         '{"' +
         decodeURIComponent(search)
-        .replace(/"/g, '\\"')
-        .replace(/&/g, '","')
-        .replace(/=/g, '":"')
-        .replace(/\+/g, ' ') +
+            .replace(/"/g, '\\"')
+            .replace(/&/g, '","')
+            .replace(/=/g, '":"')
+            .replace(/\+/g, ' ') +
         '"}'
     )
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 父子关系的数组转换成树形结构数据
  * @param data
  * @returns {*}
@@ -179,7 +173,6 @@ export function translateDataToTree(data) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 树形结构数据转换成父子关系的数组
  * @param data
  * @returns {[]}
@@ -206,7 +199,6 @@ export function translateTreeToData(data) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 10位时间戳转换
  * @param time
  * @returns {string}
@@ -228,7 +220,6 @@ export function tenBitTimestamp(time) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 13位时间戳转换
  * @param time
  * @returns {string}
@@ -250,7 +241,6 @@ export function thirteenBitTimestamp(time) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 获取随机id
  * @param length
  * @returns {string}
@@ -265,7 +255,6 @@ export function uuid(length = 32) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description m到n的随机数
  * @param m
  * @param n
@@ -276,12 +265,11 @@ export function random(m, n) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description addEventListener
  * @type {function(...[*]=)}
  */
-export const on = (function() {
-    return function(element, event, handler, useCapture = false) {
+export const on = (function () {
+    return function (element, event, handler, useCapture = false) {
         if (element && event && handler) {
             element.addEventListener(event, handler, useCapture)
         }
@@ -289,7 +277,6 @@ export const on = (function() {
 })()
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description removeEventListener
  * @type {function(...[*]=)}
  */

+ 0 - 1
src/utils/pageTitle.js

@@ -1,7 +1,6 @@
 import { title, titleReverse, titleSeparator } from '@/config'
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 设置标题
  * @param pageTitle
  * @returns {string}

+ 31 - 45
src/utils/request.js

@@ -2,50 +2,16 @@ import axios from 'axios'
 import store from '@/store'
 import qs from 'qs'
 import router from '@/router'
-import { contentType, debounce, requestTimeout, successCode, tokenName, } from '@/config'
+import { contentType, debounce, requestTimeout, successCode, tokenName, loadingInstance } from '@/config'
 import { isArray } from '@/utils/validate'
-import { message } from 'ant-design-vue'
+import { message } from 'ant-design-vue';
 
-// console.log(successCode, tokenName, contentType)
-
-let loadingInstance
-
-console.log(loadingInstance)
-console.log(loadingInstance.close())
-
-var tag = true
-
-/**
- * @description 处理code异常
- * @param {*} code
- * @param {*} msg
- */
-const handleCode = (code, msg) => {
-
-    switch (code) {
-        case '401':
-            if (tag) {
-                message.error('登录状态已过期,请重新登陆!')
-                tag = false
-            }
-            store.dispatch('user/resetAll').catch(() => { })
-            store.dispatch('user/logout').catch(() => { })
-            router.replace({ path: "/login" });
-            break
-        case '403':
-            router.push({ path: '/401' }).catch(() => { })
-            break
-        default:
-            message.error(msg || `后端接口${code}异常`)
-            break
-    }
-}
+let tag = true
+let baseURL = window.PLATFROM_CONFIG.baseUrl
 
 /**
  * @description axios初始化
  */
-const baseURL = window.PLATFROM_CONFIG.baseUrl
-// console.log(baseURL)
 const instance = axios.create({
     baseURL,
     timeout: requestTimeout,
@@ -82,8 +48,7 @@ instance.interceptors.request.use(
  */
 instance.interceptors.response.use(
     (response) => {
-        if (loadingInstance) loadingInstance.close()
-        const { data, config } = response
+        const { data } = response
         const { code, msg } = data
         // 操作正常Code数组
         const codeVerificationArray = isArray(successCode) ? [...successCode] : [...[successCode]]
@@ -92,10 +57,7 @@ instance.interceptors.response.use(
             return data
         } else {
             handleCode(code, msg)
-            return Promise.reject(
-                'vue-admin-beautiful请求异常拦截:' +
-                JSON.stringify({ url: config.url, code, msg }) || 'Error'
-            )
+            return Promise.reject(msg)
         }
     },
     (error) => {
@@ -117,10 +79,34 @@ instance.interceptors.response.use(
                 const code = message.substr(message.length - 3)
                 message = '后端接口' + code + '异常'
             }
-            message.error(message || `后端接口未知异常`)
             return Promise.reject(error)
         }
     }
 )
 
+/**
+ * @description 处理code异常
+ * @param {*} code
+ * @param {*} msg
+ */
+const handleCode = (code, msg) => {
+    switch (code) {
+        case '401':
+            if (tag) {
+                message.error('登录状态已过期,请重新登陆!');
+                tag = false;
+            }
+            store.dispatch('user/resetAll').catch(() => { })
+            store.dispatch('user/logout').catch(() => { })
+            router.replace({ path: '/login', replace: true });
+            break
+        case '403':
+            router.push({ path: '/401' }).catch(() => { })
+            break
+        default:
+            message.error(msg || `后端接口${code}异常`)
+            break
+    }
+}
+
 export default instance

+ 0 - 1
src/utils/static.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 导入所有 controller 模块,浏览器环境中自动输出controller文件夹下Mock接口,请勿修改。
  */
 import Mock from 'mockjs'

+ 0 - 23
src/utils/validate.js

@@ -1,5 +1,4 @@
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判读是否为外链
  * @param path
  * @returns {boolean}
@@ -9,7 +8,6 @@ export function isExternal(path) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 校验密码是否小于6位
  * @param value
  * @returns {boolean}
@@ -19,7 +17,6 @@ export function isPassword(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为数字
  * @param value
  * @returns {boolean}
@@ -30,7 +27,6 @@ export function isNumber(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是名称
  * @param value
  * @returns {boolean}
@@ -41,7 +37,6 @@ export function isName(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为IP
  * @param ip
  * @returns {boolean}
@@ -52,7 +47,6 @@ export function isIP(ip) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是传统网站
  * @param url
  * @returns {boolean}
@@ -63,7 +57,6 @@ export function isUrl(url) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是小写字母
  * @param value
  * @returns {boolean}
@@ -74,7 +67,6 @@ export function isLowerCase(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是大写字母
  * @param value
  * @returns {boolean}
@@ -85,7 +77,6 @@ export function isUpperCase(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是大写字母开头
  * @param value
  * @returns {boolean}
@@ -96,7 +87,6 @@ export function isAlphabets(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是字符串
  * @param value
  * @returns {boolean}
@@ -106,7 +96,6 @@ export function isString(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是数组
  * @param arg
  * @returns {arg is any[]|boolean}
@@ -119,7 +108,6 @@ export function isArray(arg) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是端口号
  * @param value
  * @returns {boolean}
@@ -130,7 +118,6 @@ export function isPort(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是手机号
  * @param value
  * @returns {boolean}
@@ -141,7 +128,6 @@ export function isPhone(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是身份证号(第二代)
  * @param value
  * @returns {boolean}
@@ -152,7 +138,6 @@ export function isIdCard(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否是邮箱
  * @param value
  * @returns {boolean}
@@ -163,7 +148,6 @@ export function isEmail(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否中文
  * @param value
  * @returns {boolean}
@@ -174,7 +158,6 @@ export function isChina(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为空
  * @param value
  * @returns {boolean}
@@ -190,7 +173,6 @@ export function isBlank(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为固话
  * @param value
  * @returns {boolean}
@@ -201,7 +183,6 @@ export function isTel(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为数字且最多两位小数
  * @param value
  * @returns {boolean}
@@ -212,7 +193,6 @@ export function isNum(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断经度 -180.0~+180.0(整数部分为0~180,必须输入1到5位小数)
  * @param value
  * @returns {boolean}
@@ -223,7 +203,6 @@ export function isLongitude(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断纬度 -90.0~+90.0(整数部分为0~90,必须输入1到5位小数)
  * @param value
  * @returns {boolean}
@@ -234,7 +213,6 @@ export function isLatitude(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description rtsp校验,只要有rtsp://
  * @param value
  * @returns {boolean}
@@ -247,7 +225,6 @@ export function isRTSP(value) {
 }
 
 /**
- * @author chuzhixin 1204505056@qq.com
  * @description 判断是否为json
  * @param value
  * @returns {boolean}

+ 0 - 5
src/vab/index.js

@@ -1,5 +0,0 @@
-// 加载插件
-const requirePlugin = require.context('./plugins', true, /\.js$/)
-requirePlugin.keys().forEach((fileName) => {
-  requirePlugin(fileName)
-})

+ 0 - 29
src/vab/styles/vab.less

@@ -1,29 +0,0 @@
-@import "./normalize.less";
-
-html {
-  body {
-
-    * {
-      box-sizing: border-box;
-    }
-
-    /* ant-input-search搜索框 */
-    .ant-input-search {
-      max-width: 250px;
-    }
-
-    /* ant-pagination分页 */
-    .ant-pagination {
-      margin-top: @vab-margin;
-      text-align: center;
-
-      &.ant-table-pagination {
-        float: none !important;
-        margin-top: @vab-margin;
-      }
-
-    }
-
-
-  }
-}

+ 3 - 3
src/views/401.vue

@@ -68,7 +68,7 @@
   }
 </script>
 
-<style lang="less" scoped>
+<style lang="scss" scoped>
   .error-container {
     position: relative;
     height: 100vh;
@@ -142,7 +142,7 @@
         overflow: hidden;
 
         &-oops {
-          margin-bottom: @vab-margin;
+          margin-bottom: $vab-margin;
           font-size: 32px;
           font-weight: bold;
           line-height: 40px;
@@ -186,7 +186,7 @@
           color: #fff;
           text-align: center;
           cursor: pointer;
-          background: @vab-color-blue;
+          background: $vab-color-blue;
           border-radius: 100px;
           opacity: 0;
           animation-name: slideUp;

+ 3 - 3
src/views/403.vue

@@ -68,7 +68,7 @@
   }
 </script>
 
-<style lang="less" scoped>
+<style lang="scss" scoped>
   .error-container {
     position: relative;
     height: 100vh;
@@ -142,7 +142,7 @@
         overflow: hidden;
 
         &-oops {
-          margin-bottom: @vab-margin;
+          margin-bottom: $vab-margin;
           font-size: 32px;
           font-weight: bold;
           line-height: 40px;
@@ -186,7 +186,7 @@
           color: #fff;
           text-align: center;
           cursor: pointer;
-          background: @vab-color-blue;
+          background: $vab-color-blue;
           border-radius: 100px;
           opacity: 0;
           animation-name: slideUp;

+ 3 - 3
src/views/404.vue

@@ -67,7 +67,7 @@
   }
 </script>
 
-<style lang="less" scoped>
+<style lang="scss" scoped>
   .error-container {
     position: relative;
     height: 100vh;
@@ -141,7 +141,7 @@
         overflow: hidden;
 
         &-oops {
-          margin-bottom: @vab-margin;
+          margin-bottom: $vab-margin;
           font-size: 32px;
           font-weight: bold;
           line-height: 40px;
@@ -185,7 +185,7 @@
           color: #fff;
           text-align: center;
           cursor: pointer;
-          background: @vab-color-blue;
+          background: $vab-color-blue;
           border-radius: 100px;
           opacity: 0;
           animation-name: slideUp;

+ 0 - 1
src/views/alarmManage/index.vue

@@ -32,7 +32,6 @@
               end-placeholder="结束日期"
               style="width: auto"
               :disabled="store.state.authorities.indexOf('查询')==-1"
-        
             ></el-date-picker>
           </div>
           <el-button

+ 96 - 133
src/views/login/index.vue

@@ -27,22 +27,12 @@
               </a-input>
             </a-form-item>
 
-            <!-- <a-form-item>
-              <JcRange
-                :status="status"
-                @successFun="onSuccess()"
-                @errorFun="onError()"
-              ></JcRange>
-            </a-form-item> -->
-
             <a-form-item>
               <a-button
                 type="primary"
                 html-type="submit"
-                :disabled="
-                  form.username === '' ||
-                  form.password === ''
-                "
+                :loading="loading"
+                :disabled="form.username === '' || form.password === ''"
               >
                 登录
               </a-button>
@@ -51,137 +41,110 @@
         </div>
       </a-col>
     </a-row>
-    <!-- <div class="login-container-tips">
-      基于vue{{ dependencies['vue'] }}
-      + ant-design-vue
-      {{ dependencies['ant-design-vue'] }}开发
-    </div> -->
   </div>
 </template>
 <script>
-import { dependencies, devDependencies } from '*/package.json'
-import { mapActions, mapGetters } from 'vuex'
-import { useRouter } from 'vue-router'
-import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
-
-// import JcRange from './JcRange.vue'
+  import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
+  import { message } from 'ant-design-vue'
 
-export default {
-  name: 'Login',
-  components: {
-    UserOutlined,
-    LockOutlined,
-    // JcRange,
-  },
-  data() {
-    return {
-      form: {
-        username: '',
-        password: '',
-      },
-      status: false,
-      redirect: undefined,
-      dependencies: dependencies,
-      devDependencies: devDependencies,
-    }
-  },
-  computed: {
-    ...mapGetters({
-      logo: 'settings/logo',
-      title: 'settings/title',
-    }),
-  },
-  watch: {
-    $route: {
-      handler(route) {
-        this.redirect = (route.query && route.query.redirect) || '/'
+  export default {
+    name: 'Login',
+    components: { UserOutlined, LockOutlined },
+    data() {
+      return {
+        form: {
+          username: '',
+          password: '',
+        },
+        loading: false,
+        redirect: undefined,
+      }
+    },
+    computed: {},
+    watch: {
+      $route: {
+        handler(route) {
+          this.redirect = (route.query && route.query.redirect) || '/'
+        },
+        immediate: true,
       },
-      immediate: true,
     },
-  },
-  mounted() {
-    this.form.username = '' //admin
-    this.form.password = '' //admin123
+    mounted() {
+      this.form.username = '' //admin
+      this.form.password = '' //admin123
 
-    const router = useRouter()
-    console.log(router)
-    if (router.currentRoute.value.query.userName === 'admin') {
-      this.handleSubmit()
-    }
-  },
-  methods: {
-    ...mapActions({
-      login: 'user/login',
-    }),
-    handleRoute() {
-      return this.redirect === '/404' || this.redirect === '/403'
-        ? '/'
-        : this.redirect
-    },
-    onSuccess() {
-      console.log('滑块成功')
-      this.status = true
+      if (this.$route.query.userName === 'admin') {
+        this.form.username = 'admin'
+        this.handleSubmit()
+      }
     },
-    onError() {
-      console.log('滑块失败')
-      this.status = false
-    },
-
-    async handleSubmit() {
-      await this.login(this.form)
-      await this.$router.push(this.handleRoute())
+    methods: {
+      handleRoute() {
+        const validRoutes = ['/', '/404', '/403'] // 根据您的路由配置调整
+        return validRoutes.includes(this.redirect) ? this.redirect : '/'
+      },
+      async handleSubmit() {
+        try {
+          this.loading = true
+          await this.$store.dispatch('user/login', this.form) // 登录请求
+          await this.$router.push(this.handleRoute()) // 登录成功,跳转到目标页面
+          this.loading = false
+        } catch (error) {
+          message.error(error.message || '登录失败,请检查用户名和密码')
+          this.loading = false
+        }
+      },
     },
-  },
-}
-</script>
-<style lang="less">
-.login-container {
-  width: 100%;
-  height: 100vh;
-  background: url('~@/assets/login_images/login_background.png');
-  background-size: cover;
-  &-form {
-    width: calc(100% - 40px);
-    min-width: 360px;
-    height: 440px;
-    padding: 4vh;
-    margin-top: calc((100vh - 380px) / 2);
-    margin-right: 20px;
-    margin-left: 20px;
-    background: url('~@/assets/login_images/login_form.png');
-    background-size: 100% 100%;
-    border-radius: 10px;
-    box-shadow: 0 2px 8px 0 rgba(7, 17, 27, 0.06);
-  }
-  &-hello {
-    font-size: 32px;
-    color: #fff;
-  }
-  &-title {
-    margin-bottom: 30px;
-    font-size: 20px;
-    color: #fff;
   }
-  &-tips {
-    position: fixed;
-    bottom: @vab-margin;
-    width: 100%;
-    height: 40px;
-    color: rgba(255, 255, 255, 0.856);
-    text-align: center;
-  }
-  .ant-col {
-    width: 100%;
-    padding: 0 10px 0 10px;
-  }
-  .ant-input {
-    height: 35px;
-  }
-  .ant-btn {
+</script>
+<style lang="scss">
+  .login-container {
     width: 100%;
-    height: 45px;
-    border-radius: 99px;
+    height: 100vh;
+    background: url('@/assets/login_images/login_background.png');
+    background-size: cover;
+    &-form {
+      width: calc(100% - 40px);
+      min-width: 360px;
+      height: 440px;
+      padding: 4vh;
+      margin-top: calc((100vh - 380px) / 2);
+      margin-right: 20px;
+      margin-left: 20px;
+      background: url('@/assets/login_images/login_form.png');
+      background-size: 100% 100%;
+      border-radius: 10px;
+      box-shadow: 0 2px 8px 0 rgba(7, 17, 27, 0.06);
+    }
+    &-hello {
+      font-size: 32px;
+      color: #fff;
+    }
+    &-title {
+      margin-bottom: 30px;
+      font-size: 20px;
+      color: #fff;
+    }
+    &-tips {
+      position: fixed;
+      bottom: $vab-margin;
+      width: 100%;
+      height: 40px;
+      color: rgba(255, 255, 255, 0.856);
+      text-align: center;
+    }
+    .ant-col {
+      width: 100%;
+      padding: 0 10px 0 10px;
+    }
+    .ant-input {
+      height: 35px;
+    }
+    .ant-btn {
+      width: 100%;
+      height: 45px;
+      border-radius: 99px;
+    }
   }
-}
 </style>
-l
+l

+ 2 - 2
src/views/vab/icon/index.vue

@@ -91,11 +91,11 @@
   }
 </script>
 
-<style lang="less">
+<style lang="scss">
   .icon-container {
     .ant-input-search,
     .ant-alert {
-      margin-bottom: @vab-padding;
+      margin-bottom: $vab-padding;
     }
     .ant-card-body {
       position: relative;

+ 28 - 20
vue.config.js

@@ -53,21 +53,16 @@ module.exports = {
         hot: true,
         port: devPort,
         open: true,
-        noInfo: false,
-        overlay: {
-            warnings: true,
-            errors: true,
+        client: {
+            overlay: false,
+            // 也可以单独控制错误或警告:
+            // overlay: {
+            //   errors: false, // 关闭错误提示
+            //   warnings: false // 关闭警告提示
+            // }
         },
         // 注释掉的地方是前端配置代理访问后端的示例
         proxy: {
-            //   [baseURL]: {
-            //     target: `http://你的后端接口地址`,
-            //     ws: true,
-            //     changeOrigin: true,
-            //     pathRewrite: {
-            //       ["^/" + baseURL]: "",
-            //     },
-            //   },
             './': {
                 target: 'https://qhome.usky.cn/fivapi/',
                 ws: false,
@@ -77,8 +72,6 @@ module.exports = {
                 }
             }
         },
-        // public: 'localhost:9999/',  
-        // after: mockServer(),
     },
     configureWebpack() {
         return {
@@ -92,8 +85,10 @@ module.exports = {
             resolve: {
                 alias: {
                     '@': resolve('src'),
-                    '*': resolve(''),
                 },
+                fallback: {
+                    'path': require.resolve('path-browserify')
+                }
             },
             plugins: [
                 new Webpack.ProvidePlugin(providePlugin),
@@ -101,6 +96,19 @@ module.exports = {
                     name: webpackBarName,
                 }),
             ],
+            optimization: {
+                splitChunks: {
+                    chunks: 'all',
+                    minSize: 20000,
+                    cacheGroups: {
+                        vendor: {
+                            test: /[\\/]node_modules[\\/]/,
+                            name: 'vendors',
+                            chunks: 'all'
+                        }
+                    }
+                }
+            }
         }
     },
     chainWebpack(config) {
@@ -173,7 +181,6 @@ module.exports = {
     runtimeCompiler: true,
     productionSourceMap: false,
     css: {
-        requireModuleExtension: true,
         sourceMap: true,
         loaderOptions: {
             less: {
@@ -190,11 +197,12 @@ module.exports = {
                 },
             },
             sass: {
-                data: `
+                additionalData: `
+                    @import "@/assets/css/variables.module.scss";
                     @import "@/assets/css/index.scss";
                     @import "@/assets/css/global.scss";
-                    `
-            }
-        },
+                `
+            },
+        }
     },
 }