ソースを参照

Merge branch 'master' of http://39.105.126.192:3000/DR3_web/iot-front-ui.git

wandequan 2 年 前
コミット
db3d16e5ee
67 ファイル変更2316 行追加418 行削除
  1. BIN
      src/assets/fonts/PingFangSC-Bold.ttf
  2. BIN
      src/assets/fonts/PingFangSC-Regular.ttf
  3. 0 0
      src/assets/images/function/auth.png
  4. 0 0
      src/assets/images/function/carbon.png
  5. 0 0
      src/assets/images/function/dashboard.png
  6. 0 0
      src/assets/images/function/life.png
  7. 0 0
      src/assets/images/function/operation.png
  8. 0 0
      src/assets/images/function/report.png
  9. 0 0
      src/assets/images/function/scene.png
  10. 0 0
      src/assets/images/function/security.png
  11. 0 0
      src/assets/images/function/work.png
  12. 0 0
      src/assets/images/functionColor/life/iocRestaurant.png
  13. 1 1
      src/assets/svg/IconCamera.vue
  14. 3 4
      src/components/common/card.vue
  15. 32 10
      src/components/common/coreData.vue
  16. 10 4
      src/components/dashboard/Dashboard.vue
  17. 14 7
      src/components/dashboard/commonFuncManage/function.vue
  18. 55 147
      src/components/dashboard/commonFuncManage/functionManage.vue
  19. 2 0
      src/components/dashboard/message/dashboardMessageCard.vue
  20. 41 23
      src/components/dashboard/message/dashboardMsgList.vue
  21. 3 3
      src/components/dashboard/more/space/DataSituation.vue
  22. 2 0
      src/components/dashboard/portrait/cold/coldTrendChart.vue
  23. 5 7
      src/components/dashboard/portrait/coldPortrait.vue
  24. 1 1
      src/components/dashboard/portrait/dashboardPortrait.vue
  25. 1 0
      src/components/dashboard/portrait/electricity/electricityUseChart.vue
  26. 5 6
      src/components/dashboard/portrait/electricityPortrait.vue
  27. 2 0
      src/components/dashboard/portrait/hot/hotTrendChart.vue
  28. 6 7
      src/components/dashboard/portrait/hotPortrait.vue
  29. 2 2
      src/components/dashboard/portrait/moneyPortrait.vue
  30. 7 1
      src/components/dashboard/portrait/person/personTrendChart.vue
  31. 12 13
      src/components/dashboard/portrait/personPortrait.vue
  32. 1 0
      src/components/dashboard/portrait/restaurant/restaurantTrendChart.vue
  33. 3 4
      src/components/dashboard/portrait/restaurantPortrait.vue
  34. 1 0
      src/components/dashboard/portrait/supermarket/supermarketTrendChart.vue
  35. 4 5
      src/components/dashboard/portrait/supermarketPortrait.vue
  36. 1 0
      src/components/dashboard/portrait/water/waterUseChart.vue
  37. 4 4
      src/components/dashboard/portrait/waterPortrait.vue
  38. 1 4
      src/components/doubleCarbon/PV/doubleCarbonPv.vue
  39. 1 4
      src/components/doubleCarbon/car/doubleCarbonCar.vue
  40. 1 4
      src/components/doubleCarbon/print/doubleCarbonPrint.vue
  41. 19 24
      src/components/home/ContainerAside.vue
  42. 11 1
      src/components/home/HomeAside.vue
  43. 21 18
      src/components/home/HomeHeader.vue
  44. 121 0
      src/components/home/HomeLeft.vue
  45. 13 11
      src/components/home/NavigationPage.vue
  46. 89 0
      src/components/notice/notice.vue
  47. 156 0
      src/components/notice/noticeList.vue
  48. 147 0
      src/components/scene/AnalogData.js
  49. 314 2
      src/components/scene/meeting/sceneMeeting.vue
  50. 84 0
      src/components/security/alarm/manage/securityAlarmManageCategory.vue
  51. 58 0
      src/components/security/alarm/manage/securityAlarmManageDistribute.vue
  52. 37 0
      src/components/security/alarm/manage/securityAlarmManageDistributeMap.vue
  53. 136 0
      src/components/security/alarm/manage/securityAlarmManageOnlineTrend.vue
  54. 154 0
      src/components/security/alarm/manage/securityAlarmManageTrend.vue
  55. 22 2
      src/components/security/alarm/securityAlarmGrid.vue
  56. 182 2
      src/components/security/alarm/securityAlarmInfo.vue
  57. 119 2
      src/components/security/alarm/securityAlarmManage.vue
  58. 133 0
      src/components/security/common/securityDeviceSelect.vue
  59. 40 2
      src/components/security/device/securityDevice.vue
  60. 26 0
      src/components/security/device/securityDeviceItem.vue
  61. 33 38
      src/data/json/menuList.json
  62. 26 13
      src/data/json/ssoList.json
  63. 3 0
      src/main.js
  64. 5 5
      src/router/index.js
  65. 75 12
      src/stores/index.js
  66. 33 1
      src/style/common.css
  67. 38 24
      src/views/HomeView.vue

BIN
src/assets/fonts/PingFangSC-Bold.ttf


BIN
src/assets/fonts/PingFangSC-Regular.ttf


+ 0 - 0
src/assets/images/aside/auth.png → src/assets/images/function/auth.png


+ 0 - 0
src/assets/images/aside/carbon.png → src/assets/images/function/carbon.png


+ 0 - 0
src/assets/images/aside/dashboard.png → src/assets/images/function/dashboard.png


+ 0 - 0
src/assets/images/aside/life.png → src/assets/images/function/life.png


+ 0 - 0
src/assets/images/aside/operation.png → src/assets/images/function/operation.png


+ 0 - 0
src/assets/images/aside/report.png → src/assets/images/function/report.png


+ 0 - 0
src/assets/images/aside/scene.png → src/assets/images/function/scene.png


+ 0 - 0
src/assets/images/aside/security.png → src/assets/images/function/security.png


+ 0 - 0
src/assets/images/aside/work.png → src/assets/images/function/work.png


+ 0 - 0
src/assets/images/function/iocRestaurant.png → src/assets/images/functionColor/life/iocRestaurant.png


+ 1 - 1
src/assets/svg/IconCamera.vue

@@ -1,6 +1,6 @@
 <template>
   <svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
-    <circle cx="24" cy="19" r="14" :stroke="color&&stroke!==''?color:'#2ea8e6'" stroke-width="4"
+    <circle cx="24" cy="19" r="14" :stroke="color&&color!==''?color:'#2ea8e6'" stroke-width="4"
             stroke-linecap="round" stroke-linejoin="round"/>
     <circle cx="24" cy="19" r="6" :fill="color&&color!==''?color:'#2ea8e6'" :stroke="color&&color!==''?color:'#2ea8e6'" stroke-width="4"
             stroke-linecap="round"

+ 3 - 4
src/components/common/card.vue

@@ -23,13 +23,12 @@ export default {
 
 <style lang="less" scoped>
 .ioc-card {
+  border-radius: 20px;
   .card_title {
     padding: 10px 0px 10px 15px;
-    //height: 20px;
-    //line-height: 20px;
     font-size: 16px;
-    font-weight: bold;
-    //border-left: 8px solid #98d4f3;
+    font-family: PingFangSC-Bold,serif;
+    color: #333333;
   }
 }
 

+ 32 - 10
src/components/common/coreData.vue

@@ -1,7 +1,13 @@
 <script>
 import {requireImg} from "@/utils/requireImg";
+import IsNumeric from "ant-design-vue/lib/_util/isNumeric";
 
 export default {
+  computed: {
+    IsNumeric() {
+      return IsNumeric
+    }
+  },
   data() {
     return {
       itemWidth: 150,
@@ -48,17 +54,23 @@ export default {
       >
         <div class="coreData-item-title">
           <span>{{ ele.title }}</span>
-          <div v-if="ele.type === 1 || ele.showStar" style="display: inline-block;background-color: transparent;float: right;margin-right: 2%">
+          <div v-if="ele.showStar" style="display: inline-block;background-color: transparent;float: right;margin-right: 5%">
             <a-avatar :size="28" :src="requireImg('common/star.png')"></a-avatar>
           </div>
         </div>
         <template v-if="ele.type === 1">
           <div class="coreData-high-content">
-            <span>{{ ele.content }}</span>
+            <span :class="IsNumeric(ele.content)?'coreData-item-num':''">{{ ele.content }}</span>
           </div>
         </template>
         <template v-else>
-          <div class="coreData-item-num" v-html="ele.num"></div>
+          <div class="coreData-item-num" >
+            <span>{{ Math.abs(ele.num) }}</span>
+            <span class="anticon" v-if="ele.showTrendIcon" style="font-size: 14px;display: inline-block;margin-left: 3px">
+              <i-icon-park-outline-trending-up style="color: #FF2A00" v-if="Number(ele.num)>0" />
+              <i-icon-park-outline-trending-down style="color: #39E681" v-if="Number(ele.num)<0"  />
+            </span>
+          </div>
           <div class="coreData-item-unit" v-html="ele.unit"></div>
           <div class="coreData-item-history">
             <div class="coreData-item-historyDesc">
@@ -72,8 +84,17 @@ export default {
 
             </div>
             <div class="coreData-item-historyNum" v-if="!isNaN(ele.historyNum)">
-              {{ Math.abs(ele.historyNum) }}%
+              <span :style="{color: ele.historyNum>0?'red':ele.historyNum<0?'#39E681':''}">
+                {{ Math.abs(ele.historyNum) }}%
+              </span>
             </div>
+            <span class="anticon"
+                  v-if="!ele.hideTrendDesc"
+                  :style="{color: ele.historyNum>0?'red':ele.historyNum<0?'#39E681':''}"
+                  style="vertical-align: middle;font-size: 12px">
+              <a-icon type="caret-up" v-if="ele.historyNum > 0" />
+              <a-icon type="caret-down" v-if="ele.historyNum < 0" />
+            </span>
           </div>
         </template>
       </div>
@@ -95,12 +116,12 @@ export default {
     border-radius: 5px;
     .coreData-high-content {
       margin-top: 4%;
-      width: 60%;
+      width: 75%;
       color: #4D4D4D;
       font-size: 15px;
       max-height: 60px;
       overflow: hidden;
-      font-weight: bold;
+      font-family: PingFangSC-Bold,serif;
       letter-spacing: 1px;
       word-wrap:break-word;
       word-break:break-all;
@@ -111,9 +132,11 @@ export default {
     }
     .coreData-item-num {
       display: inline-block;
-      font-size: 30px;
-      font-weight: bolder;
-      height: 50%;
+      font-size: 22px;
+      color: #4D4D4D;
+      padding-top: 4%;
+      font-family: PingFangSC-Bold,serif;
+      height: 46%;
     }
     .coreData-item-unit {
       display: inline-block;
@@ -127,7 +150,6 @@ export default {
     .coreData-item-historyNum {
       margin-left: 5px;
       display: inline-block;
-      color: red;
     }
   }
 }

+ 10 - 4
src/components/dashboard/Dashboard.vue

@@ -13,7 +13,7 @@
             </template>
             <a-row>
               <a-col v-for="(item, index) in commonMenu" :span="6" :key="index">
-                <IocFunction :title="'智慧餐厅'" :icon="require('@/assets/images/function/iocRestaurant.png')"></IocFunction>
+                <IocFunction :item="item"></IocFunction>
               </a-col>
             </a-row>
           </IocCard>
@@ -39,7 +39,7 @@
     </a-row>
 
 
-    <FunctionManage :visible.sync="showFuncManage"></FunctionManage>
+    <FunctionManage v-if="showFuncManage" :visible.sync="showFuncManage" :common-function.sync="commonMenu"></FunctionManage>
 
   </div>
 </template>
@@ -52,13 +52,14 @@ import DashboardMessageCard from "@/components/dashboard/message/dashboardMessag
 import DashboardPortrait from "@/components/dashboard/portrait/dashboardPortrait.vue";
 import DashboardMore from "@/components/dashboard/more/dashboardMore.vue";
 import FunctionManage from "@/components/dashboard/commonFuncManage/functionManage.vue";
+import {requireImg} from "@/utils/requireImg";
 
 
 export default {
   data() {
     return {
       showFuncManage: false,
-      commonMenu: [{},{},{},{},{},{},{},{}]
+      commonMenu: []
     }
   },
   components: {
@@ -70,9 +71,11 @@ export default {
     DashboardMore,
     FunctionManage,
   },
-  created() {
+  mounted() {
+    this.commonMenu = this.$store.menuStore().commonFunction;
   },
   methods: {
+    requireImg,
     openFuncManage() {
       this.showFuncManage = true;
     }
@@ -87,6 +90,9 @@ export default {
   padding: 0 15px 15px;
   background-color: #f0f2f5;
   overflow-y: auto;
+  div {
+    border-radius: 4px;
+  }
   .dashboard-popFunc {
     margin-right: 15px;
     margin-top: 12px;

+ 14 - 7
src/components/dashboard/commonFuncManage/function.vue

@@ -1,15 +1,15 @@
 <template>
   <div class="function-btn" :style="functionBtnStyle">
     <div class="function-icon">
-      <a-avatar class="function-avatar" shape="square" size="large" :src="icon"></a-avatar>
+      <a-avatar class="function-avatar" shape="square" size="large" :src="requireImg(item.iconColor)"></a-avatar>
     </div>
-    <div class="function-title">{{ title }}</div>
-    <div class="function-btn-opr" v-if="type==-1" @click="minusFunction?minusFunction(title, isSSO):()=>{}">
+    <div class="function-title">{{ item.name }}</div>
+    <div class="function-btn-opr" v-if="type==-1" @click="minusFunction(item)">
       <span class="anticon" >
         <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#cd2a2a" stroke="#cd2a2a" stroke-width="4" stroke-linejoin="round"/><path d="M16 24L32 24" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>
       </span>
     </div>
-    <div class="function-btn-opr" v-if="type==1" @click="plusFunction?plusFunction(title, isSSO):()=>{}">
+    <div class="function-btn-opr" v-if="type===1" @click="plusFunction(item)">
        <span class="anticon" >
          <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#2ea8e6" stroke="#2ea8e6" stroke-width="4" stroke-linejoin="round"/><path d="M24 16V32" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 24L32 24" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </span>
@@ -19,7 +19,10 @@
 </template>
 
 <script>
+import {requireImg} from "@/utils/requireImg";
+
 export default {
+  methods: {requireImg},
   data() {
     return {
       functionBtnStyle: {
@@ -28,10 +31,10 @@ export default {
     }
   },
   props: {
+    item: Object,
     type: Number,
     title: String,
     icon: String,
-    isSSO: Boolean,
     plusFunction: Function,
     minusFunction: Function,
   },
@@ -66,12 +69,16 @@ export default {
     }
   }
   .function-title {
+    width: 55%;
+    line-height: 20px;
+    vertical-align: middle;
     display: inline-block;
-    margin-top: 20px;
+    //margin-top: 20px;
     margin-left: 5%;
     font-size: 16px;
-    line-height: 24px;
     letter-spacing: 1px;
+    white-space:pre-wrap;
+    word-break: break-word;
   }
   .function-btn-opr {
     position: absolute;

+ 55 - 147
src/components/dashboard/commonFuncManage/functionManage.vue

@@ -1,123 +1,22 @@
 <script>
+import menuList from "@/data/json/menuList.json"
+import ssoList from "@/data/json/ssoList.json"
 import Function from "@/components/dashboard/commonFuncManage/function.vue";
 
 export default {
   data() {
     return {
-      commonFunctions: [
-        {
-          name: '智慧餐厅',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-        {
-          name: '智慧餐厅2',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅3',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅4',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅5',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅6',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅7',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },{
-          name: '智慧餐厅8',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-      ],
-      functions: [
-        {
-          name: '智慧停车',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-        {
-          name: '智慧停车2',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-        {
-          name: '智慧停车3',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-        {
-          name: '智慧停车4',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-        {
-          name: '智慧停车5',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          type: 'route'
-        },
-      ],
-      ssoList: [
-        {
-          name: '系统1',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          isSSO: true,
-          type: 'url'
-        },{
-          name: '系统2',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          isSSO: true,
-          type: 'url'
-        },{
-          name: '系统3',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          isSSO: true,
-          type: 'url'
-        },{
-          name: '系统4',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          isSSO: true,
-          type: 'url'
-        },{
-          name: '系统5',
-          icon: '@/assets/images/function/iocRestaurant.png',
-          url: '',
-          isSSO: true,
-          type: 'url'
-        },
-      ],
+      menuList,
+      ssoList,
+      customFunction: [],
+      functions: [],
+      ssoSystems: [],
       show: false,
     }
   },
   props: {
     visible: Boolean,
+    commonFunction: Array,
   },
   components: {
     Function
@@ -128,65 +27,74 @@ export default {
     },
     "visible": function (val) {
       this.show = val
-    }
+    },
   },
-  emits: ['update:visible'],
+  emits: ['update:visible', 'update:commonFunction'],
   setup(props, context) {
     const methods = {
       toggleVisible(flag) {
         context.emit('update:visible', flag)
       },
+      updateFunctions(arr) {
+        context.emit('update:commonFunction', arr)
+      }
     }
     return methods
   },
   mounted() {
     this.show = this.visible;
+    this.customFunction = JSON.parse(JSON.stringify(this.commonFunction));
+    this.getFunctions();
+    this.ssoSystems = this.ssoList
   },
   methods: {
+    getFunctions() {
+      let names = this.commonFunction.map(i=>{return i.name});
+      this.functions = [];
+      for (let i = 0; i < this.menuList.length; i++) {
+        let menu = this.menuList[i];
+        let childMenus = menu.children?menu.children:[];
+        childMenus = childMenus.filter(i=>names.indexOf(i.name)<0);
+        childMenus.forEach(item => {
+          this.functions.push(item)
+        })
+      }
+    },
     handleOk() {
+      this.$store.menuStore().commonFunction = JSON.parse(JSON.stringify(this.customFunction));
+      this.updateFunctions(this.$store.menuStore().commonFunction)
       this.show = false;
     },
     handleCancel() {
       this.show = false
     },
-    plusFunction(item, isSSO) {
-      if (!item || item == '') {
-        return;
-      }
-      if (this.commonFunctions.length>=8) {
+    plusFunction(item) {
+      if (this.customFunction.length>=8) {
         this.$message.warning('功能位已满,请先移除功能后重试')
         return;
       }
-      let obj;
-      let index = this.functions.findIndex(i=>i.name==item)
-      if (!index || index>=0) {
-        index = this.ssoList.findIndex(i=>i.name==item)
-        if (index && index>=0) {
-          obj = this.ssoList[index];
-          this.ssoList.splice(index, 1)
+      if (item.isSso) {
+        let index = this.ssoSystems.findIndex(i=>i.name==item.name)
+        if (index) {
+          this.ssoSystems.splice(index, 1)
         }
       } else {
-        obj = this.functions[index];
-        this.functions.splice(index, 1)
-      }
-      if (obj) {
-        this.commonFunctions.push(obj)
+        let index = this.functions.findIndex(i=>i.name==item.name)
+        if (index) {
+          this.functions.splice(index, 1)
+        }
       }
+      this.customFunction.push(item)
     },
-    minusFunction(item, isSSO) {
-      if (!item || item == '') {
-        return;
-      }
-      let obj;
-      let index = this.commonFunctions.findIndex(i=>i.name==item)
-      if (index && index>=0) {
-        obj = this.commonFunctions[index]
-        this.commonFunctions.splice(index, 1)
-      }
-      if (isSSO) {
-        this.ssoList.push(obj)
-      } else {
-        this.functions.push(obj)
+    minusFunction(item) {
+      let index = this.customFunction.findIndex(i => i.name==item.name);
+      if (index) {
+        this.customFunction.splice(index, 1);
+        if (item.isSso) {
+          this.ssoSystems.push(item);
+        } else {
+          this.functions.push(item);
+        }
       }
     },
   }
@@ -215,8 +123,8 @@ export default {
       <div class="funcManage-body">
         <a-row :gutter="16">
           <transition-group name="common-function">
-            <a-col :span="6" v-for="(item,index) in commonFunctions" :key="item.name" style="margin-bottom: 12px">
-              <Function :minus-function="minusFunction" :title="item.name" :type="-1" :icon="require('@/assets/images/function/iocRestaurant.png')"></Function>
+            <a-col :span="6" v-for="(item,index) in customFunction" :key="item.name" style="margin-bottom: 12px">
+              <Function :minus-function="minusFunction" :item="item" :type="-1"></Function>
             </a-col>
           </transition-group>
         </a-row>
@@ -230,7 +138,7 @@ export default {
           <a-row :gutter="16">
             <transition-group name="common-function">
               <a-col :span="6" v-for="(item,index) in functions" :key="item.name" style="margin-bottom: 12px">
-                <Function :plus-function="plusFunction" :title="item.name" :type="1"></Function>
+                <Function :plus-function="plusFunction" :item="item" :type="1"></Function>
               </a-col>
             </transition-group>
           </a-row>
@@ -242,8 +150,8 @@ export default {
         <div class="funcManage-body">
           <a-row :gutter="16">
             <transition-group name="common-function">
-              <a-col :span="6" v-for="(item, index) in ssoList" :key="item.name" style="margin-bottom: 12px">
-                <Function :plus-function="plusFunction" :title="item.name" :type="1"></Function>
+              <a-col :span="6" v-for="(item, index) in ssoSystems" :key="item.name" style="margin-bottom: 12px">
+                <Function :plus-function="plusFunction" :item="item" :type="1"></Function>
               </a-col>
             </transition-group>
           </a-row>

+ 2 - 0
src/components/dashboard/message/dashboardMessageCard.vue

@@ -72,6 +72,8 @@ export default {
   }
   .ant-tabs-nav .ant-tabs-tab {
     margin: 0;
+    padding-left: 0 !important;
+    padding-right: 20%;
   }
   .ant-tabs-nav .ant-tabs-tab-active {
     color: #333333;

+ 41 - 23
src/components/dashboard/message/dashboardMsgList.vue

@@ -10,11 +10,9 @@ export default {
   },
   mounted() {
     let width = this.$refs.dashboardMsgList.$el.clientWidth
-    this.contentWidth = width*0.7+'px'
+    this.contentWidth = width * 0.7 + 'px'
   },
-  methods: {
-
-  }
+  methods: {}
 }
 </script>
 
@@ -22,24 +20,36 @@ export default {
   <a-list class="dashboardMsgList" item-layout="horizontal" :data-source="data" :split="false" ref="dashboardMsgList">
     <a-list-item slot="renderItem" slot-scope="item, index">
       <a-row style="width: 100%" justify="start">
-        <a-col :span="6">
+        <div style="width: 100%">
           <span v-if="item.isRead">【已阅】</span>
           <span v-else>【待阅】</span>
 
-          <span v-if="item.type==1" style="color: #5495F1">①</span>
-          <span v-else-if="item.type==2" style="color: #3BC5B0">②</span>
-          <span v-else-if="item.type==3" style="color: #F1934E">③</span>
-        </a-col>
-        <!--<a-col :span="1">-->
+          <span class="msg-warn" v-if="item.type==1" style="color: #5495F1">①</span>
+          <span class="msg-warn" v-else-if="item.type==2" style="color: #3BC5B0">②</span>
+          <span class="msg-warn" v-else-if="item.type==3" style="color: #F1934E">③</span>
+          <span class="msg-warn" v-else ></span>
+
+          <span class="msg-content-span" >{{ item.msg }}</span>
+        </div>
+
+        <!--<a-col :span="6">-->
+        <!--  <span v-if="item.isRead">【已阅】</span>-->
+        <!--  <span v-else>【待阅】</span>-->
+
         <!--  <span v-if="item.type==1" style="color: #5495F1">①</span>-->
         <!--  <span v-else-if="item.type==2" style="color: #3BC5B0">②</span>-->
         <!--  <span v-else-if="item.type==3" style="color: #F1934E">③</span>-->
         <!--</a-col>-->
-        <a-col :span="17">
-          <div class="msg-content" :style="{width: contentWidth}">
-            <span class="msg-content-span" :style="{width: contentWidth}">{{item.msg}}</span>
-          </div>
-        </a-col>
+        <!--&lt;!&ndash;<a-col :span="1">&ndash;&gt;-->
+        <!--&lt;!&ndash;  <span v-if="item.type==1" style="color: #5495F1">①</span>&ndash;&gt;-->
+        <!--&lt;!&ndash;  <span v-else-if="item.type==2" style="color: #3BC5B0">②</span>&ndash;&gt;-->
+        <!--&lt;!&ndash;  <span v-else-if="item.type==3" style="color: #F1934E">③</span>&ndash;&gt;-->
+        <!--&lt;!&ndash;</a-col>&ndash;&gt;-->
+        <!--<a-col :span="17">-->
+        <!--  <div class="msg-content" :style="{width: contentWidth}">-->
+
+        <!--</div>-->
+        <!--</a-col>-->
       </a-row>
       <!--<div class="msg-read">-->
       <!--  -->
@@ -61,25 +71,33 @@ export default {
     line-height: 30px;
     width: 100%;
   }
+
   .msg-read {
     display: inline-block;
     width: 120px !important;
     flex-direction: row;
   }
+
   .msg-type {
     display: inline-block;
     width: 20px;
     flex-direction: row;
     text-align: left;
   }
-  .msg-content {
-    .msg-content-span {
-      vertical-align: top;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      display: inline-block;
-    }
+
+  .msg-warn {
+    display: inline-block;
+    width: 20px;
+    text-align: left;
+  }
+
+  .msg-content-span {
+    display: inline-block;
+    width: 70%;
+    vertical-align: top;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
   }
 }
 </style>

+ 3 - 3
src/components/dashboard/more/space/DataSituation.vue

@@ -111,7 +111,7 @@ export default {
           type: 'liquidFill',
           data: [num],
           color: [primaryColor],
-          radius: '80%',
+          radius: '75%',
           animationDuration: 800,
           animationDurationUpdate: 500,
           amplitude: '5%',
@@ -150,7 +150,7 @@ export default {
 .dataSituation {
   display: inline-block;
   margin: 5px 10px;
-  width: 100%;
+  width: 80%;
   padding: 0 2%;
   //min-width: 70px;
   height: auto;
@@ -164,7 +164,7 @@ export default {
     color: #B2B2B2;
   }
   .dataSituation-canvas-border {
-    width: 75%;
+    width: 60%;
     margin: 5% auto;
     position: relative;
     .dataSituation-canvas {

+ 2 - 0
src/components/dashboard/portrait/cold/coldTrendChart.vue

@@ -83,6 +83,7 @@ export default {
             stack: 'a',
             yAxisIndex:0,
             smooth: true,
+            showSymbol:false,
             lineStyle: {
               color: "#62CC97",
               width: 1,
@@ -100,6 +101,7 @@ export default {
             type: 'line',
             stack: 'b',
             smooth: true,
+            showSymbol:false,
             yAxisIndex:1,
             lineStyle: {
               color: "#FDB456",

+ 5 - 7
src/components/dashboard/portrait/coldPortrait.vue

@@ -10,22 +10,19 @@ export default {
           title: '月总用冷量(kWh)',
           num: 2000,
           historyDesc: '同比',
-          historyNum: '0.4'
+          historyNum: 0.4
         },
         {
           type: 0,
           title: '今日用冷趋势',
           num: 1800,
           historyDesc: '同比',
-          historyNum: '0.4'
+          showTrendIcon: true,
         },
         {
-          type: 0,
+          type: 1,
           title: '能效比',
-          num: 30,
-          unit: '%',
-          historyDesc: '同比',
-          historyNum: '0.4'
+          content: 80,
         },
         {
           type: 0,
@@ -37,6 +34,7 @@ export default {
         {
           type: 1,
           isHighLight: false,
+          showStar: true,
           title: '值得关注',
           content: ''
         },

+ 1 - 1
src/components/dashboard/portrait/dashboardPortrait.vue

@@ -53,7 +53,7 @@ export default {
   <div class="dashboardPortrait">
     <Card title="统计画像">
       <div style="width: 97%;margin: 0 auto">
-        <a-divider style="margin: 10px 0;padding: 0;"></a-divider>
+        <a-divider style="margin: 0 0 10px;padding: 0;"></a-divider>
       </div>
       <div class="dashboardPortrait-select">
         <a-checkable-tag v-model="tagCheck.person" color="white" class="dashboardPortrait-select-tag" @change="handleTagSelect('person')">

+ 1 - 0
src/components/dashboard/portrait/electricity/electricityUseChart.vue

@@ -74,6 +74,7 @@ export default {
             type: 'line',
             stack: 'x',
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,

+ 5 - 6
src/components/dashboard/portrait/electricityPortrait.vue

@@ -23,23 +23,22 @@ export default {
         {
           type: 0,
           title: '今日用电趋势',
-          num: 30,
-          unit: '%',
+          num: -30,
+          showTrendIcon: true,
           historyDesc: '同比',
-          historyNum: 0.4
         },
         {
           type: 0,
           title: '人均用电成本(元/天)',
-          num: 30,
+          num: 80,
           historyDesc: '同比',
           historyNum: -0.4
         },
         {
           type: 1,
-          isHighLight: false,
+          showStar: true,
           title: '值得关注',
-          content: ''
+          content: '用电成本月增速5%,主为动力用电'
         },
       ]
     }

+ 2 - 0
src/components/dashboard/portrait/hot/hotTrendChart.vue

@@ -83,6 +83,7 @@ export default {
             stack: 'a',
             yAxisIndex:0,
             smooth: true,
+            showSymbol:false,
             lineStyle: {
               color: "#62CC97",
               width: 1,
@@ -101,6 +102,7 @@ export default {
             stack: 'b',
             yAxisIndex:1,
             smooth: true,
+            showSymbol:false,
             itemStyle: {
               color: '#FDB456'
             },

+ 6 - 7
src/components/dashboard/portrait/hotPortrait.vue

@@ -16,29 +16,28 @@ export default {
           type: 0,
           title: '今日用热趋势',
           num: 1800,
+          showTrendIcon: true,
           historyDesc: '同比',
-          historyNum: '0.4'
         },
         {
           type: 0,
           title: '人均用热成本(kWh)',
-          num: 30,
-          unit: '%',
+          num: 10,
           historyDesc: '同比',
           historyNum: '0.4'
         },
         {
           type: 0,
           title: '人均用热量(kWh/天)',
-          num: 30,
+          num: 78,
           historyDesc: '同比',
-          historyNum: '0.4'
+          historyNum: '-0.4'
         },
         {
           type: 1,
-          isHighLight: false,
+          showStar: true,
           title: '值得关注',
-          content: ''
+          content: '本月用热将超行业标准20%'
         },
       ]
     }

+ 2 - 2
src/components/dashboard/portrait/moneyPortrait.vue

@@ -36,9 +36,9 @@ export default {
         },
         {
           type: 1,
-          isHighLight: false,
+          showStar: true,
           title: '值得关注',
-          content: ''
+          content: '本月投资将超行业标准20%'
         },
       ]
     }

+ 7 - 1
src/components/dashboard/portrait/person/personTrendChart.vue

@@ -9,8 +9,11 @@ export default {
     height: Number,
   },
   mounted() {
+    let app = this;
     this.$nextTick(()=>{
-      this.initChart()
+      setTimeout(()=>{
+        app.initChart()
+      },50)
     })
   },
   methods: {
@@ -76,6 +79,7 @@ export default {
             type: 'line',
             stack: 'x',
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,
@@ -99,6 +103,7 @@ export default {
             type: 'line',
             stack: 'x',
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,
@@ -122,6 +127,7 @@ export default {
             type: 'line',
             stack: 'x',
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,

+ 12 - 13
src/components/dashboard/portrait/personPortrait.vue

@@ -7,38 +7,37 @@ export default {
       coreData: [
         {
           type: 0,
-          title: '月总用水量(m³)',
+          title: '进入大楼(人)',
           num: 2000,
           historyDesc: '同比',
-          historyNum: '0.4'
+          historyNum: 0.4
         },
         {
           type: 0,
-          title: '今日用水总量(m³)',
+          title: '离开大楼(人)',
           num: 200,
           historyDesc: '同比',
-          historyNum: '0.4'
+          historyNum: -0.4
         },
         {
           type: 0,
-          title: '今日用水趋势',
-          num: 30,
-          unit: '%',
+          title: '9点前进入大楼(人)',
+          num: 1800,
           historyDesc: '同比',
-          historyNum: '0.4'
+          historyNum: -0.4
         },
         {
           type: 0,
-          title: '人均用水量(m³)',
+          title: '楼内人员数量(人)',
           num: 80,
-          historyDesc: '比',
-          historyNum: '0.4'
+          historyDesc: '比',
+          historyNum: -0.4
         },
         {
           type: 1,
-          isHighLight: false,
           title: '值得关注',
-          content: ''
+          showStar: true,
+          content: '本周上班时间持续延后'
         },
       ]
     }

+ 1 - 0
src/components/dashboard/portrait/restaurant/restaurantTrendChart.vue

@@ -125,6 +125,7 @@ export default {
             },
             yAxisIndex:1,
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,

+ 3 - 4
src/components/dashboard/portrait/restaurantPortrait.vue

@@ -23,20 +23,19 @@ export default {
           type: 0,
           title: '餐厅平均单价(元/单)',
           num: 30,
-          unit: '%',
           historyDesc: '同比',
           historyNum: '0.4'
         },
         {
           type: 1,
           title: '第三方结算方式 费用(元)',
-          content: ''
+          content: '200'
         },
         {
           type: 1,
-          isHighLight: false,
+          showStar: true,
           title: '值得关注',
-          content: ''
+          content: '提高合同额'
         },
       ]
     }

+ 1 - 0
src/components/dashboard/portrait/supermarket/supermarketTrendChart.vue

@@ -125,6 +125,7 @@ export default {
             },
             yAxisIndex:1,
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,

+ 4 - 5
src/components/dashboard/portrait/supermarketPortrait.vue

@@ -22,21 +22,20 @@ export default {
         {
           type: 0,
           title: '商超平均单价(元/单)',
-          num: 30,
-          unit: '%',
+          num: 18,
           historyDesc: '同比',
           historyNum: '0.4'
         },
         {
           type: 1,
           title: '第三方结算方式 费用(元)',
-          content: ''
+          content: '30'
         },
         {
           type: 1,
-          isHighLight: false,
           title: '值得关注',
-          content: ''
+          showStar: true,
+          content: '提高合同额'
         },
       ]
     }

+ 1 - 0
src/components/dashboard/portrait/water/waterUseChart.vue

@@ -74,6 +74,7 @@ export default {
             type: 'line',
             stack: 'x',
             smooth: true,
+            showSymbol:false,
             areaStyle: {
               color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                 offset: 0,

+ 4 - 4
src/components/dashboard/portrait/waterPortrait.vue

@@ -24,22 +24,22 @@ export default {
           type: 0,
           title: '今日用水趋势',
           num: 30,
-          unit: '%',
+          showTrendIcon: true,
           historyDesc: '同比',
           historyNum: '0.4'
         },
         {
           type: 0,
           title: '人均用水量(m³)',
-          num: 30,
+          num: 60,
           historyDesc: '同比',
           historyNum: '0.4'
         },
         {
           type: 1,
-          isHighLight: false,
+          showStar: true,
           title: '值得关注',
-          content: ''
+          content: '用水量低于行业标准20%'
         },
       ]
     }

+ 1 - 4
src/components/doubleCarbon/PV/doubleCarbonPv.vue

@@ -44,10 +44,7 @@
             <span class="core_info_title">{{ item.info.title }}</span
             ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
               >{{ item.info.value
-              }}<i
-                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
-                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
-            /></span>
+              }}<a-icon v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)" :type="item.info.leavel == 3 ? 'caret-up' : 'caret-down'" /></span>
           </div>
         </div>
       </div>

+ 1 - 4
src/components/doubleCarbon/car/doubleCarbonCar.vue

@@ -44,10 +44,7 @@
             <span class="core_info_title">{{ item.info.title }}</span
             ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
               >{{ item.info.value
-              }}<i
-                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
-                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
-            /></span>
+              }}<a-icon v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)" :type="item.info.leavel == 3 ? 'caret-up' : 'caret-down'" /></span>
           </div>
         </div>
       </div>

+ 1 - 4
src/components/doubleCarbon/print/doubleCarbonPrint.vue

@@ -44,10 +44,7 @@
             <span class="core_info_title">{{ item.info.title }}</span
             ><span class="core_info_value" :style="{ color: $constant.COLOR_LEAVEL[item.info.leavel] }"
               >{{ item.info.value
-              }}<i
-                v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)"
-                :class="item.info.leavel == 3 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'"
-            /></span>
+              }}<a-icon v-if="item.info.leavel && (item.info.leavel == 1 || item.info.leavel == 3)" :type="item.info.leavel == 3 ? 'caret-up' : 'caret-down'" /></span>
           </div>
         </div>
       </div>

+ 19 - 24
src/components/home/ContainerAside.vue

@@ -6,14 +6,12 @@ export default {
     return {
       selectedKeys: [],
       highLight: {backgroundColor: '#e9f6fd'},
-      routers: [],
       menuList: [],
       height: '100%',
     }
   },
   mounted() {
     let app = this;
-    this.routers = this.$router.options.routes;
     this.$nextTick(() => {
       app.getCurrMenuList()
     })
@@ -22,28 +20,25 @@ export default {
   methods: {
     requireImg,
     getCurrMenuList() {
-      let arr = this.$route.matched;
-      let route = this.routers[0].children;
-      if (arr.length>1) {
-        let obj = route.find((e) => (e.path == arr[1].path));
-        route = obj.children;
+      let matchRoutes = this.$route.matched;
+      let menu = this.$store.menuStore().currMenu
+      this.menuList = [];
+      if (menu.children && menu.children.length>0) {
+        this.menuList = JSON.parse(JSON.stringify(menu.children))
       }
-      this.menuList = JSON.parse(JSON.stringify(route))
-      this.selectedKeys = [];
-      if (arr.length>2) {
-        for (let i = 0; i < arr.length; i++) {
-          this.selectedKeys.push(arr[i].path)
-        }
-      } else if (arr.length===2) {
-        if (this.menuList.length>0 && !this.menuList[0].children) {
-          this.handleClick(this.menuList[0]);
-          this.selectedKeys.push(this.menuList[0].path)
-        }
+      if (matchRoutes.length===2) {
+        this.toRoute(this.menuList[0].router)
+      } else if (matchRoutes.length>2) {
+        let route = this.$route.matched[2];
+        this.toRoute(route.path)
       }
     },
     handleClick(item) {
-      let path = item.path?item.path:item.key
+      this.toRoute(item.key)
+    },
+    toRoute(path) {
       this.$router.push({path: path})
+      this.selectedKeys = [path]
       this.$forceUpdate()
     }
   }
@@ -60,12 +55,12 @@ export default {
         @click="handleClick"
     >
       <template v-for="item in menuList">
-        <a-menu-item  class="menuItem" :key="item.path" :route="item.key" v-if="item.meta.hideChild || !item.children">
+        <a-menu-item  class="menuItem" :key="item.router" :route="item.router" v-if="!item.children">
         <span class="anticon" style="vertical-align: text-top">
           <a-avatar class="function-avatar" shape="square" :size="20" :src="requireImg(item.icon)"></a-avatar>
         </span>
           <span >
-            {{ item.meta.breadcrumb }}
+            {{ item.name }}
           </span>
         </a-menu-item>
 
@@ -74,13 +69,13 @@ export default {
             <span class="anticon" style="vertical-align: text-top">
           <a-avatar class="function-avatar" shape="square" :size="20" :src="requireImg(item.icon)"></a-avatar>
         </span>
-            <span>{{ item.meta.breadcrumb }}</span>
+            <span>{{ item.name }}</span>
           </template>
-          <a-menu-item v-for="subItem in item.children" :key="subItem.path" :route="subItem.path">
+          <a-menu-item v-for="subItem in item.children" :key="subItem.router" :route="subItem.router">
             <span class="anticon" style="vertical-align: text-top">
           <a-avatar class="function-avatar" shape="square" :size="20" :src="requireImg(item.icon)"></a-avatar>
         </span>
-            <span>{{ subItem.meta.breadcrumb }}</span>
+            <span>{{ subItem.name }}</span>
           </a-menu-item>
         </a-sub-menu>
       </template>

+ 11 - 1
src/components/home/HomeAside.vue

@@ -18,6 +18,10 @@ export default {
     collapse(val) {
       this.suitHeight(val)
     },
+    $route() {
+      this.getCurrRoute()
+      this.$forceUpdate();
+    }
   },
   mounted() {
     this.suitHeight(this.collapse)
@@ -57,10 +61,15 @@ export default {
         if (this.$route.matched.length>1) {
           this.selectedKey = [this.$route.matched[1].path+'']
         }
+        let index = this.menuList.findIndex(i=>i.router==this.selectedKey)
+        this.handleClickMenuItem(this.menuList[index])
         this.$forceUpdate()
       })
 
     },
+    handleClickMenuItem(item) {
+      this.$store.menuStore().currMenu = item;
+    },
     handleSelected(item) {
       this.$router.push({path: item.key})
     },
@@ -88,7 +97,7 @@ export default {
           </div>
         </template>
       </a-menu-item-group>
-      <a-menu-item v-for="item in menuList" :key="item.router" >
+      <a-menu-item v-for="item in menuList" :key="item.router" @click="handleClickMenuItem(item)" >
         <span class="anticon" :style="{verticalAlign: iconVerticalAlign}">
           <a-avatar class="function-avatar" shape="square" :size="20" :src="requireImg(item.icon)"></a-avatar>
         </span>
@@ -121,6 +130,7 @@ export default {
   //width: 100%;
   height: 100%;
 
+  /*菜单样式*/
   /deep/ .ant-menu-sub {
     box-shadow: none !important;
   }

+ 21 - 18
src/components/home/HomeHeader.vue

@@ -2,36 +2,38 @@
 import logoPng from '@/assets/images/logo.png'
 export default {
   props: {
-    //collapse: Boolean,
+    leftVisible: Boolean,
     isLogin: Boolean,
   },
-  //emits: ['update:collapse'],
-  //setup(props, context) {
-  //  const methods = {
-  //    toggleCollapse() {
-  //      const val = !props.collapse
-  //      context.emit('update:collapse', val)
-  //    },
-  //  }
-  //  return methods
-  //},
+  emits: ['update:leftVisible'],
+  setup(props, context) {
+    const methods = {
+      toggleLeftVisible() {
+        const val = !props.leftVisible
+        context.emit('update:leftVisible', val)
+      },
+    }
+    return methods
+  },
   data() {
     return {
       logoPng,
-      hasMsg: false,
+      hasMsg: true,
     }
   },
   mounted() {
   },
   methods: {
-
+    toNotice() {
+      this.$router.push({path: '/notice'})
+    }
   },
 }
 </script>
 
 <template>
   <div class="header">
-    <div v-show="isLogin" class="fold">
+    <div v-show="isLogin" class="fold" @click="toggleLeftVisible">
       <a-icon type="unordered-list" class="icon" />
     </div>
     <div class="systemInfo">
@@ -61,8 +63,8 @@ export default {
       <a-icon type="mobile" class="icon" />
       <span v-show="isLogin">
         <a-icon type="question-circle" class="icon" />
-        <a-icon v-if="!hasMsg" type="bell" class="icon" />
-        <a-badge v-if="hasMsg" dot :offset="[-15, 15]">
+        <a-icon v-if="!hasMsg" type="bell" class="icon" @click="toNotice" />
+        <a-badge v-if="hasMsg" dot :offset="[-15, 15]" @click="toNotice">
           <a-icon type="bell" class="icon" />
         </a-badge>
       </span>
@@ -105,13 +107,13 @@ export default {
   .systemInfo {
     vertical-align: top;
     color: white;
-    font-weight: bolder;
     letter-spacing: 4px;
     margin-left: 12px;
     .logo {
       vertical-align: top;
       margin-right: 10px;
       margin-top: 15px;
+      pointer-events: none;
     }
     .title {
       display: inline-block;
@@ -119,7 +121,8 @@ export default {
       margin-left: 10px;
       line-height: 60px;
       font-size: 22px;
-      letter-spacing: 6px;
+      letter-spacing: 8px;
+      //font-family: PingFangSC-Bold,serif;
     }
   }
   .project {

+ 121 - 0
src/components/home/HomeLeft.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="homeLeft">
+    <a-menu
+        style="height: 100%;width: 200px;display: inline-block"
+        mode="inline"
+        theme="dark"
+    >
+
+      <a-menu-item-group key="g1" >
+        <template slot="title">
+          <div @mouseover="showNav" class="allNavBtn">
+            <div style="height: 12px"></div>
+            <a-icon style="color: white" type="appstore" />
+            <span style="color: white;display: inline-block;margin-left: 12px">全部导航模块</span>
+            <a-icon style="color: white;float: right;margin-right: 15px;padding-top: 3px;font-size: 12px" type="right" />
+          </div>
+        </template>
+      </a-menu-item-group>
+
+      <a-menu-item-group key="common" @mouseover="hideNav" >
+        <template slot="title">
+          <div style="text-align: center;margin-bottom: 12px">
+            <span style="color: white;display: inline-block;margin-left: 12px">常用功能</span>
+          </div>
+        </template>
+
+        <a-menu-item>
+          智能看板
+        </a-menu-item>
+      </a-menu-item-group>
+
+    </a-menu>
+
+    <div class="ioc-nav" v-if="navVisible"  >
+      <NavigationPage :to-route="toRoute" />
+    </div>
+
+  </div>
+</template>
+
+<script>
+import NavigationPage from "@/components/home/NavigationPage.vue";
+export default {
+  data() {
+    return {
+      navVisible: false
+    }
+  },
+  props: {
+    close: Function,
+  },
+  components: {
+    NavigationPage
+  },
+  methods: {
+    toRoute(item, parent) {
+      this.$store.menuStore().currMenu = parent;
+      this.$router.push({path: item.router});
+      this.close();
+    },
+    showNav() {
+      this.navVisible = true;
+    },
+    hideNav() {
+      this.navVisible = false;
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+@menu-dark-bg: #266a99;
+@menu-dark-submenu-bg: #266a99;
+@menu-dark-color: #fff;
+@menu-dark-arrow-color: #fff;
+@menu-dark-highlight-color: #fff;
+.homeLeft {
+  width: 100%;
+  height: 100%;
+
+  .allNavBtn {
+    width: 100%;
+    cursor: pointer;
+    //text-align: center;
+    padding-bottom: 10px;
+    padding-left: 15%;
+    margin: 12px 0;
+  }
+  .allNavBtn:hover {
+    background-color: @primary-color;
+  }
+
+  .ioc-nav {
+    display: inline-block;
+    vertical-align: top;
+    width: 70%;
+  }
+
+  /deep/ .ant-menu-item-group-title {
+    padding: 0;
+  }
+
+  /*菜单样式*/
+  /deep/ .ant-menu-sub {
+    box-shadow: none !important;
+  }
+  /deep/ .ant-menu-item-selected {
+    color: @menu-dark-selected-item-text-color !important;
+  }
+  .ant-menu-inline-collapsed > .ant-menu-item {
+    padding: 0 !important;
+    margin-left: 0 !important;
+    padding-left: 33% !important;
+  }
+  /deep/ .ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item {
+    padding: 0 !important;
+    margin-left: 0 !important;
+    padding-left: 33% !important;
+  }
+}
+</style>

+ 13 - 11
src/components/home/NavigationPage.vue

@@ -1,11 +1,13 @@
 <template>
-  <div class="dashboard">
-    <div class="menu" v-for="menu in menuList" :key="menu.name">
-      <div class="menu-title">{{menu.name}}</div>
-      <ul class="menu-content" >
-        <li class="menu-content-item" v-for="item in menu.children" :key="item.name" >{{ item.name }}</li>
-      </ul>
-    </div>
+  <div class="left-dashboard">
+    <template v-for="menu in menuList">
+      <div class="menu" v-if="menu.name!=='智能看板'" :key="menu.name">
+        <div class="menu-title">{{menu.name}}</div>
+        <ul class="menu-content" >
+          <li class="menu-content-item" v-for="item in menu.children" :key="item.name" @click="toRoute(item, menu)" >{{ item.name }}</li>
+        </ul>
+      </div>
+    </template>
     <div class="menu sso">
       <div class="menu-title">单点登录</div>
       <div class="menu-content sso-item" v-for="item in ssoList" :key="item.name" >
@@ -26,27 +28,26 @@ export default {
     }
   },
   props: {
-
+    toRoute: Function
   },
   created() {
   },
   mounted() {
   },
   methods: {
-
   }
 
 }
 </script>
 
 <style lang="less" scoped>
-.dashboard {
+.left-dashboard {
   .menu {
     display: inline-block;
     vertical-align: top;
     width: 150px;
     height: 200px;
-    margin: 10px;
+    margin: 30px;
     .menu-title {
       margin-left: 20px;
       margin-top: 10px;
@@ -64,6 +65,7 @@ export default {
         line-height: 30px;
         letter-spacing: 1px;
         color: #101010;
+        cursor: pointer;
       }
     }
   }

+ 89 - 0
src/components/notice/notice.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="ioc-notice">
+
+    <a-layout style="height: 100%">
+      <a-layout-sider v-model="collapsed" :trigger="null" collapsible>
+        <div class="logo" />
+        <a-menu :default-selected-keys="['unReadNotice']" theme="dark" mode="inline" style="height: 100%" @click="handleClick">
+          <a-menu-item-group key="message">
+            <template slot="title">
+              <span style="color: #f0f2f5">通知</span>
+            </template>
+            <a-menu-item key="unReadNotice">
+              未读通知
+            </a-menu-item>
+            <a-menu-item key="readNotice">
+              已读通知
+            </a-menu-item>
+            <a-menu-item key="allNotice">
+              全部通知
+            </a-menu-item>
+          </a-menu-item-group>
+          <a-menu-item-group key="feedback">
+            <template slot="title">
+              <span style="color: #f0f2f5">用户反馈</span>
+            </template>
+            <a-menu-item key="unReadFeedback">
+              未读反馈
+            </a-menu-item>
+            <a-menu-item key="readFeedback">
+              已读反馈
+            </a-menu-item>
+            <a-menu-item key="allFeedback">
+              全部反馈
+            </a-menu-item>
+          </a-menu-item-group>
+
+        </a-menu>
+      </a-layout-sider>
+      <a-layout>
+        <a-layout-content
+            :style="{ margin: '12px', padding: '15px', background: '#fff', minHeight: '280px' }"
+        >
+          <NoticeList :type="type"></NoticeList>
+        </a-layout-content>
+      </a-layout>
+    </a-layout>
+
+  </div>
+</template>
+
+<script>
+import NoticeList from "@/components/notice/noticeList.vue";
+export default {
+  data() {
+    return {
+      collapsed: false,
+      type: 'unReadNotice'
+    }
+  },
+  components: {
+    NoticeList
+  },
+  mounted() {
+  },
+  methods: {
+    handleClick(e) {
+      this.type = e.key
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+@menu-dark-bg: #266a99;
+@menu-dark-submenu-bg: #266a99;
+@menu-dark-color: #fff;
+@menu-dark-arrow-color: #fff;
+@menu-dark-highlight-color: #fff;
+.ioc-notice {
+  width: 100%;
+  height: 100%;
+  .ioc-notice-left {
+
+  }
+  .ioc-notice-right {
+
+  }
+}
+</style>

+ 156 - 0
src/components/notice/noticeList.vue

@@ -0,0 +1,156 @@
+<template>
+  <div class="ioc-notice-list">
+    <div class="ioc-notice-list-header">
+      <span v-if="type==='unReadNotice'">未读通知</span>
+      <span v-else-if="type==='readNotice'">已读通知</span>
+      <span v-else-if="type==='allNotice'">全部通知</span>
+      <span v-else-if="type==='unReadFeedback'">未读反馈</span>
+      <span v-else-if="type==='readFeedback'">已读反馈</span>
+      <span v-else-if="type==='allFeedback'">全部反馈</span>
+      <span v-else></span>
+    </div>
+    <div class="ioc-notice-list-query">
+      <div style="display: inline-block;vertical-align: middle">
+        <a-button >设为已读</a-button>
+        <a-button >删除</a-button>
+      </div>
+
+      <div style="display: inline-block;vertical-align: middle;float: right;">
+        <a-form layout="inline" :form="formData">
+          <a-form-item>
+            <a-select style="width: 120px" placeholder="告警类别">
+              <a-select-option value="system">系统通知</a-select-option>
+              <a-select-option value="device">设备通知</a-select-option>
+              <a-select-option value="alarm">设备告警</a-select-option>
+            </a-select>
+          </a-form-item>
+          <a-form-item>
+            <TimeRange></TimeRange>
+          </a-form-item>
+          <a-form-item>
+            <a-button size="small">重置</a-button>
+            <a-button size="small">查询</a-button>
+          </a-form-item>
+        </a-form>
+      </div>
+    </div>
+    <div class="ioc-notice-list-content">
+      <a-table :rowKey="(record, index) => index"
+               style="height: 100%"
+               :columns="columns"
+               :data-source="tableData"
+               :pagination="false"
+               :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+      >
+        <template #operation="text">
+          <a-button type="link">删除</a-button>
+          <a-button type="link" >查看</a-button>
+        </template>
+      </a-table>
+      <a-pagination
+          show-size-changer
+          :default-current="3"
+          :total="500"
+          style="float: right"
+      />
+      <br />
+    </div>
+  </div>
+</template>
+
+<script>
+import TimeRange from "@/components/common/timeRange.vue";
+
+export default {
+  components: {TimeRange},
+  watch: {
+    type: function (val) {
+      this.refresh();
+    }
+  },
+  data() {
+    return {
+      formData: {},
+      selectedRowKeys: [],
+      columns: [
+        {
+          title: '告警类别',
+          dataIndex: 'type',
+          align: 'center',
+          width: 150,
+          key: 'type'
+        },
+        {
+          title: '事件内容',
+          dataIndex: 'content',
+          align: 'center',
+          key: 'content'
+        },
+        {
+          title: '告警地点',
+          dataIndex: 'area',
+          align: 'center',
+          minWidth: 240,
+          key: 'area'
+        },
+        {
+          title: '告警时间',
+          dataIndex: 'time',
+          align: 'center',
+          width: 240,
+          key: 'time'
+        },
+        {
+          title: '操作',
+          dataIndex: 'operation',
+          key: 'operation',
+          width: 200,
+          align: 'center',
+          scopedSlots: { customRender: 'operation' },
+        }
+      ],
+      tableData: [
+        {
+          type: '设备告警',
+          content: '位于1层301的水浸设备出现告警,请尽快派人处理',
+          area: '1层301',
+          time: '2022年7月11日 12:01:00',
+        }
+      ],
+    }
+  },
+  props: {
+    type: String,
+  },
+  mounted() {
+  },
+  methods: {
+    refresh() {
+      this.formData = {};
+      this.selectedRowKeys = [];
+    },
+    onSelectChange(selectedRowKeys) {
+      this.selectedRowKeys = selectedRowKeys;
+    }
+
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.ioc-notice-list {
+  width: 100%;
+  height: 100%;
+
+  .ioc-notice-list-header {
+    font-size: 16px;
+  }
+
+  .ioc-notice-list-query {
+    margin: 12px 0;
+  }
+  .ioc-notice-list-content {
+    height: 600px;
+  }
+}
+</style>

+ 147 - 0
src/components/scene/AnalogData.js

@@ -0,0 +1,147 @@
+// 双碳概览-模拟数据
+// 楼层\会议室状态\会议室人数
+const floor = [
+    { value: "1", label: "一楼" },
+    { value: "2", label: "二楼" }
+]
+const conferenceRoomStatus = [
+    { value: "1", label: "会议中" },
+    { value: "2", label: "闲置中" },
+    { value: "3", label: "已预订" }
+]
+const numberOfPeopleInConferenceRoom = [
+    { value: "1", label: "4人" },
+    { value: "2", label: "8人" },
+    { value: "3", label: "16人" }
+]
+const CHART_DATA = {
+    BarChartData: {
+        yAxisData: ["中讯", "北京规划院", "郑分", "广分", "上分"],
+        seriesData: {
+            碳配额存量: [120, 132, 101, 134, 90, 230, 210],
+            碳配额消耗: [220, 182, 191, 234, 290, 330, 310]
+        }
+    },
+    LineChartData: {
+        xAxisData: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],
+        seriesData: {
+            中讯: [120, 132, 101, 134, 90, 230, 210],
+            北京规划院: [220, 182, 191, 234, 290, 330, 310],
+            郑分: [150, 232, 201, 154, 190, 330, 410],
+            广分: [320, 332, 301, 334, 390, 330, 320],
+            上分: [820, 932, 901, 934, 1290, 1330, 1320]
+        }
+    },
+    PieChartData: {
+        seriesName: "碳排放占比",
+        seriesData: [
+            { value: 1048, name: "汽油" },
+            { value: 735, name: "柴油" },
+            { value: 580, name: "天然气" },
+            { value: 484, name: "热力" },
+            { value: 300, name: "电力" },
+            { value: 199, name: "其他" }
+        ]
+    }
+}
+const doubleCarbonNewsInfoList = [
+    {
+        title: "【助力“双碳”,人才缺口这么补】",
+        content: `<div class="article"><p>  近日,天津市科学技术局等6部门发布《天津市科技支撑碳达峰碳中和实施方案(2022—2030年)》,提出加强绿色低碳领域人才选拔培养,加大对绿色低碳领域科技人才的支持力度,积极引进绿色低碳科技创新发展急需的各类人才,加强人才队伍建设。</p>
+<p>  不只是天津,放眼全国,上海、吉林、贵州、内蒙古等地相关政府部门也已经陆续发布了关于科技支撑碳达峰、碳中和(以下简称“双碳”)的实施方案,其中“提升绿色低碳人才培养能力”成为各地方案中都提到的一项内容。</p>
+<p>  <strong>产业、技术变革催生新需求</strong></p>
+<p>  2020年,我国提出采取更加有力的政策和措施,二氧化碳排放力争2030年前达到峰值,努力争取2060年前实现碳中和。这就是人们熟知的“双碳”目标。</p>
+<p>  其实,早在“双碳”目标提出前,我国的清洁能源建设已经取得重大成就,在水电、风电、光伏及氢能、储能等领域,人才队伍培养与建设均在有序进行。而当“双碳”目标提出后,一场广泛而深刻的经济社会系统性变革就此开始,清洁能源领域人才队伍开始走上助力实现“双碳”目标的转型之路。</p>
+<p>  面对新形势,原有人才队伍能否满足需求呢?</p>
+<p>  答案是否定的。</p>
+<p>  科技部科技人才交流开发服务中心开发服务处处长牛萍在具体调研中发现,战略科学家不足、复合型人才稀少、产业人才短缺成为当前“双碳”科技人才市场的主要特点。</p>
+<p>  牛萍告诉科技日报记者,面向“双碳”目标,通识教育难以满足复合型“双碳”科技人才的培养需求,导致高校“双碳”科技人才培养与市场需求不匹配。与此同时,“双碳”领域相关产学研合作不足,产业人才缺乏,这些都是导致“双碳”人才出现紧缺的原因。</p>
+<p>  在具体产业方面,从教育部下发的方案中可以看出,储能与氢能、碳捕集利用与封存、碳金融和碳交易等领域尤其缺乏人才支撑。</p>
+<p>  “人才需求的改变,源于产业需求的变化。”相关业内专家表示,“在‘双碳’目标提出前,氢能和储能产业关注的是‘能’,而在‘双碳’目标提出后,产业的关注点转变为‘碳’。换言之,‘双碳’目标的提出使氢能和储能等相关产业的技术目标,由追求相对减排率转变为追求绝对减排量。”</p>
+<p>  不仅是产业变化,技术变革也会带来人才需求的改变。</p>
+<p>  二氧化碳捕集、利用与封存(CCUS)技术被形象地称为“碳捕手”,其可将二氧化碳从工业或其他碳排放源中捕集,并运输到特定地点加以利用或封存,具有减排规模大、减排效益明显的特点。</p>
+<p>  不过,在过去很长一段时间内,二氧化碳捕集、利用与封存技术并未“合体”,而是各自分散在不同行业。伴随降碳要求的不断增加,化石能源大规模低碳化利用的技术需求也随之增加,二氧化碳捕集、利用与封存技术被有机地“组合”到一起。同时,行业从业者也要完成技能、知识等的“交叉融合”,此外还需要复合型人才的加入。</p>
+<p>  <strong>产学研多方推进人才培养</strong></p>
+<p>  在内蒙古乌兰察布市,三峡现代能源创新示范园(以下简称示范园)拔地而起。示范园里,中国长江三峡集团有限公司(以下简称三峡集团)“拉了个群”,联合产学研合作伙伴,共同探索“源网荷储”(以“电源、电网、负荷、储能”为整体规划的新型电力运行模式)一体化新型能源系统发展,建设源网荷储技术研发试验基地。</p>
+<p>  “示范园中的源网荷储技术研发试验基地,是三峡集团培养储能技术人才的一个基地。”三峡集团科学技术研究院综合能源技术研究中心主任尹立坤告诉科技日报记者,2020年,他们综合考量全球先进储能技术,结合我国地理、气候特点,选择对8种新型储能技术进行研究,并建成2个行业急需的大型实验室,联合中国科学院、清华大学、华北电力大学等20余家科研单位进行技术攻关,联合培养人才。</p>
+<p>  此后短短2年,一系列储能技术成果相继落地:当前国内容量最大的功率路由器设备,国内规模最大、类型最丰富的储能系统动态模拟平台,兆瓦时级固态锂离子电池储能关键技术及工程应用项目……</p>
+<p>  科研成果创下“行业之最”的同时,科研人才也不断涌现。三峡集团科学技术研究院统计资料显示,目前集团已培养博士20余名,其中15名青年骨干研发人员已走上企业储能一线工作岗位。</p>
+<p>  产业之外,以培养人才为己任的高校也加快了探索的脚步。</p>
+<p>  2021年9月,清华大学成立碳中和研究院。作为学科交叉研究平台,该研究院整合清华大学相关领域学科优势,直面“双碳”领域复合型人才稀少等难题,协同打造低碳、零碳、负碳等颠覆性的核心技术,推动碳中和相关学科建设和高层次人才培养。</p>
+<p>  清华大学碳中和研究院院长助理、环境学院教授鲁玺介绍,目前清华大学碳中和研究院有8个研究中心,研究方向涵盖低碳能源、新型电力系统、零碳建筑、零碳交通、工业深度减碳、减污降碳协同增效、气候变化与碳中和战略及气候治理与碳金融等交叉领域,以系统思维推动碳中和人才队伍建设和培养。</p>
+<p>  <strong>关键一步在于转变观念</strong></p>
+<p>  2021年10月24日,《中共中央国务院关于完整准确全面贯彻新发展理念做好碳达峰碳中和工作的意见》和《国务院关于印发2030年前碳达峰行动方案的通知》正式印发,从国家层面对“双碳”工作进行顶层设计。此后,各领域“双碳”行动方案陆续出台,“双碳”“1+N”政策体系不断完善,“双碳”科技人才培养的政策举措不断优化。</p>
+<p>  2022年4月24日,教育部印发《加强碳达峰碳中和高等教育人才培养体系建设工作方案》,从加快紧缺人才培养、促进传统专业转型升级、加强高水平教师队伍建设等9个方面,明确22条主要任务和重点举措。同年8月17日,科技部等九部门发布《科技支撑碳达峰碳中和实施方案(2022—2030)》,提出推动国家绿色低碳创新基地建设和人才培养,培养和发展壮大碳达峰碳中和领域战略科学家、科技领军人才和创新团队、青年人才和创新创业人才,建设面向实现碳达峰碳中和目标的可持续人才队伍。</p>
+<p>  “对于‘双碳’人才的培养,我国在‘双碳’‘1+N’政策体系下,不断统筹优化‘双碳’科技人才培养举措,顶层设计已相对健全。”牛萍介绍,但在省市区县各级政府部门制定的“双碳”工作实施方案及规划中,对“双碳”人才培养虽有所提及,却仍然缺乏关于“双碳”人才的专项政策,缺少更具体的实施举措。</p>
+<p>  在牛萍看来,双碳人才培养的关键一步在于转变观念。从科研人才到产业人才,都需要将“碳”的观念树立起来,提升自身的“双碳”素养,让“双碳”理念先行。尤其是各级政府部门,可以通过开展科技人才“双碳”素养提升行动,为各类“双碳”人才涌现营造良好的生态环境。</p>
+<p>  未来,面向“双碳”科技人才的培养需求,牛萍建议,要建立“双碳”重点领域全球高层次人才动态监测机制,为“双碳”科技人才靶向引进和自主培养提供决策参考;加强符合“双碳”标准的复合型科技人才培养,在国际标准平台上扩大中国的影响力。</p></div>`,
+        author: "科技日报",
+        pushTime: "2023-02-13 15:30"
+    },
+    {
+        title: "【减碳小妙招】",
+        content: "xxxxxxxxxxxxxxxxxx165465465465xxxxx",
+        author: "中讯邮电设计院-张三",
+        pushTime: "2021-08-09"
+    },
+    {
+        title: "【减碳小妙招】",
+        content: "xxxxxxxxxxxxxxxxxxxxxxx",
+        author: "中讯邮电设计院-张三",
+        pushTime: "2021-08-09"
+    }
+]
+const core_List = [
+    {
+        title: "碳配额存量",
+        value: "60%",
+        leavel: 1
+    },
+    {
+        title: "碳排放存量",
+        value: 500,
+        unit: "tCO2e",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "单位面积碳排放",
+        value: 380,
+        unit: "tCO2e/m²",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "人均碳排放",
+        value: 80,
+        unit: "tCO2e/人",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "光伏减排",
+        value: 40,
+        unit: "tCO2e",
+        info: {
+            title: "同比上升",
+            leavel: 3,
+            value: "0.4%"
+        }
+    },
+    {
+        title: "值得关注",
+        value: "减少2辆车出行一周"
+    }
+]
+export default {
+    floor, conferenceRoomStatus, numberOfPeopleInConferenceRoom, CHART_DATA, doubleCarbonNewsInfoList, core_List
+}

+ 314 - 2
src/components/scene/meeting/sceneMeeting.vue

@@ -1,3 +1,315 @@
+<!--
+    智慧场景-智·会议-配置会议
+    @author 刘梦祥
+    @date 2023年2月22日
+-->
 <template>
-  <router-view />
-</template>
+  <div class="doubleCarbon-main-box flexColumn">
+    <a-spin class="spinStyle" size="large" tip="Loading..." v-show="searchLoading"></a-spin>
+    <a-tabs default-active-key="1" @change="callback">
+      <a-tab-pane key="1" tab="会议室总览">
+        <!-- 头部搜索区域 -->
+        <div class="borderColor" style="margin-bottom: 0.5rem;">
+          <div class="flex flex_between margin5rem">
+            <div class="flex">
+              <div class="mr1rem">
+                时间:
+                <a-range-picker
+                  show-time
+                  id="rangePicker"
+                  :placeholder="['开始时间', '结束时间']"
+                  @change="onChangeRangeDate"
+                  separator="至"
+                  :show-time="{
+                    hideDisabledOptions: true,
+                    defaultValue: [$moment('00:00:00', 'HH:mm:ss'), $moment('23:59:59', 'HH:mm:ss')]
+                  }"
+                  format="YYYY-MM-DD HH:mm:ss"
+                >
+                </a-range-picker>
+              </div>
+              <div class="mr1rem">
+                楼层:
+                <a-select
+                  style="width:200px;"
+                  v-model="searchParam.floor"
+                  :allowClear="selectProps.allowClear"
+                  :mode="selectProps.mode"
+                  :options="options.floor"
+                  :notFoundConent="selectProps.notFoundConent"
+                  :placeholder="selectProps.placeholder"
+                ></a-select>
+              </div>
+              <div class="mr1rem">
+                会议室状态:
+                <a-select
+                  style="width:200px;"
+                  v-model="searchParam.conferenceRoomStatus"
+                  :allowClear="selectProps.allowClear"
+                  :mode="selectProps.mode"
+                  :options="options.conferenceRoomStatus"
+                  :notFoundConent="selectProps.notFoundConent"
+                  :placeholder="selectProps.placeholder"
+                ></a-select>
+              </div>
+              <div class="mr1rem">
+                会议室人数:
+                <a-select
+                  style="width:200px;"
+                  v-model="searchParam.numberOfPeopleInConferenceRoom"
+                  :allowClear="selectProps.allowClear"
+                  :mode="selectProps.mode"
+                  :options="options.numberOfPeopleInConferenceRoom"
+                  :notFoundConent="selectProps.notFoundConent"
+                  :placeholder="selectProps.placeholder"
+                ></a-select>
+              </div>
+            </div>
+            <div>
+              <a-button class="mr1rem" @click="reset">重置</a-button>
+              <a-button type="primary" @click="search">查询</a-button>
+            </div>
+          </div>
+        </div>
+        <!-- 碳排放分析和碳配额构成 -->
+        <div class="flexColumn">
+          <div class="floorBox borderColor padding5rem">
+            <div class="floorTitle margin5rem flex_between" style="flex-wrap: nowrap;">
+              3F
+              <div class="titleLine"></div>
+            </div>
+            <div class="margin5rem chartDomBox">other</div>
+          </div>
+        </div>
+      </a-tab-pane>
+      <a-tab-pane key="2" tab="智能策略"> 智能策略 </a-tab-pane>
+    </a-tabs>
+  </div>
+</template>
+
+<script>
+import LineChart from "../../echart/LineChart.vue";
+import BarChart from "../../echart/BarChart.vue";
+import PieChart from "../../echart/PieChart.vue";
+// 模拟数据
+import AnalogData from "../AnalogData.js";
+export default {
+  components: {
+    LineChart,
+    BarChart,
+    PieChart
+  },
+  data() {
+    return {
+      // selectProps配置
+      selectProps: {
+        allowClear: true, // 支持清除
+        mode: "default", // 模式['default'|'multiple'|'tags'|'combobox']
+        notFoundConent: "Not Found", // 当下拉列表为空时显示的内容
+        placeholder: "请选择", // 选择框默认文字 string|slot
+        showArrow: true, // 是否显示下拉小箭头
+        size: "large" // 选择框大小['large'|'small']
+      },
+      // options 数据,如果设置则不需要手动构造 selectOption 节点
+      options: {
+        floor: [], // 楼层
+        conferenceRoomStatus: [], // 会议室状态
+        numberOfPeopleInConferenceRoom: [] // 会议室人数
+      },
+      // loading状态
+      searchLoading: true,
+      // 头部搜索条件中绑定值
+      monthArr: [],
+      searchParam: {
+        floor: undefined,
+        timeRange: [undefined, undefined],
+        conferenceRoomStatus: undefined,
+        numberOfPeopleInConferenceRoom: undefined
+      },
+      // 头部核心指标循环显示数据
+      coreList: [],
+      // 双碳新闻模拟数据
+      DoubleCarbonNewsInfoList: [],
+      // 双碳新闻弹窗打开状态
+      showModalStatus: false,
+      // 弹窗暂存数据对象
+      showModalInfo: {
+        title: "--",
+        content: "--",
+        author: "--",
+        pushTime: "--"
+      },
+      // chart暂存数据对象
+      chartData: []
+    };
+  },
+  created() {},
+  mounted() {
+    // 页面初始化
+    this.init();
+    // this.searchLoading = false;
+    //默认是当日24小时
+    setTimeout(() => {
+      this.defaulTimeRangeS();
+    }, 0);
+  },
+  methods: {
+    callback() {
+      // console.log("tabs切换");
+    },
+    onChangeRangeDate(date, dateStr) {
+      this.searchParam.timeRange = dateStr;
+    },
+    // 时间初始化
+    defaulTimeRangeS() {
+      this.searchParam.timeRange[0] = this.$moment().format("YYYY-MM-DD 00:00:00");
+      this.searchParam.timeRange[1] = this.$moment().format("YYYY-MM-DD 23:59:59");
+      setTimeout(() => {
+        document.getElementById("rangePicker").querySelectorAll("input")[0].value = this.searchParam.timeRange[0];
+        document.getElementById("rangePicker").querySelectorAll("input")[1].value = this.searchParam.timeRange[1];
+      }, 0);
+    },
+    // 查询事件
+    search() {
+      this.searchLoading = true;
+      console.log(
+        "查询条件:",
+        this.searchParam.floor,
+        this.searchParam.conferenceRoomStatus,
+        this.searchParam.numberOfPeopleInConferenceRoom,
+        this.searchParam.timeRange[0],
+        this.searchParam.timeRange[1]
+      );
+      setTimeout(() => {
+        this.searchLoading = false;
+      }, 1000);
+    },
+    // 重置事件
+    reset() {
+      this.searchParam = {
+        floor: undefined,
+        timeRange: [this.$moment().format("YYYY-MM-DD 00:00:00"), this.$moment().format("YYYY-MM-DD 23:59:59")],
+        conferenceRoomStatus: undefined,
+        numberOfPeopleInConferenceRoom: undefined
+      };
+      document.getElementById("rangePicker").querySelectorAll("input")[0].value = this.searchParam.timeRange[0];
+      document.getElementById("rangePicker").querySelectorAll("input")[1].value = this.searchParam.timeRange[1];
+    },
+    // 弹窗显示事件
+    showModal(item) {
+      this.showModalStatus = true;
+      this.showModalInfo = item;
+    },
+    // 弹窗隐藏事件
+    onCancel() {
+      this.showModalStatus = false;
+    },
+    init() {
+      // 初始化加载[[楼层\会议室状态\会议室人数]列表、核心指标、碳排放分析、碳配额构成、碳排放占比、双碳新闻]
+      setTimeout(() => {
+        this.options.floor = AnalogData.floor;
+        this.options.conferenceRoomStatus = AnalogData.conferenceRoomStatus;
+        this.options.numberOfPeopleInConferenceRoom = AnalogData.numberOfPeopleInConferenceRoom;
+        this.coreList = AnalogData.core_List;
+        this.chartData = AnalogData.CHART_DATA;
+        this.DoubleCarbonNewsInfoList = AnalogData.doubleCarbonNewsInfoList;
+        this.searchLoading = false;
+      }, 1000);
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+// 复用样式
+.flexColumn {
+  display: flex;
+  flex-direction: column;
+  flex-wrap: nowrap;
+}
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+  align-content: center;
+  align-items: center;
+  &_center {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: center;
+  }
+  &_between {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-between;
+  }
+  &_around {
+    display: flex;
+    flex-wrap: wrap;
+    align-content: center;
+    align-items: center;
+    justify-content: space-around;
+  }
+}
+.floorTitle {
+  width: calc(100% - 20px);
+  font-size: 24px;
+  font-weight: bold;
+  color: @primary-color;
+  .titleLine {
+    width: calc(100% - 40px);
+    border-bottom: 1px dashed @primary-color;
+  }
+}
+.borderColor {
+  border: 1px solid #e7eaf1;
+}
+.margin5rem {
+  margin: 0.5rem;
+}
+.padding5rem {
+  padding: 0.5rem;
+}
+// 页面主题样式
+.doubleCarbon-main-box {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  & * {
+    user-select: none;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    ::-webkit-scrollbar {
+      width: 0 !important;
+    }
+    -ms-overflow-style: none;
+    overflow: -moz-scrollbars-none;
+  }
+  & > div {
+    // padding: 5px 10px;
+    border-radius: 2px;
+    margin-bottom: 10px;
+  }
+  .spinStyle {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background: rgba(255, 255, 255, 0.75);
+    z-index: 2;
+  }
+}
+// 头部搜索框和(重置、查询)按钮之间的间距样式
+.mr1rem {
+  margin-right: 1rem;
+}
+// loading样式
+.spin-content {
+  border: 1px solid #91d5ff;
+  background-color: #e6f7ff;
+  padding: 30px;
+}
+</style>

+ 84 - 0
src/components/security/alarm/manage/securityAlarmManageCategory.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="myChart" ref="myChart" :style="{height: height+'px'}"></div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+    }
+  },
+  props: {
+    height: Number
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      let chart = this.$echarts.init(this.$refs.myChart);
+      let options = {
+        color: ['#80B2FF','#FFDF80'],
+        legend: {
+          data: [
+            '告警次数',
+          ]
+        },
+        grid: {
+          left: '2%', //默认10%
+          right: '2%', //默认10%
+          bottom: '0%', //默认60
+          top: '15%',
+          containLabel: true
+          //grid区域是否包含坐标轴的刻度标签
+        },
+        xAxis: {
+          type: 'category',
+          data: ['火焰告警', '烟雾告警', '水浸异常', '设备故障', '违规闯入', '行为异常']
+        },
+        yAxis: [
+          {
+            //name: '告警次数',
+            type: 'value',
+            nameTextStyle: {
+              padding: [10, 0, 10, 15]
+            },
+          },
+        ],
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          textStyle: {
+            color: '#fff',
+            align: 'left',
+            fontSize: 14
+          },
+          axisLine: {//x坐标轴轴线
+            show: true,
+            lineStyle: {//x坐标轴轴线样式
+              color: '#000',//'#ccc' | 'rgb(128, 128, 128)' | 'rgba(128, 128, 128, 0.5)',设置标签颜色
+            }
+          },
+          backgroundColor: 'rgba(0,0,0,0.8)',
+        },
+        series: [
+          {
+            name: '告警次数',
+            data: [120, 125, 133, 145, 170, 175],
+            type: 'bar',
+            backgroundStyle: {
+              color: 'rgba(180, 180, 180, 0.2)'
+            }
+          },
+        ]
+      };
+      chart.setOption(options);
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+</style>

+ 58 - 0
src/components/security/alarm/manage/securityAlarmManageDistribute.vue

@@ -0,0 +1,58 @@
+<script>
+export default {
+  data() {
+    return {}
+  },
+  props: {
+    height: Number,
+  },
+  mounted() {
+    this.$nextTick(()=>{
+      this.initChart()
+    })
+  },
+  methods: {
+    initChart() {
+      let chart = this.$echarts.init(this.$refs.myChart)
+      let option = {
+        color: ['#80D4FF', '#A6A6FF', '#FFB580', '#FFDF80', '#79F2E8'],
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          bottom: 'bottom',
+          icon: 'circle'
+        },
+        series: [
+          {
+            name: '告警次数',
+            type: 'pie',
+            radius: '50%',
+            data: [
+              { value: 177, name: '一层' },
+              { value: 150, name: 'B1停车场' },
+              { value: 100, name: 'B2停车场' },
+            ],
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      };
+      chart.setOption(option)
+    }
+  }
+}
+</script>
+
+<template>
+  <div style="width: 100%" :style="{height: height+'px'}" ref="myChart"></div>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 37 - 0
src/components/security/alarm/manage/securityAlarmManageDistributeMap.vue

@@ -0,0 +1,37 @@
+<template>
+  <div style="width: 100%;height: 500px">
+    <div style="width: 100%;height: 450px">
+      <ImageMap></ImageMap>
+    </div>
+    <div style="width: 100%;height: 50px">
+      <a-radio-group style="margin: 3px auto 3px 33%;" :options="floorOptions" default-value="1" @change="floorChange" />
+    </div>
+  </div>
+</template>
+
+<script>
+import ImageMap from "@/components/security/alarm/map/imageMap.vue";
+export default {
+  data() {
+    return {
+      floorOptions: [
+        { label: '一层大厅', value: '1' },
+        { label: 'B1停车场', value: 'B1' },
+        { label: 'B2停车场', value: 'B2' },
+      ]
+    }
+  },
+  components: {
+    ImageMap
+  },
+  methods: {
+    floorChange() {
+
+    }
+  }
+}
+</script>
+
+<style lang="less">
+
+</style>

+ 136 - 0
src/components/security/alarm/manage/securityAlarmManageOnlineTrend.vue

@@ -0,0 +1,136 @@
+<script>
+export default {
+  data() {
+    return {
+
+    }
+  },
+  props: {
+    height: Number,
+  },
+  mounted() {
+    this.$nextTick(()=>{
+      this.initChart()
+    })
+  },
+  methods: {
+    initChart() {
+      let chart = this.$echarts.init(this.$refs.myChart)
+      let defaultOption = {
+        legend: {
+          data: [
+            '摄像头',
+            '水浸设备',
+          ]
+        },
+        grid: {
+          left: '0%', //默认10%
+          right: '1%', //默认10%
+          bottom: '15%', //默认60
+          top: '15%',
+          containLabel: true
+          //grid区域是否包含坐标轴的刻度标签
+        },
+        xAxis: {
+          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+        },
+        yAxis: [
+          {
+            type: 'value',
+            min: 0,
+            max: 100,
+            nameTextStyle: {
+              padding: [10, 0, 10, -12]
+            },
+            axisLabel: {
+              show: true,
+              formatter: '{value}%'
+            }
+          },
+        ],
+        dataZoom: [
+          {
+            start: 0,
+            end: 100,
+            height: 16,
+          }
+        ],
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          textStyle: {
+            color: '#fff',
+            align: 'left',
+            fontSize: 14
+          },
+          axisLine: {//x坐标轴轴线
+            show: true,
+            lineStyle: {//x坐标轴轴线样式
+              color: '#000',//'#ccc' | 'rgb(128, 128, 128)' | 'rgba(128, 128, 128, 0.5)',设置标签颜色
+            }
+          },
+          backgroundColor: 'rgba(0,0,0,0.8)',
+        },
+        series: [
+          {
+            name: '摄像头',
+            data: [25,35,45,55, 65, 75, 85, 88, 89, 89, 89, 89],
+            type: 'line',
+            smooth: true,
+            //areaStyle: {
+            //  color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+            //    offset: 0,
+            //    color: '#A6C9FF' // 0% 处的颜色
+            //  }, {
+            //    offset: 0.8,
+            //    color: '#ffffff' // 100% 处的颜色
+            //  }], false),
+            //},
+            lineStyle: {
+              color: "#5A9BFE",
+              width: 1,
+            },
+            emphasis: {
+              scale:1.5
+            }
+          },
+          {
+            name: '水浸设备',
+            data: [20,30,40,50, 60, 70, 80, 82, 85, 87, 88, 89],
+            type: 'line',
+            smooth: true,
+            //areaStyle: {
+            //  color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+            //    offset: 0,
+            //    color: '#B0E5CB' // 0% 处的颜色
+            //  }, {
+            //    offset: 0.8,
+            //    color: '#ffffff' // 100% 处的颜色
+            //  }], false),
+            //},
+            lineStyle: {
+              color: "#62CC97",
+              width: 1,
+            },
+            emphasis: {
+              scale:1.5
+            },
+          }
+        ]
+      };
+      //Object.assign(defaultOption, this.option)
+      chart.setOption(defaultOption)
+    }
+  }
+}
+</script>
+
+<template>
+  <div style="width: 100%" :style="{height: height+'px'}" ref="myChart"></div>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 154 - 0
src/components/security/alarm/manage/securityAlarmManageTrend.vue

@@ -0,0 +1,154 @@
+<script>
+export default {
+  data() {
+    return {
+
+    }
+  },
+  props: {
+    height: Number,
+  },
+  mounted() {
+    this.$nextTick(()=>{
+      this.initChart()
+    })
+  },
+  methods: {
+    initChart() {
+      let chart = this.$echarts.init(this.$refs.myChart)
+      let defaultOption = {
+        legend: {
+          data: [
+            '一般告警',
+            '重要告警',
+            '紧急告警',
+          ]
+        },
+        grid: {
+          left: '0%', //默认10%
+          right: '1%', //默认10%
+          bottom: '15%', //默认60
+          top: '15%',
+          containLabel: true
+          //grid区域是否包含坐标轴的刻度标签
+        },
+        xAxis: {
+          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+        },
+        yAxis: [
+          {
+            name: '次数',
+            type: 'value',
+            nameTextStyle: {
+              padding: [10, 0, 10, -12]
+            },
+          },
+        ],
+        dataZoom: [
+          {
+            start: 0,
+            end: 100,
+            height: 16,
+          }
+        ],
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          textStyle: {
+            color: '#fff',
+            align: 'left',
+            fontSize: 14
+          },
+          axisLine: {//x坐标轴轴线
+            show: true,
+            lineStyle: {//x坐标轴轴线样式
+              color: '#000',//'#ccc' | 'rgb(128, 128, 128)' | 'rgba(128, 128, 128, 0.5)',设置标签颜色
+            }
+          },
+          backgroundColor: 'rgba(0,0,0,0.8)',
+        },
+        series: [
+          {
+            name: '一般告警',
+            data: [302, 395, 227, 375, 349, 396, 304, 226, 207, 383, 287, 243],
+            type: 'line',
+            smooth: true,
+            //areaStyle: {
+            //  color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+            //    offset: 0,
+            //    color: '#A6C9FF' // 0% 处的颜色
+            //  }, {
+            //    offset: 0.8,
+            //    color: '#ffffff' // 100% 处的颜色
+            //  }], false),
+            //},
+            lineStyle: {
+              color: "#5A9BFE",
+              width: 1,
+            },
+            emphasis: {
+              scale:1.5
+            }
+          },
+          {
+            name: '重要告警',
+            data: [108, 104, 117, 152, 157, 121, 138, 146, 106, 143, 132, 177],
+            type: 'line',
+            smooth: true,
+            //areaStyle: {
+            //  color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+            //    offset: 0,
+            //    color: '#B0E5CB' // 0% 处的颜色
+            //  }, {
+            //    offset: 0.8,
+            //    color: '#ffffff' // 100% 处的颜色
+            //  }], false),
+            //},
+            lineStyle: {
+              color: "#62CC97",
+              width: 1,
+            },
+            emphasis: {
+              scale:1.5
+            },
+          },
+          {
+            name: '紧急告警',
+            data: [40, 15, 59, 18, 33, 31, 31, 26, 34, 26, 28, 40],
+            type: 'line',
+            smooth: true,
+            //areaStyle: {
+            //  color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+            //    offset: 0,
+            //    color: '#FFD7AC' // 0% 处的颜色
+            //  }, {
+            //    offset: 0.8,
+            //    color: '#ffffff' // 100% 处的颜色
+            //  }], false),
+            //},
+            lineStyle: {
+              color: "#FDB456",
+              width: 1,
+            },
+            emphasis: {
+              scale:1.5
+            },
+          }
+        ]
+      };
+      //Object.assign(defaultOption, this.option)
+      chart.setOption(defaultOption)
+    }
+  }
+}
+</script>
+
+<template>
+  <div style="width: 100%" :style="{height: height+'px'}" ref="myChart"></div>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 22 - 2
src/components/security/alarm/securityAlarmGrid.vue

@@ -1,9 +1,29 @@
 <template>
-
+  <div class="securityAlarmGrid">
+    <Card title="宫格模式">
+      <a-row>
+        <a-col :span="4">
+          <div style="padding-left: 15px">
+            <SecurityDeviceSelect></SecurityDeviceSelect>
+          </div>
+        </a-col>
+        <a-col :span="20">
+          <div></div>
+        </a-col>
+      </a-row>
+    </Card>
+  </div>
 </template>
 
 <script>
-export default {}
+import Card from "@/components/common/card.vue";
+import SecurityDeviceSelect from "@/components/security/common/securityDeviceSelect.vue";
+
+export default {
+  components: {
+    SecurityDeviceSelect
+  }
+}
 </script>
 
 <style lang="less" scoped>

+ 182 - 2
src/components/security/alarm/securityAlarmInfo.vue

@@ -1,11 +1,191 @@
 <template>
+  <div class="securityAlarmInfo">
+    <a-row style="height: 100%">
+      <a-col :span="6" style="height: 100%">
+        <security-device-select/>
+      </a-col>
+      <a-col :span="18" style="height: 100%;padding: 15px">
+        <div class="securityAlarmInfo-query">
+          <a-form-model layout="inline" :model="formData">
+            <a-form-model-item label="告警类型">
+              <a-select defaultValue="all" style="width: 150px">
+                <a-select-option value="all">全部</a-select-option>
+                <a-select-option value="fumes">烟雾告警</a-select-option>
+                <a-select-option value="fire">火焰告警</a-select-option>
+                <a-select-option value="trespass">非法闯入</a-select-option>
+                <a-select-option value="violation">违规行为</a-select-option>
+              </a-select>
+            </a-form-model-item>
+            <a-form-model-item label="时间范围">
+              <TimeRange></TimeRange>
+            </a-form-model-item>
+            <a-form-model-item label="处理情况">
+              <a-select defaultValue="all" style="width: 120px">
+                <a-select-option value="all">全部</a-select-option>
+                <a-select-option value="finish">已处理</a-select-option>
+                <a-select-option value="todo">待处理</a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-form-model>
+        </div>
+        <div class="securityAlarmInfo-list">
+          <a-table :rowKey="(record, index) => index"
+                   :columns="columns"
+                   :data-source="tableData"
+          >
 
+            <template #level="text">
+              <span v-if="text==0" style="color: #ffbf6b">一般告警</span>
+              <span v-if="text==1" style="color: #d26e64">重要告警</span>
+              <span v-if="text==2" style="color: #b83023">紧急告警</span>
+            </template>
+
+            <template #type="text">
+              <span v-if="text==0" style="color: #ffbf6b">火焰告警</span>
+              <span v-if="text==1" style="color: #d26e64">水浸告警</span>
+              <span v-if="text==2" style="color: #b83023">摄像头告警</span>
+            </template>
+
+            <template #operation="text">
+              <a-button type="link">确认处理</a-button>
+              <a-button type="link" @click="viewDetail">查看详情</a-button>
+            </template>
+          </a-table>
+        </div>
+      </a-col>
+    </a-row>
+
+    <!--告警详情-->
+    <a-modal class="securityPersonMoreDetail" v-if="showDetail"
+             :visible="true"
+             :width="800"
+             :footer="null"
+             @cancel="handleCancel"
+    >
+      <div>告警详情</div>
+      <a-divider />
+
+      <div style="width: 100%;height: 100%">
+        <div style="height: 250px;width: 100%">
+          <img width="100%" height="100%" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
+        </div>
+        <div style="margin-top: 20px">
+          <a-descriptions :column="3" size="small">
+            <a-descriptions-item label="监控点">
+              一层大厅西南角1号球机
+            </a-descriptions-item>
+            <a-descriptions-item label="告警区域">
+              一层大厅西南角
+            </a-descriptions-item>
+            <a-descriptions-item label="告警类型">
+              烟雾告警
+            </a-descriptions-item>
+            <a-descriptions-item label="告警时间">
+              2022-08-01 12:00:00
+            </a-descriptions-item>
+            <a-descriptions-item label="告警级别">
+              紧急告警
+            </a-descriptions-item>
+            <a-descriptions-item label="准确率">
+              98%
+            </a-descriptions-item>
+          </a-descriptions>
+        </div>
+      </div>
+    </a-modal>
+
+  </div>
 </template>
 
 <script>
-export default {}
+import SecurityDeviceSelect from "@/components/security/common/securityDeviceSelect.vue";
+import TimeRange from "@/components/common/timeRange.vue";
+
+export default {
+  data() {
+    return {
+      showDetail: false,
+      formData: {},
+      tableData: [
+        {
+          time: '2022-08-01 12:00:00',
+          area: '一层大厅',
+          level: 0,
+          source: '一层大厅东南角1号球机',
+          type: 0,
+        },
+        {
+          time: '2022-08-01 12:00:00',
+          area: '一层大厅',
+          level: 1,
+          source: '一层大厅东南角1号球机',
+          type: 1,
+        },
+        {
+          time: '2022-08-01 12:00:00',
+          area: '一层大厅',
+          level: 2,
+          source: '一层大厅东南角1号球机',
+          type: 2,
+        },
+      ],
+      columns: [
+        {
+          title: '告警时间',
+          dataIndex: 'time',
+          key: 'time'
+        },
+        {
+          title: '告警区域',
+          dataIndex: 'area',
+          key: 'area'
+        },
+        {
+          title: '告警级别',
+          dataIndex: 'level',
+          key: 'level',
+          scopedSlots: { customRender: 'level' },
+        },
+        {
+          title: '告警来源',
+          dataIndex: 'source',
+          key: 'source'
+        },
+        {
+          title: '告警类型',
+          dataIndex: 'type',
+          key: 'type',
+          scopedSlots: { customRender: 'type' },
+        },
+        {
+          title: '操作',
+          dataIndex: 'operation',
+          key: 'operation',
+          minWidth: 220,
+          align: 'center',
+          scopedSlots: { customRender: 'operation' },
+        }
+      ]
+    }
+  },
+  components: {
+    SecurityDeviceSelect,
+    TimeRange,
+  },
+  methods: {
+    viewDetail() {
+      this.showDetail = true;
+    },
+    handleCancel() {
+      this.showDetail = false
+    }
+  }
+}
 </script>
 
 <style lang="less" scoped>
-
+.securityAlarmInfo {
+  width: 100%;
+  height: 100%;
+}
 </style>

+ 119 - 2
src/components/security/alarm/securityAlarmManage.vue

@@ -1,11 +1,128 @@
 <template>
+  <div class="securityAlarmManage">
+    <div class="securityAlarmManage-query">
+      <Query></Query>
+    </div>
+    <div class="securityAlarmManage-core">
+      <Card title="核心指标">
+        <CoreData :data-list="coreData"></CoreData>
+      </Card>
+    </div>
+    <a-row>
+      <a-col :span="14">
+        <div class="securityAlarmManage-distributeMap">
+          <Card title="告警分布">
+            <SecurityAlarmManageDistributeMap></SecurityAlarmManageDistributeMap>
+          </Card>
+        </div>
+      </a-col>
+      <a-col :span="10">
+        <div class="securityAlarmManage-trend">
+          <Card title="告警趋势">
+            <SecurityAlarmManageTrend :height="450"></SecurityAlarmManageTrend>
+          </Card>
+        </div>
+      </a-col>
+    </a-row>
 
+    <a-row>
+      <a-col :span="8">
+        <div class="securityAlarmManage-distribute">
+          <Card title="楼层告警分布">
+            <SecurityAlarmManageDistribute :height="300"></SecurityAlarmManageDistribute>
+          </Card>
+        </div>
+      </a-col>
+      <a-col :span="8">
+        <div class="securityAlarmManage-onlineTrend">
+          <Card title="设备在线趋势">
+            <SecurityAlarmManageOnlineTrend :height="300"></SecurityAlarmManageOnlineTrend>
+          </Card>
+        </div>
+      </a-col>
+      <a-col :span="8">
+        <div class="securityAlarmManage-category">
+          <Card title="告警分类">
+            <SecurityAlarmManageCategory :height="300"></SecurityAlarmManageCategory>
+          </Card>
+        </div>
+      </a-col>
+    </a-row>
+  </div>
 </template>
 
 <script>
-export default {}
+import Query from "@/components/common/query.vue";
+import Card from "@/components/common/card.vue";
+import CoreData from "@/components/common/coreData.vue";
+
+import SecurityAlarmManageDistributeMap from "@/components/security/alarm/manage/securityAlarmManageDistributeMap.vue";
+import SecurityAlarmManageTrend from "@/components/security/alarm/manage/securityAlarmManageTrend.vue";
+import SecurityAlarmManageDistribute from "@/components/security/alarm/manage/securityAlarmManageDistribute.vue";
+import SecurityAlarmManageOnlineTrend from "@/components/security/alarm/manage/securityAlarmManageOnlineTrend.vue";
+import SecurityAlarmManageCategory from "@/components/security/alarm/manage/securityAlarmManageCategory.vue";
+
+export default {
+  data() {
+    return {
+      coreData: [
+        {
+          title: '告警事件',
+          num: 1000,
+          historyDesc: '同比',
+          historyNum: 0.4
+        },{
+          title: '紧急告警事件',
+          num: 500,
+          historyDesc: '同比',
+          historyNum: 0.4
+        },{
+          title: '已处理事件',
+          num: 200,
+          historyDesc: '同比',
+          hideTrend: true,
+          historyNum: 60
+        },{
+          title: '告警最多类型',
+          num: '设备离线',
+          historyDesc: '同比',
+          historyNum: 0.4
+        },{
+          type: 1,
+          title: '值得关注',
+        }
+      ]
+    }
+  },
+  components: {
+    Card,
+    Query,
+    CoreData,
+    SecurityAlarmManageDistributeMap,
+    SecurityAlarmManageTrend,
+    SecurityAlarmManageDistribute,
+    SecurityAlarmManageOnlineTrend,
+    SecurityAlarmManageCategory,
+  },
+  mounted() {
+  },
+  methods: {
+
+  }
+}
 </script>
 
 <style lang="less" scoped>
-
+.securityAlarmManage {
+  .securityAlarmManage-distributeMap {
+    width: 100%;
+    padding: 0 15px 15px;
+  }
+  .securityAlarmManage-trend {
+    width: 95%;
+  }
+  .securityAlarmManage-distribute {
+    padding-bottom: 5%;
+  }
+}
 </style>

+ 133 - 0
src/components/security/common/securityDeviceSelect.vue

@@ -0,0 +1,133 @@
+<template>
+  <div class="securityDeviceSelect" style="width: 100%;height: 100%">
+    <div class="securityDeviceSelect-title">监控点位</div>
+    <div>
+      <a-input-search style="margin-bottom: 8px" placeholder="Search" @change="onChange"/>
+      <a-tree
+          :expanded-keys="expandedKeys"
+          :auto-expand-parent="true"
+          :tree-data="treeData"
+          :show-icon="true"
+          @expand="onExpand"
+      >
+        <template #camera>
+          <span class="anticon"><i-icon-park-outline-camera-two /></span>
+        </template>
+        <template #water>
+          <span class="anticon"><i-icon-park-outline-control /></span>
+        </template>
+
+        <template #title="{ title }">
+                  <span v-if="title.indexOf(searchValue) > -1">
+                    {{ title.substr(0, title.indexOf(searchValue)) }}
+                    <span style="color: #f50">{{ searchValue }}</span>
+                    {{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
+                  </span>
+          <span v-else>{{ title }}</span>
+        </template>
+      </a-tree>
+    </div>
+  </div>
+</template>
+
+<script>
+import Card from "@/components/common/card.vue";
+
+export default {
+  data() {
+    return {
+      expandedKeys: [],
+      oriData: [],
+      treeData: [
+        {
+          title: '一层大厅',
+          key: '1',
+          selectable: false,
+          children: [
+            {
+              title: '大厅正门',
+              key: '1-0',
+              slots: {
+                icon: 'camera',
+              },
+            },
+            {
+              title: '水浸设备1',
+              key: '0-0-1',
+              slots: {
+                icon: 'water',
+              },
+            },
+          ],
+        },
+      ],
+      searchValue: '',
+    }
+  },
+  components: {
+    Card
+  },
+  created() {
+    this.generateList(this.treeData)
+  },
+  methods: {
+    onExpand(expandedKeys) {
+      this.expandedKeys = expandedKeys;
+      this.autoExpandParent = false;
+    },
+    generateList(data) {
+      for (let i = 0; i < data.length; i++) {
+        const node = data[i];
+        const key = node.key;
+        this.oriData.push({ key, title: key });
+        if (node.children) {
+          this.generateList(node.children);
+        }
+      }
+    },
+    getParentKey(key, tree) {
+      let parentKey;
+      for (let i = 0; i < tree.length; i++) {
+        const node = tree[i];
+        if (node.children) {
+          if (node.children.some(item => item.key === key)) {
+            parentKey = node.key;
+          } else if (this.getParentKey(key, node.children)) {
+            parentKey = this.getParentKey(key, node.children);
+          }
+        }
+      }
+      return parentKey;
+    },
+    onChange(e) {
+      const value = e.target.value;
+      const expandedKeys = this.oriData
+          .map(item => {
+            if (item.title.indexOf(value) > -1) {
+              return this.getParentKey(item.key, this.treeData);
+            }
+            return null;
+          })
+          .filter((item, i, self) => item && self.indexOf(item) === i);
+      Object.assign(this, {
+        expandedKeys,
+        searchValue: value,
+        autoExpandParent: true,
+      });
+    },
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.securityDeviceSelect {
+  width: 100%;
+  height: 100%;
+  border: 1px solid #d9d9d9;
+  padding: 15px;
+  border-radius: 6px;
+  .securityDeviceSelect-title {
+
+  }
+}
+</style>

+ 40 - 2
src/components/security/device/securityDevice.vue

@@ -1,11 +1,49 @@
 <template>
+  <div class="securityDevice">
+    <a-row style="height: 100%">
+      <a-col :span="6" style="height: 100%">
+        <SecurityDeviceSelect />
+      </a-col>
+      <a-col :span="18" style="height: 100%">
+        <div class="securityDevice-content">
+          <Card title="可交互设备">
+            <a-divider style="padding: 0;margin: 0;"/>
 
+            <div class="securityDevice-devices">
+              <SecurityDeviceItem />
+              <SecurityDeviceItem />
+              <SecurityDeviceItem />
+              <SecurityDeviceItem />
+            </div>
+          </Card>
+        </div>
+      </a-col>
+    </a-row>
+  </div>
 </template>
 
 <script>
-export default {}
+import Card from "@/components/common/card.vue";
+import SecurityDeviceSelect from "@/components/security/common/securityDeviceSelect.vue";
+import SecurityDeviceItem from "@/components/security/device/securityDeviceItem.vue";
+export default {
+  components: {
+    Card,
+    SecurityDeviceSelect,
+    SecurityDeviceItem,
+  }
+}
 </script>
 
 <style lang="less" scoped>
-
+.securityDevice {
+  width: 100%;
+  height: 100%;
+  .securityDevice-content {
+    height: 100%;
+    border: 1px solid #d9d9d9;
+    margin: 0 15px;
+    border-radius: 5px;
+  }
+}
 </style>

+ 26 - 0
src/components/security/device/securityDeviceItem.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="securityDeviceItem">
+    <div class="securityDeviceItem-line">设备名称:门禁设备1#</div>
+    <div class="securityDeviceItem-line">设备状态:在线</div>
+    <div class="securityDeviceItem-line">功能交互:</div>
+  </div>
+</template>
+
+<script>
+export default {}
+</script>
+
+<style lang="less" scoped>
+.securityDeviceItem {
+  display: inline-block;
+  margin: 15px 20px;
+  width: 300px;
+  height: 150px;
+  border: 1px solid #eeeeee;
+  box-shadow: 5px 0px 5px 0px #4D4D4D;
+  .securityDeviceItem-line {
+    line-height: 25px;
+    margin: 10px;
+  }
+}
+</style>

+ 33 - 38
src/data/json/menuList.json

@@ -2,110 +2,105 @@
   {
     "name": "智能看板",
     "router": "/dashboard",
-    "icon": "aside/dashboard.png",
-    "children": [
-      {
-        "name": "人员画像",
-        "router": "",
-        "icon": ""
-      },
-      {
-        "name": "能源画像",
-        "router": "",
-        "icon": ""
-      },
-      {
-        "name": "资产画像",
-        "router": "",
-        "icon": ""
-      }
-    ]
+    "icon": "function/dashboard.png"
   },
   {
     "name": "智享生活",
     "router": "/life",
-    "icon": "aside/life.png",
+    "icon": "function/life.png",
     "children": [
       {
         "name": "智慧餐厅",
         "router": "/life/restaurant",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "智慧停车",
         "router": "/life/parking",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "无人商超",
         "router": "/life/supermarket",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "健康小屋",
         "router": "/life/healthyHome",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       }
     ]
   },
   {
     "name": "智慧办公",
     "router": "/work",
-    "icon": "aside/work.png",
+    "icon": "function/work.png",
     "children": [
       {
         "name": "楼层概览",
         "router": "/work/overview",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "会议管理",
         "router": "/work/meeting",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "文印管理",
         "router": "/work/print",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "公车管理",
         "router": "/work/bus",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       }
     ]
   },
   {
     "name": "数智双碳",
     "router": "/doubleCarbon",
-    "icon": "aside/carbon.png",
+    "icon": "function/carbon.png",
     "children": [
       {
         "name": "双碳概览",
         "router": "/doubleCarbon/overview",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "车辆排放",
         "router": "/doubleCarbon/car",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "文印排放",
         "router": "/doubleCarbon/print",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       },
       {
         "name": "光伏发电",
         "router": "/doubleCarbon/pv",
-        "icon": ""
+        "icon": "",
+        "iconColor": "functionColor/life/iocRestaurant.png"
       }
     ]
   },
   {
     "name": "智慧运营",
     "router": "/business",
-    "icon": "aside/operation.png",
+    "icon": "function/operation.png",
     "children": [
       {
         "name": "资产管理",
@@ -127,7 +122,7 @@
   {
     "name": "智慧安防",
     "router": "/security",
-    "icon": "aside/security.png",
+    "icon": "function/security.png",
     "children": [
       {
         "name": "安防人员",
@@ -171,7 +166,7 @@
   {
     "name": "智慧场景",
     "router": "/scene",
-    "icon": "aside/scene.png",
+    "icon": "function/scene.png",
     "children": [
       {
         "name": "智•会议",
@@ -239,7 +234,7 @@
   {
     "name": "数据报表",
     "router": "/report",
-    "icon": "aside/report.png",
+    "icon": "function/report.png",
     "children": [
       {
         "name": "报表",
@@ -256,7 +251,7 @@
   {
     "name": "权限下达",
     "router": "/auth",
-    "icon": "aside/auth.png",
+    "icon": "function/auth.png",
     "children": [
       {
         "name": "角色权限",

+ 26 - 13
src/data/json/ssoList.json

@@ -2,66 +2,79 @@
   {
     "name": "能源系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "文印管理系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "资产管理系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "空间管理系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "视频云平台",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "停车管理系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "会议系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "门禁口出入系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "餐厅系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "碳数据管理平台",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "智慧健康系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "车辆管理系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   },
   {
     "name": "无人商超系统",
     "icon": "",
-    "url": ""
+    "url": "",
+    "isSso": true
   }
 ]

+ 3 - 0
src/main.js

@@ -17,6 +17,9 @@ import constant from '@/utils/constant.js'
 // 时间插件
 import moment from '@/utils/moment_set.js'
 
+import Stores from "@/stores";
+Vue.prototype.$store = Stores;
+
 Vue.prototype.$util = util
 Vue.prototype.$constant = constant
 Vue.prototype.$echarts = echarts

+ 5 - 5
src/router/index.js

@@ -2,7 +2,7 @@ import Vue from 'vue'
 import VueRouter from 'vue-router'
 import HomeView from '../views/HomeView.vue'
 import LoginView from '@/views/LoginView.vue'
-import NavigationPage from '@/components/home/NavigationPage.vue'
+import Notice from '@/components/notice/notice.vue'
 import Empty from '@/components/Empty.vue'
 import Dashboard from "@/components/dashboard/Dashboard.vue";
 
@@ -25,10 +25,10 @@ const router = new VueRouter({
           component: Empty,
         },
         {
-          path: '/nav',
-          name: 'nav',
-          meta: {breadcrumb: '导航页'},
-          component: NavigationPage,
+          path: '/notice',
+          name: 'notice',
+          meta: {breadcrumb: '消息通知'},
+          component: Notice,
         },
         {
           path: '/dashboard',

+ 75 - 12
src/stores/index.js

@@ -1,15 +1,78 @@
-import { defineStore } from 'pinia'
+import {defineStore} from 'pinia'
 
-export const useUserStore = defineStore('user', {
-  state: () => ({
-    userInfo: {},
-    token: '',
-  }),
-  getters: {
-    userToken: state => state.token,
-    userInfo: state => state.userInfo,
-  },
-  actions: {
+const menuStore = defineStore('ioc-menu', {
+    state: () => (
+        {
+            currMenu: {},
+            commonFunction: [
+                {
+                    "name": "智慧餐厅",
+                    "router": "/life/restaurant",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "智慧停车",
+                    "router": "/life/parking",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "无人商超",
+                    "router": "/life/supermarket",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "健康小屋",
+                    "router": "/life/healthyHome",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "双碳概览",
+                    "router": "/doubleCarbon/overview",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "车辆排放",
+                    "router": "/doubleCarbon/car",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "文印排放",
+                    "router": "/doubleCarbon/print",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                },
+                {
+                    "name": "光伏发电",
+                    "router": "/doubleCarbon/pv",
+                    "icon": "",
+                    "iconColor": "functionColor/life/iocRestaurant.png"
+                }
+            ],
+        }
+    ),
+    getters: {},
+    actions: {},
+})
 
-  },
+const userStore = defineStore('ioc-user', {
+    state: () => ({
+        userInfo: {},
+        token: '',
+    }),
+    getters: {
+        userToken: state => state.token,
+        userInfo: state => state.userInfo,
+    },
+    actions: {},
 })
+
+export default {
+    menuStore,
+    userStore,
+}

+ 33 - 1
src/style/common.css

@@ -1,3 +1,7 @@
+* {
+  font-family: PingFangSC-Regular, serif;
+}
+
 .pageContainer-body {
   width: calc(100% - 175px);
   height: 100%;
@@ -21,7 +25,14 @@
   font-family: numberMH;
   src: url(../assets/fonts/Digiface-Regular.ttf);
 }
-
+@font-face {
+  font-family: PingFangSC-Regular;
+  src: url(../assets/fonts/PingFangSC-Regular.ttf);
+}
+@font-face {
+  font-family: PingFangSC-Bold;
+  src: url(../assets/fonts/PingFangSC-Bold.ttf);
+}
 /*滚动条样式*/
 ::-webkit-scrollbar {
   width: 8px;
@@ -44,4 +55,25 @@
   -moz-box-shadow: 0 0 4px #0000004d;
   box-shadow: 0 0 4px #0000004d;
   padding: 10px 20px;
+}
+
+/* fade-transform */
+.fade-transform--move,
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all .5s;
+}
+
+.fade-transform-leave-active {
+  position: absolute;
+}
+
+.fade-transform-enter {
+  opacity: 0;
+  transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+  opacity: 0;
+  transform: translateX(30px);
 }

+ 38 - 24
src/views/HomeView.vue

@@ -3,22 +3,34 @@
   <div class="home">
     <a-layout id="components-layout-demo-top-side-2">
       <a-layout-header class="header">
-        <HomeHeader :collapse.sync="collapse" :is-login="true" />
+        <HomeHeader :leftVisible.sync="leftVisible" :is-login="true" />
       </a-layout-header>
       <a-layout class="main_body">
+        <a-drawer v-if="leftVisible"
+            placement="left"
+            :visible="leftVisible"
+            :get-container="false"
+            :closable="false"
+            @close="closeLeft"
+            width="auto"
+            :wrap-style="{ position: 'absolute' }">
+          <HomeLeft :close="()=>{leftVisible=false}" />
+        </a-drawer>
         <a-layout-sider
           v-model="collapse"
           :trigger="null"
           :width="asideWidth"
           style="background: #fff"
           :collapsible="true"
-          :collapsed-width="60"
+          :collapsed-width="collapsedWidth"
         >
           <HomeAside :collapse.sync="collapse" />
         </a-layout-sider>
         <!-- 内容 -->
         <a-layout-content class="home-page">
-          <router-view />
+          <Transition name="fade-transform" mode="out-in">
+            <router-view :key="$route.matched[1].name" />
+          </transition>
         </a-layout-content>
       </a-layout>
     </a-layout>
@@ -27,54 +39,50 @@
 
 <script>
 import "@/style/common.css";
+import HomeHeader from "@/components/home/HomeHeader.vue";
+import HomeAside from "@/components/home/HomeAside.vue";
+import HomeLeft from "@/components/home/HomeLeft.vue";
 
 export default {
   name: "HomeView",
   components: {
-    HomeHeader: () => import("@/components/home/HomeHeader.vue"),
-    HomeAside: () => import("@/components/home/HomeAside.vue"),
+    HomeHeader,
+    HomeAside,
+    HomeLeft,
   },
   data() {
     return {
       collapse: true, // 侧边栏是否收起
+      leftVisible: false,
       asideWidth: 160,
+      collapsedWidth: 60,
       contentWidth: "84%",
       contentHeight: 450,
     };
   },
   watch: {
-    fold(val) {
-      let app = this;
-      setTimeout(() => {
-        app.suitHeight();
-      }, 100);
-    },
     $route() {
-      //this.judgeHideAside();
-    },
+      this.judgeHideAside();
+    }
   },
   mounted() {
-    this.suitHeight();
-    //this.judgeHideAside();
+    this.judgeHideAside();
     if (this.$route.matched.length===1) {
       this.$router.push({path: '/dashboard'})
     }
   },
   methods: {
+    closeLeft() {
+      this.leftVisible = false
+    },
     judgeHideAside() {
       let name = this.$route.name
-      if (['dashboard'].indexOf(name)>-1) {
+      //if (['dashboard','notice'].indexOf(name)>-1) {
+      if (['notice'].indexOf(name)>-1) {
         this.asideWidth = 0;
+        this.collapsedWidth=0;
       }
     },
-    suitHeight() {
-      let app = this;
-      this.$nextTick(() => {
-        const height = document.getElementsByClassName("home")[0].clientHeight;
-        app.contentHeight = height - 60 - 24;
-        app.$forceUpdate();
-      });
-    },
   },
 };
 </script>
@@ -84,6 +92,11 @@ export default {
   width: 100%;
   height: 100%;
 
+  /deep/ .ant-drawer-body {
+    padding: 0;
+    height: 100%;
+  }
+
   .header {
     height: 60px;
     padding: 0;
@@ -91,6 +104,7 @@ export default {
   }
   .main_body{
     height:calc(100vh - 60px);
+    position: relative;
   }
 
   .home-page {