Selaa lähdekoodia

图标步长优化,安防人员

tianyabing 2 vuotta sitten
vanhempi
commit
3cd3ed5039
28 muutettua tiedostoa jossa 471 lisäystä ja 338 poistoa
  1. 16 0
      src/api/scene/apiSceneStrategy.js
  2. 10 0
      src/api/scene/meeting/apiSceneMeeting.js
  3. 14 0
      src/api/security/apiSecurityCamera.js
  4. 5 1
      src/api/security/apiSecurityPerson.js
  5. 2 10
      src/components/business/analysis/all/businessEnergyChart.vue
  6. 0 1
      src/components/business/analysis/cold/BusinessColdChart.vue
  7. 0 1
      src/components/business/analysis/hot/BusinessHotChart.vue
  8. 0 1
      src/components/business/analysis/pv/BusinessPvChart.vue
  9. 1 10
      src/components/business/analysis/pv/BusinessPvMoneyChart.vue
  10. 0 2
      src/components/dashboard/portrait/cold/coldTrendChart.vue
  11. 0 4
      src/components/dashboard/portrait/hot/hotTrendChart.vue
  12. 13 1
      src/components/dashboard/portrait/person/personTrendChart.vue
  13. 1 6
      src/components/dashboard/portrait/restaurant/restaurantTrendChart.vue
  14. 1 1
      src/components/dashboard/portrait/supermarket/supermarketTrendChart.vue
  15. 18 2
      src/components/scene/meeting/config/meetingRoomConfig.vue
  16. 7 0
      src/components/scene/meeting/config/meetingRooms.vue
  17. 42 3
      src/components/scene/meeting/config/meetingStrategy.vue
  18. 29 141
      src/components/security/alarm/securityAlarmGrid.vue
  19. 12 10
      src/components/security/alarm/securityAlarmMap.vue
  20. 52 15
      src/components/security/camera/hkwsCamera.vue
  21. 20 11
      src/components/security/common/securityDeviceSelect.vue
  22. 47 61
      src/components/security/person/components/securityPersonDuty.vue
  23. 72 39
      src/components/security/person/securityPersonMore.vue
  24. 13 1
      src/components/work/bus/component/workBusChart.vue
  25. 13 1
      src/components/work/meeting/component/workMeetingCostTrend.vue
  26. 17 14
      src/utils/constant.js
  27. 65 1
      src/utils/dataUtil.js
  28. 1 1
      vite.config.js

+ 16 - 0
src/api/scene/apiSceneStrategy.js

@@ -0,0 +1,16 @@
+import Request from "@/utils/request";
+
+// 创建策略
+const addStrategy = (params) => {
+    return Request.post('/strategy/add', params)
+}
+
+// 获取策略列表
+const getStrategyList = (params) => {
+    return Request.post('strategy/getStrategyList', params)
+}
+
+export default {
+    addStrategy,
+    getStrategyList
+}

+ 10 - 0
src/api/scene/meeting/apiSceneMeeting.js

@@ -0,0 +1,10 @@
+import Request from "@/utils/request";
+
+// 获取会议室列表
+const getMeetingRoomList = (params) => {
+    return Request.post('/meetingroom/getMeetingRoomList', params)
+}
+
+export default {
+    getMeetingRoomList
+}

+ 14 - 0
src/api/security/apiSecurityCamera.js

@@ -0,0 +1,14 @@
+import Request from "@/utils/request";
+
+const getHkApi = (param) => {
+    return Request.post('/security_camera/apiInfo', param)
+}
+
+const getCameraList = (param) => {
+    return Request.post('/security_camera/getCameras', param)
+}
+
+export default {
+    getHkApi,
+    getCameraList
+}

+ 5 - 1
src/api/security/apiSecurityPerson.js

@@ -13,9 +13,13 @@ const getPassengerFlow = (timeRange) => {
     return Request.post('/security_person/getPassengerFlow', timeRange)
 }
 
+const getPersonDuty = (timeRange) => {
+    return Request.post('/security_person/getDuty', timeRange)
+}
+
 export default {
     getCoreData,
     getPopulationPerson,
     getPassengerFlow,
-
+    getPersonDuty,
 }

+ 2 - 10
src/components/business/analysis/all/businessEnergyChart.vue

@@ -28,19 +28,11 @@ export default {
         },
         yAxis: [
           {
-            name: 'kwh',
             type: 'value',
             nameTextStyle: {
               padding: [10, 0, 10, -30]
             },
-          },
-          {
-            name: 'm³',
-            type: 'value',
-            nameTextStyle: {
-              padding: [10, 0, 10, 30]
-            },
-          },
+          }
         ],
         dataZoom: [
           {
@@ -98,7 +90,7 @@ export default {
             data: [],
             type: 'line',
             stack: 'a',
-            yAxisIndex:1,
+            yAxisIndex:0,
             smooth: true,
             showSymbol:false,
             itemStyle: {

+ 0 - 1
src/components/business/analysis/cold/BusinessColdChart.vue

@@ -69,7 +69,6 @@ export default {
             name: '制冷量',
             data: [],
             type: 'bar',
-            stack: 'A',
             barWidth: '30%',
             itemStyle: {
               color: '#3AA7E6'

+ 0 - 1
src/components/business/analysis/hot/BusinessHotChart.vue

@@ -61,7 +61,6 @@ export default {
             name: '用热量',
             data: [],
             type: 'bar',
-            stack: 'A',
             barWidth: '30%',
             itemStyle: {
               color: '#3AA7E6'

+ 0 - 1
src/components/business/analysis/pv/BusinessPvChart.vue

@@ -69,7 +69,6 @@ export default {
             name: '发电量',
             data: [],
             type: 'bar',
-            stack: 'A',
             barWidth: '30%',
             itemStyle: {
               color: '#3AA7E6'

+ 1 - 10
src/components/business/analysis/pv/BusinessPvMoneyChart.vue

@@ -25,17 +25,9 @@ export default {
         },
         yAxis: [
           {
-            name: 'kwh',
             type: 'value',
             nameTextStyle: {
-              padding: [0, 0, 10, -30]
-            },
-          },
-          {
-            name: 'm³',
-            type: 'value',
-            nameTextStyle: {
-              padding: [10, 0, 10, 30]
+              padding: [20, 0, 10, 0]
             },
           },
         ],
@@ -95,7 +87,6 @@ export default {
             data: [],
             type: 'line',
             stack: 'a',
-            yAxisIndex:1,
             smooth: true,
             showSymbol:false,
             itemStyle: {

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

@@ -78,7 +78,6 @@ export default {
             name: '用冷量',
             data: [],
             type: 'line',
-            stack: 'a',
             yAxisIndex:0,
             smooth: true,
             showSymbol:false,
@@ -97,7 +96,6 @@ export default {
             name: '温度',
             data: [],
             type: 'line',
-            stack: 'b',
             smooth: true,
             showSymbol:false,
             yAxisIndex:1,

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

@@ -26,8 +26,6 @@ export default {
           {
             name: '热量(kWh)',
             type: 'value',
-            max: 12,
-            interval: 3,
             nameTextStyle: {
               padding: [10, 0, 10, 15]
             },
@@ -35,8 +33,6 @@ export default {
           {
             name: '温度(℃)',
             type: 'value',
-            max: 40,
-            interval: 10,
             nameTextStyle: {
               padding: [10, 0, 10, -12]
             },

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

@@ -39,7 +39,19 @@ export default {
                         },
                     },
                 ],
-                dataZoom: this.$constant.ECHARTS_DATAZOOM,
+                dataZoom: [
+                  {
+                    type: 'slider',
+                    start: 0,
+                    end: 100,
+                    height: 12,
+                  },
+                  {
+                    type: 'inside',
+                    start: 0,
+                    end: 100,
+                  }
+                ],
                 tooltip: {
                     trigger: 'axis',
                     axisPointer: {

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

@@ -25,12 +25,7 @@ export default {
         },
         xAxis: {
           data: [],
-          splitArea: {
-            show: true,
-            areaStyle: {
-              color: ['white']
-            }
-          }
+
         },
         yAxis: [
           {

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

@@ -30,7 +30,7 @@ export default {
         xAxis: {
           data: [],
           splitArea: {
-            show: true,
+            show: false,
             areaStyle: {
               color: ['white']
             }

+ 18 - 2
src/components/scene/meeting/config/meetingRoomConfig.vue

@@ -145,6 +145,7 @@
 <script>
 import MeetingRoomDeviceTable from "@/components/scene/meeting/config/meetingRoomDeviceTable.vue";
 import Card from "@/components/common/card.vue";
+import apiSceneMeeting from "@/api/scene/apiSceneStrategy";
 export default {
   components: {
     Card,
@@ -245,13 +246,28 @@ export default {
     finish() {
       this.finishLoading = true;
       let app = this;
-      setTimeout(function () {
+      let config = {
+        basicInfo: this.basicInfo,
+        deviceInfo: this.deviceTableData,
+      }
+      let params= {
+        "configParams": JSON.stringify(config),
+        "createTime": this.$util.dateUtil.getCurrDateTime(),
+        "creator": this.$store.userStore().userInfo.name,
+        "isDel": 0,
+        "name": this.basicInfo.name,
+        "status": 1,
+        "type": 1
+      }
+      apiSceneMeeting.addStrategy(params).then(res=>{
         app.finishLoading = false;
         app.$notification.success({
           message: '配置策略成功',
         });
         app.close()
-      }, 2000)
+      }).catch(err=>{
+        app.finishLoading = false;
+      })
     }
   }
 }

+ 7 - 0
src/components/scene/meeting/config/meetingRooms.vue

@@ -43,6 +43,7 @@
 <script>
 import MeetingRoomItem from "@/components/scene/meeting/config/meetingRoomItem.vue";
 import Query from "@/components/common/query.vue";
+import apiSceneMeeting from "@/api/scene/meeting/apiSceneMeeting";
 
 export default {
   components: {
@@ -168,10 +169,16 @@ export default {
 
   },
   mounted() {
+    this.getMeetingRooms()
   },
   methods: {
     reset() {},
     search() {},
+    getMeetingRooms() {
+      apiSceneMeeting.getMeetingRoomList({}).then(res=>{
+        console.log(res)
+      })
+    }
   }
 }
 </script>

+ 42 - 3
src/components/scene/meeting/config/meetingStrategy.vue

@@ -8,14 +8,24 @@
           :rowKey=" (record, index) => index"
           :columns="columns"
           :data-source="tableData"
-          :pagination="false"
+          :pagination="true"
       >
+        <template #enable="text,record">
+          <a-switch v-model="text" checked-children="开" un-checked-children="关"/>
+        </template>
+        <template #operation="text,record">
+          <a-button type="link" @click="view">查看</a-button>
+          <a-button type="link" @click="edit">编辑</a-button>
+          <a-button type="link" @click="del">删除</a-button>
+        </template>
       </a-table>
     </div>
   </div>
 </template>
 
 <script>
+import apiSceneStrategy from "@/api/scene/apiSceneStrategy";
+
 export default {
   data() {
     return {
@@ -39,15 +49,44 @@ export default {
         {
           dataIndex: 'enable',
           key: 'enable',
-          title: '启用'
+          title: '启用',
+          scopedSlots: { customRender: 'enable' },
         },
         {
           dataIndex: 'operation',
           key: 'operation',
-          title: '操作'
+          title: '操作',
+          align: 'center',
+          scopedSlots: { customRender: 'operation' },
         },
       ]
     }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    getData() {
+      let params = {
+        type: '1'
+      };
+      let app = this;
+      apiSceneStrategy.getStrategyList(params).then(res=>{
+        res.forEach(item=>{
+          item.enable = item.status=='0'
+        })
+        this.tableData = res;
+      })
+    },
+    view() {
+
+    },
+    edit() {
+
+    },
+    del() {
+
+    }
   }
 }
 </script>

+ 29 - 141
src/components/security/alarm/securityAlarmGrid.vue

@@ -4,13 +4,13 @@
       <div style="height: 100%;margin: 0 15px 15px">
         <a-row style="height: 100%">
           <a-col :span="4" style="height: 90%">
-            <div style="padding-left: 15px; height: 100%">
-              <SecurityDeviceSelect :tree-data="treeData"></SecurityDeviceSelect>
+            <div style="padding-left: 15px; height: 100%;">
+              <SecurityDeviceSelect :tree-data="treeData" :callback="selectChange"></SecurityDeviceSelect>
             </div>
           </a-col>
           <a-col :span="20" style="height: 90%">
             <div style="height: 100%">
-              <HkwsCamera />
+              <HkwsCamera :cameraId="cameraId" :show-toolbar="true" />
             </div>
           </a-col>
         </a-row>
@@ -22,12 +22,16 @@
 <script>
 import HkwsCamera from "@/components/security/camera/hkwsCamera.vue";
 import SecurityDeviceSelect from "@/components/security/common/securityDeviceSelect.vue";
+import apiSecurityCamera from "@/api/security/apiSecurityCamera";
 
 export default {
   components: {
     SecurityDeviceSelect,
     HkwsCamera
   },
+  mounted() {
+    this.getCameraList()
+  },
   data() {
     return {
       gridConfig: {
@@ -35,146 +39,31 @@ export default {
         num: 1,
       },
       playerIdx: 1,
-      treeData: [
-        {
-          title: '一层大厅',
-          key: '1',
-          selectable: false,
-          children: [
-            {
-              title: '大厅正门',
-              key: '1-0',
-              slots: {
-                icon: 'camera',
-              },
-            },
-            {
-              title: '1-2',
-              key: '1-2',
-              slots: {
-                icon: 'camera',
-              },
-            },{
-              title: '1-3',
-              key: '1-3',
-              slots: {
-                icon: 'camera',
-              },
-            }
-
-          ],
-        },
-        {
-          title: '2F',
-          key: '2',
-          selectable: false,
-          children: [
-            {
-              title: '正门',
-              key: '2-0',
-              slots: {
-                icon: 'camera',
-              },
-            },{
-              title: '2-1',
-              key: '2-1',
-              slots: {
-                icon: 'camera',
-              },
-            },{
-              title: '2-2',
-              key: '2-2',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },
-        {
-          title: '3F',
-          key: '3',
-          selectable: false,
-          children: [
-            {
-              title: '正门',
-              key: '3-0',
-              slots: {
-                icon: 'camera',
-              },
-            },
-            {
-              title: '3-1',
-              key: '3-1',
-              slots: {
-                icon: 'camera',
-              },
-            },
-            {
-              title: '3-2',
-              key: '3-1',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },
-        {
-          title: '4F',
-          key: '4',
-          selectable: false,
-          children: [
-            {
-              title: '4-1',
-              key: '4-1',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },{
-          title: '5F',
-          key: '5',
-          selectable: false,
-          children: [
-            {
-              title: '5-1',
-              key: '5-1',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },{
-          title: '6F',
-          key: '6',
-          selectable: false,
-          children: [
-            {
-              title: '6-1',
-              key: '6-1',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },{
-          title: '7F',
-          key: '7',
-          selectable: false,
-          children: [
-            {
-              title: '7-1',
-              key: '7-1',
-              slots: {
-                icon: 'camera',
-              },
-            }
-          ],
-        },
-      ],
+      cameraId: '',
+      treeData: []
     }
   },
   methods: {
+    getCameraList() {
+      apiSecurityCamera.getCameraList().then(res=>{
+        res.forEach(item=>{
+          item.title = item.deviceName;
+          item.key = item.deviceId;
+          item.slots = {icon: 'camera',};
+        })
+        res.sort((a,b)=>{
+          if (a.title>b.title) {
+            return 1
+          } else {
+            return -1
+          }
+        })
+        this.treeData = res;
+      })
+    },
+    selectChange(id) {
+      this.cameraId = id;
+    },
     shot(e) {
       // console.log(e)
       // send({code:'image',data:e})
@@ -200,7 +89,6 @@ export default {
       aLink.click();
     },
     destroy(idx) {
-      console.log(idx);
       this.clear(idx.substring(idx.length - 1))
     },
   }

+ 12 - 10
src/components/security/alarm/securityAlarmMap.vue

@@ -14,8 +14,8 @@
           <span style="display: inline-block;margin-right: 12px">在线</span>
           <span class="anticon" style="vertical-align: bottom"><IconCamera :color="'#a2a4a2'" ></IconCamera></span>
           <span style="display: inline-block;margin-right: 12px">离线</span>
-          <span class="anticon" style="vertical-align: bottom"><IconCamera :color="'#ff4d4f'" ></IconCamera></span>
-          <span style="display: inline-block;margin-right: 12px">告警</span>
+          <!--<span class="anticon" style="vertical-align: bottom"><IconCamera :color="'#ff4d4f'" ></IconCamera></span>-->
+          <!--<span style="display: inline-block;margin-right: 12px">告警</span>-->
         </div>
       </div>
 
@@ -38,11 +38,11 @@
           <span class="securityAlarmMap-info-item-num" style="color: #4D4D4D">{{ deviceNum.unline }}</span>
         </span>
-        <span class="securityAlarmMap-info-item">
-          当前告警摄像头:
-          <span class="securityAlarmMap-info-item-num" style="color: #F1934E">{{ deviceNum.alarm }}</span>
-          台
-        </span>
+        <!--<span class="securityAlarmMap-info-item">-->
+        <!--  当前告警摄像头:-->
+        <!--  <span class="securityAlarmMap-info-item-num" style="color: #F1934E">{{ deviceNum.alarm }}</span>-->
+        <!---->
+        <!--</span>-->
       </div>
 
       <div class="securityAlarmMap-map">
@@ -59,7 +59,7 @@
         :footer="null"
     >
       <div style="height: 450px">
-        <hkwsCamera  />
+        <hkwsCamera :camera-id="currCameraId" :show-toolbar="false"  />
       </div>
     </a-modal>
 
@@ -75,6 +75,7 @@ import hkwsCamera from "@/components/security/camera/hkwsCamera.vue";
 export default {
   data() {
     return {
+      currCameraId: '',
       alarmNum: 0,
       floor: '1',
       areaSrc: 'security/area_1F.png',
@@ -89,7 +90,7 @@ export default {
           status: 1,
           left: 348,
           top: 27,
-          code: '123456'
+          code: 'a518fd68a2dc42e0ae50f9aacc0c261c'
         },{
           status: 1,
           left: 373,
@@ -115,7 +116,7 @@ export default {
           left: 300,
           top: 130,
         },{
-          status: 2,
+          status: 1,
           left: 325,
           top: 130,
         },{
@@ -141,6 +142,7 @@ export default {
   methods: {
     handleCameraVisible(code) {
       if (code && code!='') {
+        this.currCameraId = code
         this.showcamera = true;
       } else {
         this.$message.warning('暂未获取到视频流')

+ 52 - 15
src/components/security/camera/hkwsCamera.vue

@@ -1,26 +1,40 @@
 <template>
-  <hik-comp v-if="show" ref="hkws" class="hkws-camera" :playConfig="playConfig"
-            :nameId="jkInfo.nameId" :cameraIndexCode="jkInfo.cameraIndexCode" />
+  <hik-comp v-if="show" ref="hkws" class="hkws-camera" :playConfig.sync="playConfig"
+            :nameId="jkInfo.nameId" :cameraIndexCode.sync="jkInfo.cameraIndexCode" />
 
 </template>
 
 <script>
+import apiSecurityCamera from "@/api/security/apiSecurityCamera";
+
 export default {
   data() {
     return {
       show: false,
       jkInfo: {
         nameId: "playWnd1", // nameId 具有唯一性,否则无效,如果有多个,一定不能重复
-        cameraIndexCode: "4d43345c64744929b68e6a76678d60",  // 监控点编号
+        cameraIndexCode: "",  // 监控点编号
       }
     }
   },
+  props: {
+    cameraId: String,
+    toolButtonIds: String,
+    showToolbar: Boolean
+  },
+  watch: {
+    cameraId: function (val) {
+      this.jkInfo.cameraIndexCode=val;
+      this.$refs.hkws.cameraConfig.cameraIndexCode = val;
+      this.$refs.hkws.startPreview();
+    }
+  },
   computed: {
     playConfig: function () {
       return {
-        appkey: "23546469",
-        secret: "Mgv0uhy7D2rnbKb6k17W",
-        ip: "182.92.242.51",
+        appkey: "",
+        secret: "",
+        ip: "",
         playMode: 0,
         port: 443,
         snapDir: "/SnapDir",
@@ -28,25 +42,48 @@ export default {
         layout: "1x1",
         enableHTTPS: 1,
         encryptedFields: 'secret',
-        showToolbar: 0,
+        showToolbar: this.showToolbar?1:0,
         showSmart: 0,
         buttonIDs: "",
-        toolBarButtonIDs: "4098",
+        toolBarButtonIDs: "4097,4098",
       }
     }
   },
   mounted() {
     this.$nextTick(()=>{
-      this.show=true
+      if (this.cameraId && this.cameraId.length>0) {
+        this.jkInfo.cameraIndexCode = this.cameraId
+      }
+      if (this.toolButtonIds && this.toolButtonIds.length>0) {
+        this.playConfig.toolBarButtonIDs = this.toolButtonIds
+      }
+      this.getApiInfo()
     })
   },
+  methods: {
+    getApiInfo() {
+      apiSecurityCamera.getHkApi().then(res=>{
+        let split = res.host.split(":");
+        this.playConfig.ip = split[0];
+        this.playConfig.port = Number(split[1]);
+        this.playConfig.appkey = res.appKey
+        this.playConfig.secret = res.appSecret
+        this.show = true;
+      }).catch(err=>{
+        this.$message.error('摄像头平台初始化失败')
+      })
+    },
+  },
   beforeDestroy() {
-    this.$refs.hkws.oWebControl.JS_StopService('window')
-        .then(() => {})
-        .catch((err) => console.log(err))
-    this.$refs.hkws.oWebControl.JS_DestroyWnd()
-        .then(() => {})
-        .catch((err) => console.log(err))
+    if (this.$refs.hkws && this.$refs.hkws.oWebControl) {
+      this.$refs.hkws.oWebControl.JS_StopService('window')
+          .then(() => {})
+          .catch((err) => console.log(err))
+      this.$refs.hkws.oWebControl.JS_DestroyWnd()
+          .then(() => {})
+          .catch((err) => console.log(err))
+    }
+
   }
 }
 </script>

+ 20 - 11
src/components/security/common/securityDeviceSelect.vue

@@ -1,21 +1,22 @@
 <template>
   <div class="securityDeviceSelect" style="width: 100%;height: 100%">
     <div class="securityDeviceSelect-title">设备点位</div>
-    <div>
+    <div style="height: 90%;padding-bottom: 15px;">
       <a-input-search style="margin-bottom: 8px" placeholder="请输入关键字" @change="onChange"/>
-      <a-tree
-          :expanded-keys="expandedKeys"
-          :auto-expand-parent="true"
-          :selected-keys="['1-0']"
-          :tree-data="treeData"
-          :show-icon="true"
-          @expand="onExpand"
+      <a-tree style="height: 100%;overflow-y: auto"
+              :expanded-keys="expandedKeys"
+              :auto-expand-parent="true"
+              :selected-keys="['1-0']"
+              :tree-data="treeData"
+              :show-icon="true"
+              @expand="onExpand"
+              @select="onSelect"
       >
         <template #camera>
-          <span class="anticon"><i-icon-park-outline-camera-two /></span>
+          <span class="anticon"><i-icon-park-outline-camera-two/></span>
         </template>
         <template #water>
-          <span class="anticon"><i-icon-park-outline-control /></span>
+          <span class="anticon"><i-icon-park-outline-control/></span>
         </template>
 
         <template #title="{ title }">
@@ -37,6 +38,7 @@ import Card from "@/components/common/card.vue";
 export default {
   props: {
     treeData: Array,
+    callback: Function
   },
   data() {
     return {
@@ -56,11 +58,16 @@ export default {
       this.expandedKeys = expandedKeys;
       this.autoExpandParent = false;
     },
+    onSelect(val) {
+      if (val.length>0) {
+        this.callback(val[0])
+      }
+    },
     generateList(data) {
       for (let i = 0; i < data.length; i++) {
         const node = data[i];
         const key = node.key;
-        this.oriData.push({ key, title: key });
+        this.oriData.push({key, title: key});
         if (node.children) {
           this.generateList(node.children);
         }
@@ -107,11 +114,13 @@ export default {
   background-color: #fafafa;
   padding: 15px;
   border-radius: 6px;
+
   .securityDeviceSelect-title {
     color: #666666;
     font-size: 16px;
     margin: 8px 0;
   }
+
   /deep/ .ant-tree-switcher-noop {
     display: none;
   }

+ 47 - 61
src/components/security/person/components/securityPersonDuty.vue

@@ -1,47 +1,17 @@
 <script>
+import apiSecurityPerson from "@/api/security/apiSecurityPerson";
+
 export default {
   data() {
     return {
+      loading: false,
       tagCheck: {
         front: false,
         security: false,
       },
       currCheck: '',
       oriDutyPerson: [],
-      dutyPerson: [
-        {
-          id: 1,
-          name: '章峰',
-          workNum: '31313131',
-          telNum: '18611111111',
-          workArea: '一层大厅前台',
-          img: '',
-        },
-        {
-          id: 2,
-          name: '刘玉英',
-          workNum: '31313131',
-          telNum: '18611111111',
-          workArea: '一层大厅前台',
-          img: '',
-        },
-        {
-          id: 3,
-          name: '刘玉英',
-          workNum: '31313131',
-          telNum: '18611111111',
-          workArea: '一层大厅前台',
-          img: '',
-        },
-        {
-          id: 4,
-          name: '刘玉英',
-          workNum: '31313131',
-          telNum: '18611111111',
-          workArea: '一层大厅前台',
-          img: '',
-        },
-      ]
+      dutyPerson: []
     }
   },
   watch: {
@@ -52,7 +22,7 @@ export default {
   components: {},
   mounted() {
     this.handleTagSelect('front');
-    this.oriDutyPerson = JSON.parse(JSON.stringify(this.dutyPerson))
+    this.getPersonData()
   },
   methods: {
     callback(val) {
@@ -65,12 +35,26 @@ export default {
         this.dutyPerson = this.oriDutyPerson.filter(item => item.name.indexOf(val)>-1)
       }
     },
+    getPersonData() {
+      this.loading = true
+      let type = this.tagCheck.security?"2":"1"
+      apiSecurityPerson.getPersonDuty({
+        type: type
+      }).then(res=>{
+        this.dutyPerson = res;
+        this.oriDutyPerson = JSON.parse(JSON.stringify(this.dutyPerson));
+        this.loading = false;
+      }).catch(err=>{
+        this.loading = false
+      })
+    },
     handleTagSelect(item) {
       for (const key in this.tagCheck) {
         this.tagCheck[key] = false;
       }
       this.currCheck = item;
       this.tagCheck[item] = true;
+      this.getPersonData()
     },
     openMore() {
       this.$router.push({path: '/security/person/more'})
@@ -97,39 +81,41 @@ export default {
         <a-input-search placeholder="姓名" style="width: 140px" @search="onSearch"/>
       </div>
     </div>
-    <div class="dashboardPortrait-body">
-      <div >
-        <div class="security-person-duty-content" >
-          <div class="security-person-duty-item" v-for="p in dutyPerson" :key="p.id">
-            <div class="security-person-duty-item-img">
-              <img width="90%" height="90%" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
-            </div>
-            <div class="security-person-duty-item-desc">
-              <div class="security-person-duty-item-desc-text">
-                <span class="security-person-duty-item-desc-label">姓名</span>:
-                {{ p.name }}
-              </div>
-              <div class="security-person-duty-item-desc-text">
-                <span class="security-person-duty-item-desc-label">工号</span>:
-                {{ p.workNum }}
+    <a-spin :spinning="loading">
+      <div class="dashboardPortrait-body">
+        <div >
+          <div class="security-person-duty-content" >
+            <div class="security-person-duty-item" v-for="p in dutyPerson" :key="p.id">
+              <div class="security-person-duty-item-img">
+                <img width="90%" height="90%" :src="p.photo"/>
               </div>
-              <div class="security-person-duty-item-desc-text">
-                <span class="security-person-duty-item-desc-label">联系电话</span>:
-                {{ p.telNum }}
-              </div>
-              <div class="security-person-duty-item-desc-text">
-                <span class="security-person-duty-item-desc-label">工作区域</span>:
-                {{ p.workArea }}
+              <div class="security-person-duty-item-desc">
+                <div class="security-person-duty-item-desc-text">
+                  <span class="security-person-duty-item-desc-label">姓名</span>:
+                  {{ p.name }}
+                </div>
+                <div class="security-person-duty-item-desc-text">
+                  <span class="security-person-duty-item-desc-label">工号</span>:
+                  {{ p.work_number }}
+                </div>
+                <div class="security-person-duty-item-desc-text">
+                  <span class="security-person-duty-item-desc-label">联系电话</span>:
+                  {{ p.phone }}
+                </div>
+                <div class="security-person-duty-item-desc-text">
+                  <span class="security-person-duty-item-desc-label">工作区域</span>:
+                  {{ p.scope }}
+                </div>
               </div>
             </div>
-          </div>
 
-          <div style="position: absolute;bottom: 12px;background-color: #ffffff;height: 35px;width: 90%">
-            <a-button type="primary" size="small" style="float: right;right: 5px;top:25%" @click="openMore">更多</a-button>
+            <div style="position: absolute;bottom: 12px;background-color: #ffffff;height: 35px;width: 90%">
+              <a-button type="primary" size="small" style="float: right;right: 5px;top:25%" @click="openMore">更多</a-button>
+            </div>
           </div>
         </div>
       </div>
-    </div>
+    </a-spin>
   </div>
 </template>
 

+ 72 - 39
src/components/security/person/securityPersonMore.vue

@@ -1,24 +1,17 @@
 <script>
 import TimeRange from "@/components/common/timeRange.vue";
+import apiSecurityPerson from "@/api/security/apiSecurityPerson";
 
 export default {
   components: {TimeRange},
   data() {
     return {
+      loading: false,
       showDetail: false,
       currRecord: {},
       formData: {},
-      tableData: [{
-        id: 1,
-        name: '123'
-      }],
+      tableData: [],
       columns: [
-        {
-          title: '图片',
-          dataIndex: "image",
-          key: "image",
-          align: 'center',
-        },
         {
           title: '姓名',
           dataIndex: "name",
@@ -30,11 +23,12 @@ export default {
           dataIndex: "type",
           key: "type",
           align: 'center',
+          scopedSlots: {customRender: 'type'},
         },
         {
           title: '工作区域',
-          dataIndex: "area",
-          key: "area",
+          dataIndex: "scope",
+          key: "scope",
           align: 'center',
         },
         {
@@ -42,6 +36,7 @@ export default {
           dataIndex: "duty",
           key: "duty",
           align: 'center',
+          scopedSlots: {customRender: 'duty'},
         },
         {
           title: '操作',
@@ -54,15 +49,43 @@ export default {
       ]
     }
   },
+  mounted() {
+    this.getPersonData()
+  },
   methods: {
     viewDetail(record) {
       this.currRecord = JSON.parse(JSON.stringify(record));
       this.showDetail = true;
-
+    },
+    getPersonData() {
+      this.loading = true
+      apiSecurityPerson.getPersonDuty({
+      }).then(res=>{
+        this.tableData = res;
+        this.oriData= JSON.parse(JSON.stringify(this.tableData));
+        this.loading = false;
+      }).catch(err=>{
+        this.loading = false
+      })
     },
     handleCancel() {
       this.currRecord = {};
       this.showDetail = false;
+    },
+    reset() {
+      this.formData = {};
+      this.search()
+    },
+    search() {
+      this.tableData = this.oriData.filter(item=>{
+        if (this.formData.type && this.formData.type!='' && item.type!=this.formData.type) {
+          return false;
+        }
+        if (this.formData.name && this.formData.name!='' && item.name.indexOf(this.formData.name)<0) {
+          return false;
+        }
+        return true;
+      })
     }
   }
 }
@@ -74,20 +97,21 @@ export default {
       <a-form-model :model="formData" layout="inline">
         <a-form-model-item label="人员类型">
           <a-select v-model="formData.type" placeholder="人员类型" style="width: 130px">
-            <a-select-option value="front">前台人员</a-select-option>
-            <a-select-option value="security">安防人员</a-select-option>
+            <a-select-option value="1">前台人员</a-select-option>
+            <a-select-option value="2">安防人员</a-select-option>
           </a-select>
         </a-form-model-item>
-        <a-form-model-item label="值班时段">
-          <TimeRange :disabled-time="false"
-                     :show-time="{ hideDisabledOptions: true, defaultValue: [ $moment('00:00:00', 'HH:mm:ss'), $moment('23:59:59', 'HH:mm:ss'), ], }"
-                     :time-format="'YYYY/MM/DD HH:mm:ss'"
-          >
-          </TimeRange>
+        <a-form-model-item label="姓名">
+          <!--<TimeRange :disabled-time="false"-->
+          <!--           :show-time="{ hideDisabledOptions: true, defaultValue: [ $moment('00:00:00', 'HH:mm:ss'), $moment('23:59:59', 'HH:mm:ss'), ], }"-->
+          <!--           :time-format="'YYYY/MM/DD HH:mm:ss'"-->
+          <!--&gt;-->
+          <!--</TimeRange>-->
+          <a-input v-model="formData.name" placeholder="请输入姓名" />
         </a-form-model-item>
-        <a-form-model-item>
-          <a-button type="primary">重置</a-button>
-          <a-button type="primary">查询</a-button>
+        <a-form-model-item >
+          <a-button style="width: 80px" size="small" type="info" @click="reset">重置</a-button>
+          <a-button style="width: 80px" size="small" type="primary" @click="search">查询</a-button>
         </a-form-model-item>
       </a-form-model>
     </div>
@@ -95,21 +119,31 @@ export default {
       <div style="font-weight: 400;color: #333333;line-height: 45px;font-size: 16px;margin-bottom: 6px">人员信息</div>
       <a-table
           :rowKey=" (record, index) => index"
+          :loading="loading"
           :columns="columns"
           :data-source="tableData"
           :pagination="true"
-          style="height: 300px"
+          style="height: 300px;background-color: white"
       >
         <template #operation="text, record">
           <a-button type="link" @click="viewDetail(record)">查看详情</a-button>
         </template>
+        <template #type="text, record">
+          <span v-if="record.type=='1'" >前台人员</span>
+          <span v-else-if="record.type=='2'" >安防人员</span>
+          <span v-else>未知</span>
+        </template>
+        <template #duty="text, record">
+          <span>{{ record.duty_start_time }}</span>/
+          <span>{{ record.duty_end_time }}</span>
+        </template>
       </a-table>
     </div>
 
 
     <a-modal class="securityPersonMoreDetail" v-if="showDetail"
              :visible="true"
-             :width="600"
+             :width="650"
              :footer="null"
              @cancel="handleCancel"
     >
@@ -117,34 +151,31 @@ export default {
       <a-divider/>
 
       <div style="width: 100%;height: 100%">
-        <div style="width: 40%;display: inline-block">
-          <img width="100%" height="100%" src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"/>
+        <div style="width: 40%;display: inline-block;margin-right: 5%">
+          <img width="100%" height="100%" :src="currRecord.photo"/>
         </div>
-        <div style="width: 60%;display: inline-block;vertical-align: top">
+        <div style="width: 50%;display: inline-block;vertical-align: top">
           <a-descriptions :column="1" size="small">
             <a-descriptions-item label="姓名">
-              刘玉英
-            </a-descriptions-item>
-            <a-descriptions-item label="性别">
-              女
+              {{ currRecord.name }}
             </a-descriptions-item>
             <a-descriptions-item label="工号">
-              31313131
+              {{ currRecord.work_number }}
             </a-descriptions-item>
             <a-descriptions-item label="工作类型">
               前台人员
             </a-descriptions-item>
             <a-descriptions-item label="联系电话">
-              18611111111
+              {{ currRecord.phone }}
             </a-descriptions-item>
             <a-descriptions-item label="工作区域">
-              一层大厅前台
+              {{ currRecord.scope }}
             </a-descriptions-item>
             <a-descriptions-item label="入职日期">
-              2022年3月1日
+              -
             </a-descriptions-item>
             <a-descriptions-item label="今日工作时段">
-              上午8:00-12:00 下午13::30-17:30
+              {{ currRecord.duty_start_time }}/{{ currRecord.duty_end_time }}
             </a-descriptions-item>
           </a-descriptions>
         </div>
@@ -156,7 +187,7 @@ export default {
 <style lang="less" scoped>
 .security-person-more {
   width: 100%;
-  height: auto;
+  height: 100%;
   .security-person-more-query {
     padding-left: 30px;
   }
@@ -165,6 +196,8 @@ export default {
     margin-top: 15px;
     background-color: #ffffff;
     padding: 0 30px;
+    height: 600px;
+    overflow-y: auto;
   }
 }
 </style>

+ 13 - 1
src/components/work/bus/component/workBusChart.vue

@@ -72,7 +72,19 @@ export default {
           },
           backgroundColor: 'rgba(0,0,0,0.8)',
         },
-        dataZoom: this.$constant.ECHARTS_DATAZOOM,
+        dataZoom: [
+          {
+            type: 'slider',
+            start: 0,
+            end: 100,
+            height: 12,
+          },
+          {
+            type: 'inside',
+            start: 0,
+            end: 100,
+          }
+        ],
         series: [
           {
             name: '平均出车时长',

+ 13 - 1
src/components/work/meeting/component/workMeetingCostTrend.vue

@@ -94,7 +94,19 @@ export default {
     return {
       option: {
         // backgroundColor: "#000237",
-        dataZoom: this.$constant.ECHARTS_DATAZOOM,
+        dataZoom: [
+          {
+            type: 'slider',
+            start: 0,
+            end: 100,
+            height: 12,
+          },
+          {
+            type: 'inside',
+            start: 0,
+            end: 100,
+          }
+        ],
         tooltip: {
           trigger: "axis",
           // backgroundColor: "transparent",

+ 17 - 14
src/utils/constant.js

@@ -1,17 +1,20 @@
 // 常量-echarts滚动轴设置
-const ECHARTS_DATAZOOM = [
-    {
-        type: 'slider',
-        start: 0,
-        end: 100,
-        height: 12,
-    },
-    {
-        type: 'inside',
-        start: 0,
-        end: 100,
-    }
-]
+const ECHARTS_OPTION = {
+    dataZoom: [
+        {
+            type: 'slider',
+            start: 0,
+            end: 100,
+            height: 12,
+        },
+        {
+            type: 'inside',
+            start: 0,
+            end: 100,
+        }
+    ]
+}
+
 
 const ECHARTS_BAR_WIDTH = '30%'
 
@@ -65,5 +68,5 @@ const COLOR_LEAVEL = {
 // 折线图可选颜色
 const ECHART_LINE_COLOR_LIST = ["#303133", "#606266", "#909399", "#C0C4CC", "DCDFE6"];
 export default {
-    PICKER_OPTIONS, COLOR_LEAVEL, ECHART_LINE_COLOR_LIST,ECHARTS_DATAZOOM,ECHARTS_BAR_WIDTH
+    PICKER_OPTIONS, COLOR_LEAVEL, ECHART_LINE_COLOR_LIST, ECHARTS_OPTION, ECHARTS_BAR_WIDTH
 }

+ 65 - 1
src/utils/dataUtil.js

@@ -31,12 +31,76 @@ const refreshEchartsData = (instance, option, data) => {
         }
         arr.push(data[key])
     }
+    let stackMap = new Map();
     for (let i = 0; i < option.series.length; i++) {
-        option.series[i].data = arr[i]
+        option.series[i].data = arr[i];
+        option.series[i].smooth = true;
+        option.series[i].showSymbol = false;
+
+        let stack = option.series[i].stack;
+        let index = option.series[i].yAxisIndex?option.series[i].yAxisIndex:0;
+        if (stack) {
+            let key = stack+"---"+index;
+            if (!stackMap.has(key)) {
+                stackMap.set(key, []);
+            }
+            stackMap.get(key).push(arr[i])
+        } else {
+            let obj = getInterval(arr[i]);
+            let yAxis = option.yAxis[index];
+            if (!yAxis.max || yAxis.max<obj.max) {
+                Object.assign(option.yAxis[index], obj)
+            }
+        }
     }
+    stackMap = dealStackInterval(stackMap);
+    console.log(stackMap)
+    stackMap.forEach((value, key, map)=>{
+        let index = key.split("---")[1];
+        let obj = getInterval(value);
+        let yAxis = option.yAxis[index];
+        if (!yAxis.max || yAxis.max<obj.max) {
+            Object.assign(option.yAxis[index], obj)
+        }
+    });
+    console.log(option.yAxis)
     instance.setOption(option)
 }
 
+const dealStackInterval = (stackMap) => {
+    let indexMap = new Map();
+    stackMap.forEach((value, key, map)=>{
+        let arr = [];
+        for (let i = 0; i < value[0].length; i++) {
+            let num = 0;
+            for (let j = 0; j < value.length; j++) {
+                num = num + value[j][i]
+            }
+            arr.push(num);
+        }
+        indexMap.set(key,arr);
+    })
+    return indexMap
+}
+
+const getInterval = (arr) => {
+    let splitNum = 5;
+    let max = Math.ceil(Math.max.apply(null, arr)*1.2/ splitNum)*splitNum;
+    let interval = Math.ceil(max/splitNum)
+    if (max <= 10) {
+        return {
+            min: 0,
+            max: 10,
+            interval: 2
+        }
+    }
+    return {
+        max: max,
+        min: 0,
+        interval: interval,
+    };
+}
+
 const circleChartArrToObj = (arr) => {
   let obj = {};
   if (arr) {

+ 1 - 1
vite.config.js

@@ -112,7 +112,7 @@ export default defineConfig(({ command }) => {
       port: 8081,
       proxy: {
         "/ioc-api": {
-          target: "http://121.43.55.7:10091/ioc-server",
+          target: "http://127.0.0.1:10099",
           changeOrigin: true,
           rewrite: (path) => path.replace(/^\/ioc-api/, ""),
         },