xieqy 1 year ago
parent
commit
c1e2fbb92c

+ 1 - 1
public/config.js

@@ -18,7 +18,7 @@ export const geoServerConfigIn = {
 
 export const geoServerConfigOut = {
   //客户
-  geoServerUrl:'http://117.177.153.11:12002/',
+  geoServerUrl: 'http://117.177.153.11:12002/',
   //公司
   geoServerUrl1: 'http://221.182.8.141:12002/'
 }

+ 27 - 1
src/views/saSubsystem/StatisticalStatement/MonthlyOperatingRecord/widget.vue

@@ -59,7 +59,9 @@
         >
         </el-date-picker>
         <el-button type="primary" size="small" class="search-button" @click="getRecord()">统计</el-button>
-        <!-- <el-button type="primary" size="small" class="export-button" icon="el-icon-upload2">导出</el-button> -->
+        <el-button type="primary" size="small" class="export-button" icon="el-icon-upload2" @click="exportTable()"
+          >导出</el-button
+        >
       </div>
       <div class="main-content">
         <com-table
@@ -104,6 +106,7 @@ import { comSidePage, comTable } from '../../component/index'
 import { MonthlyOperatingRecordCols } from '../../common/settings'
 import { getFactoryList, getRunTheRecord } from '../../common/requestapis'
 import moment from 'moment'
+import axios from '@/utils/request'
 //月度运行记录
 @Component({ name: 'MonthlyOperatingRecord', components: { comSidePage, comTable } })
 export default class MonthlyOperatingRecord extends Vue {
@@ -171,6 +174,7 @@ export default class MonthlyOperatingRecord extends Vue {
     label: 'label'
   }
   selectStationList = []
+  params = null //参数保存
   //表格参数
   MonthlyOperatingRecordCols = MonthlyOperatingRecordCols
 
@@ -231,6 +235,7 @@ export default class MonthlyOperatingRecord extends Vue {
           end: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
         }
       }
+    this.params = params
     const res = await getRunTheRecord(params) //0月度,1季度
     this.tableData = res.result.map((i) => {
       Object.keys(i).forEach((item) => {
@@ -272,6 +277,27 @@ export default class MonthlyOperatingRecord extends Vue {
     }
     this.customDate = [moment(time[0]).format('YYYY-MM-DD HH:mm:ss'), moment(time[1]).format('YYYY-MM-DD HH:mm:ss')]
   }
+  //导出
+  async exportTable() {
+    axios
+      .request({
+        url: '/monitor/statisticalAnalysis/runTheRecord',
+        method: 'get',
+        params: { ...this.params, isExport: 1 },
+        responseType: 'arraybuffer'
+      })
+      .then((res) => {
+        var blob = new Blob([res], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        })
+        const href = URL.createObjectURL(blob) // 创建新的URL表示指定的blob对象
+        const a = document.createElement('a')
+        a.style.display = 'none'
+        a.href = href // 指定下载链接
+        a.download = '月度运行记录.xls' // 指定下载文件名
+        a.click()
+      })
+  }
 }
 </script>
 

+ 27 - 1
src/views/saSubsystem/StatisticalStatement/QuarterlyOperatingRecord/widget.vue

@@ -45,7 +45,9 @@
         >
         </el-date-picker>
         <el-button type="primary" size="small" class="search-button" @click="getRecord()">统计</el-button>
-        <!-- <el-button type="primary" size="small" class="export-button" icon="el-icon-upload2">导出</el-button> -->
+        <el-button type="primary" size="small" class="export-button" icon="el-icon-upload2" @click="exportTable()"
+          >导出</el-button
+        >
       </div>
       <div class="main-content">
         <com-table
@@ -85,6 +87,7 @@
 </template>
 
 <script lang='ts'>
+import axios from '@/utils/request'
 import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
 import { comSidePage, comTable } from '../../component/index'
 import { MonthlyOperatingRecordCols } from '../../common/settings'
@@ -143,6 +146,7 @@ export default class QuarterlyOperatingRecord extends Vue {
     label: 'label'
   }
   selectStationList = []
+  params = null //参数保存
   //表格参数
   MonthlyOperatingRecordCols = _.cloneDeep(MonthlyOperatingRecordCols).map((i) => {
     if (i.prop == 'time') i.label = '季度'
@@ -206,6 +210,7 @@ export default class QuarterlyOperatingRecord extends Vue {
           end: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
         }
       }
+    this.params = params
     const res = await getRunTheRecord(params) //0月度,1季度
     this.tableData = res.result.map((i) => {
       Object.keys(i).forEach((item) => {
@@ -234,6 +239,27 @@ export default class QuarterlyOperatingRecord extends Vue {
       return [0, 0]
     }
   }
+  //导出
+  async exportTable() {
+    axios
+      .request({
+        url: '/monitor/statisticalAnalysis/runTheRecord',
+        method: 'get',
+        params: { ...this.params, isExport: 1 },
+        responseType: 'arraybuffer'
+      })
+      .then((res) => {
+        var blob = new Blob([res], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        })
+        const href = URL.createObjectURL(blob) // 创建新的URL表示指定的blob对象
+        const a = document.createElement('a')
+        a.style.display = 'none'
+        a.href = href // 指定下载链接
+        a.download = '季度运行记录.xls' // 指定下载文件名
+        a.click()
+      })
+  }
 }
 </script>
 

+ 6 - 2
src/views/supSubsystem/PlantFlowManagement/DataStatistics/widget.vue

@@ -262,9 +262,13 @@ export default class DataStatistics extends Vue {
       // return { ...i, tableData: historyData[i.siteCode], xData, seriesData }
       let target = classifyList.find((e) => e.type == i.indexName)
       if (!target) {
-        classifyList.push({ type: i.indexName, unit: i.unit, data: [{ ...i, historyData: historyData[i.siteCode] }] })
+        classifyList.push({
+          type: i.indexName,
+          unit: i.unit,
+          data: [{ ...i, historyData: historyData[i.siteCode] }] || []
+        })
       } else {
-        target.data.push({ ...i, historyData: historyData[i.siteCode] })
+        target.data.push({ ...i, historyData: historyData[i.siteCode] || [] })
       }
     })
     classifyList = classifyList.map((i) => {

+ 76 - 2
src/views/vmSubsystem/VideoOverview/widget.vue

@@ -217,6 +217,9 @@ export default class VideoOverview extends Vue {
   currentPage = 1
 
   timer = null
+
+  currentZoomLevel = null //当前地图缩放级别
+  cameraDataSourceList = []
   //computed
   get playicon() {
     return require('../images/playicon.png')
@@ -234,12 +237,19 @@ export default class VideoOverview extends Vue {
       this.cameraShowList.push(this.cameraList.slice(i, i + 3))
     }
   }
+  @Watch('cameraDataSourceList')
+  onCamearDsChange() {
+    if (this.cameraDataSourceList.length == this.cameraList.length) {
+      this.changeShowType()
+    }
+  }
   get mapView() {
     return (this.$attrs.data as any).mapView
   }
   @Watch('mapView', { immediate: true })
   onChangeMethod(val) {
     this.debounce(() => {
+      this.currentZoomLevel = this.mapView.getView().getZoom()
       this.getCameraType()
       this.initMapTool()
     }, 300)()
@@ -279,6 +289,7 @@ export default class VideoOverview extends Vue {
     this.isSearchCompleted = true
     this.originalData = result
     this.initialDisplay(result, true)
+    this.zoomAndMove()
   }
 
   //初始显示
@@ -408,7 +419,11 @@ export default class VideoOverview extends Vue {
     const data = emitData
     let position = [data.longitude || 0, data.latitude || 0]
     const dataSource = { ...data, position: position.map((i) => Number(i)), src: img }
-    this.isShowAllSites ? this.mapTool.showPointSymbol(dataSource) : this.mapTool.located(dataSource, true)
+    if (this.isShowAllSites) {
+      this.cameraDataSourceList.push(dataSource)
+    } else {
+      this.mapTool.located(dataSource, true)
+    }
   }
   //获取长度
   getAllChildLength(node) {
@@ -442,7 +457,8 @@ export default class VideoOverview extends Vue {
   }
   //展示视频点
   mapShowSite(sites) {
-    this.mapTool.vectorLayer.getSource().clear()
+    this.mapTool.clear()
+    this.cameraDataSourceList = []
     this.isShowAllSites = true
     ;(async () => {
       for (let index = 0; index < sites.length; index++) {
@@ -492,11 +508,69 @@ export default class VideoOverview extends Vue {
     this.detailsData = null
     this.mapTool.select.getFeatures().clear()
   }
+  // 开启缩放和拖动
+  zoomAndMove() {
+    //地图缩放和平移事件回调函数
+    let mapZoomAndMove = () => {
+      this.changeShowType()
+    }
+    //注册事件
+    this.registerOnZoom(mapZoomAndMove)
+  }
+  //地图缩放监听
+  registerOnZoom(eventListen, notListenMove?) {
+    let map = this.mapView
+    // 记录地图缩放,用于判断拖动
+    map.lastZoom = map.lastZoom || map.getView().getZoom()
+    // 地图缩放事件
+    let registerOnZoom = function (e) {
+      // 不监听地图拖动事件
+      if (notListenMove) {
+        if (map.lastZoom != map.getView().getZoom()) {
+          eventListen && eventListen(e)
+        }
+      } else {
+        eventListen && eventListen(e)
+      }
+      map.lastZoom = map.getView().getZoom()
+    }
+    // 保存缩放和拖动事件对象,用于后期移除
+    let registerOnZoomArr = map.get('registerOnZoom') || []
+    registerOnZoomArr.push(registerOnZoom)
+    // 使用地图 set 方法保存事件对象
+    map.set('registerOnZoom', registerOnZoomArr)
+    // 监听地图移动结束事件
+    map.on('moveend', registerOnZoom)
+    return eventListen
+  }
+  // 移除缩放和拖动事件对象
+  removeZoomRegister() {
+    let map = this.mapView
+    let registerOnZoomArr = map.get('registerOnZoom')
+    if (registerOnZoomArr && registerOnZoomArr.length > 0) {
+      for (let i = 0; i < registerOnZoomArr.length; i++) {
+        map.un('moveend', registerOnZoomArr[i])
+      }
+    }
+  }
+  //聚合展示还是图标展示
+  changeShowType() {
+    this.currentZoomLevel = this.mapView.getView().getZoom()
+    this.mapTool.clear()
+    if (this.currentZoomLevel < 18) {
+      this.mapTool.showClusterPoint(this.cameraDataSourceList)
+    } else {
+      this.cameraDataSourceList.forEach((item) => {
+        this.mapTool.showPointSymbol(item)
+      })
+    }
+  }
   beforeDestroy() {
     if (this.mapTool) this.mapTool.destroy()
     this.dialogVisible = false
     this.checkSite = null
     this.detailsData = null
+    this.removeZoomRegister()
   }
 }
 </script>

+ 70 - 5
src/views/vmSubsystem/common/maptool.ts

@@ -1,16 +1,17 @@
 
 import { Map } from "ol";
 import { Vector as VectorLayer } from 'ol/layer'
-import { Vector as VectorSource } from 'ol/source'
+import { Cluster, Vector as VectorSource } from 'ol/source'
 import { Geometry } from 'ol/geom'
 import Feature from 'ol/Feature';
 import { Point } from 'ol/geom';
-import { Style, Icon, } from 'ol/style';
+import { Style, Icon, Text, Fill, Circle, Stroke } from 'ol/style';
 import { Select } from 'ol/interaction'
 export default class maptool {
 
     view: Map = null
     vectorLayer: VectorLayer<VectorSource<Geometry>> = null
+    clusterLayer: VectorLayer<VectorSource<Geometry>> = null
     feature: Feature<any> = null
     src: string = null
     select: Select = null
@@ -46,14 +47,67 @@ export default class maptool {
             data
         });
         //创建标记的样式
-        this.feature.setStyle(this.setFeatureStyle());
+        this.feature.setStyle(this.setFeatureStyle(data));
         this.vectorLayer.getSource().addFeature(this.feature);
     }
+    //聚合展示
+    showClusterPoint(data) {
+        if (this.clusterLayer) return//防止重复加载
+        let features = []
+        data.forEach(item => {
+            //创建Feature,并添加进矢量容器中
+            let feature = new Feature(new Point(item.position));
+            features.push(feature)
+        });
+        const clusterSource = new Cluster({
+            source: new VectorSource({ features: features, }),
+            distance: 40,
+        })
+        const styleCache = {};
+        this.clusterLayer = new VectorLayer({
+            source: clusterSource,
+            style: function (feature) {
+                const size = feature.get('features').length;
+                let style = styleCache[size];
+                if (!style) {
+                    style = new Style({
+                        image: new Circle({
+                            radius: 20,
+                            stroke: new Stroke({
+                                color: '#fff',
+                            }),
+                            fill: new Fill({
+                                color: '#9351D6',
+                            }),
+                        }),
+                        text: new Text({
+                            text: size.toString(),
+                            fill: new Fill({
+                                color: '#fff',
+                            }),
+                        }),
+                    });
+                    styleCache[size] = style;
+                }
+                return style;
+            },
+        });
+        this.view.addLayer(this.clusterLayer);
+    }
     /**
      * @description 为要素设置样式
      */
-    setFeatureStyle() {
+    setFeatureStyle(data) {
+        const { videoTypeName, name } = data
+        let text = `${videoTypeName ? '【' + videoTypeName + '】' : ''}` + `${name || ''}`//添加文本
         return new Style({
+            text: new Text({
+                offsetY: 15,
+                font: 'bold 14px sans-serif',
+                text,
+                fill: new Fill({ color: '#000' }),
+                backgroundFill: new Fill({ color: '#fff' }),
+            }),
             image: new Icon({
                 anchor: [0.5, 1],
                 scale: 1,
@@ -74,9 +128,20 @@ export default class maptool {
         this.view.addInteraction(this.select)
         return this.select
     }
+    clear() {
+        if (this.vectorLayer) this.vectorLayer.getSource().clear()
+        if (this.clusterLayer) {
+            this.view.removeLayer(this.clusterLayer)
+            this.clusterLayer = null
+        }
+    }
     //工具销毁
     destroy() {
-        if (this.vectorLayer) this.vectorLayer.getSource().clear()
+        if (this.vectorLayer) {
+            this.vectorLayer.getSource().clear()
+            this.view.removeLayer(this.vectorLayer)
+        }
+        if (this.clusterLayer) this.view.removeLayer(this.clusterLayer)
         if (this.select) this.view.removeInteraction(this.select)
     }
 }