From 67d3b57765b0ba66ae25a9da84a16e44a4ef2937 Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期三, 25 三月 2026 09:13:59 +0800
Subject: [PATCH] 调整

---
 src/views/dataAnalysis/components/DataReGasStation.vue |  146 ++++++++++++++++++++++++
 src/components/tools/Logo.vue                          |   12 -
 src/assets/img/sdjt.jpg                                |    0 
 src/views/dataAnalysis/components/DataReLineChart.vue  |  202 +++++++++++++++++++++++++++++++++
 4 files changed, 350 insertions(+), 10 deletions(-)

diff --git a/src/assets/img/sdjt.jpg b/src/assets/img/sdjt.jpg
new file mode 100644
index 0000000..598d16f
--- /dev/null
+++ b/src/assets/img/sdjt.jpg
Binary files differ
diff --git a/src/components/tools/Logo.vue b/src/components/tools/Logo.vue
index 43a74f3..48b4230 100644
--- a/src/components/tools/Logo.vue
+++ b/src/components/tools/Logo.vue
@@ -1,15 +1,15 @@
 <template>
   <router-link :to="{ name: 'dashboard' }">
     <div class="flex logo-container flex-center">
-      <!-- <img class="logo-img" :src="@/assets/img/logo.png" alt="logo" /> -->
-      <img v-if="localInfo.logoPath" class="logo-img" :src="localInfo.logoPath" alt="logo" />
-      <img v-else class="logo-img" src="@/assets/img/menuLogo.png" alt="logo" />
+      <img class="logo-img" :src="homeLogo" alt="logo" />
       <!-- <h1 class="logo-title" v-if="showTitle">{{ title }}</h1> -->
     </div>
   </router-link>
 </template>
 
 <script>
+import homeLogo from '@/assets/img/sdjt.jpg'
+
 export default {
   name: 'Logo',
 
@@ -27,11 +27,8 @@
   },
   data() {
     return {
-      localInfo: {},
+      homeLogo,
     }
-  },
-  created() {
-    this.localInfo = JSON.parse(localStorage.getItem('localInfo'))
   },
 }
 </script>
@@ -76,4 +73,3 @@
   }
 }
 </style>
-
diff --git a/src/views/dataAnalysis/components/DataReGasStation.vue b/src/views/dataAnalysis/components/DataReGasStation.vue
index 4056c6a..1748d1a 100644
--- a/src/views/dataAnalysis/components/DataReGasStation.vue
+++ b/src/views/dataAnalysis/components/DataReGasStation.vue
@@ -1,5 +1,5 @@
 <template>
-  <div style="margin-right: 30px" class="data-reMechanism">
+  <div style="margin-right: 30px" class="data-reMechanism" :class="{ 'trend-detail-open': trendDetailVisible }">
     <div style="display: flex; align-items: center">
       <div style="margin-right:12px;font-size:16px;font-weight:bold">瓒嬪娍鍒嗘瀽</div>
       <a-radio-group v-model="trendAnalysisType" @change="trendAnalysisTypeChange">
@@ -12,7 +12,7 @@
       </a-radio-group>
     </div>
     <div>
-      <div style="display: flex; align-items: flex-end; flex-direction: column">
+      <div class="trend-analysis-chart" :class="{ 'is-modal-open': trendDetailVisible }" style="display: flex; align-items: flex-end; flex-direction: column">
         <a-radio-group
           style="margin: 20px 0"
           size="small"
@@ -31,6 +31,8 @@
           :chartData="trendAnalysisData"
           style="width: 100%"
           :showpercent="trendAnalysisChartShowPercent"
+          :enablePointClick="true"
+          @chart-click="handleTrendChartClick"
         ></DataReLineChart>
       </div>
       <div id="trendAnalysisChartID"></div>
@@ -210,6 +212,33 @@
       :typeOneTotal="customerOneTotal"
       :typeTwoTotal="customerTwoTotal"
     ></TopTenCustomers>
+    <a-modal
+      centered
+      width="70%"
+      :footer="null"
+      v-model="trendDetailVisible"
+      :title="trendDetailTitle"
+      :zIndex="5000"
+      :getContainer="getModalContainer"
+      wrapClassName="trend-detail-modal-wrap"
+      @cancel="closeTrendDetail"
+    >
+      <a-table
+        size="middle"
+        bordered
+        :columns="trendDetailColumns"
+        :dataSource="trendDetailData"
+        :loading="trendDetailLoading"
+        :scroll="{ y: 420 }"
+        :pagination="{ pageSize: 10, showSizeChanger: true, pageSizeOptions: ['10', '20', '50'] }"
+        :rowKey="
+          (record, index) => {
+            return record.id || record.licenseNum || record.captureTime || record.startTime || index
+          }
+        "
+      >
+      </a-table>
+    </a-modal>
   </div>
 </template>
 
@@ -264,6 +293,11 @@
       trendAnalysisUnit: 'DAYS', //瓒嬪娍鍒嗘瀽閫夋嫨鏃堕棿
       trendAnalysisData: {}, //瓒嬪娍鍒嗘瀽鏁版嵁
       trendAnalysisChart: null, //瓒嬪娍鍒嗘瀽鍥捐〃
+      trendDetailVisible: false,
+      trendDetailTitle: '瓒嬪娍鍒嗘瀽鏄庣粏',
+      trendDetailLoading: false,
+      trendDetailData: [],
+      trendDetailColumns: [],
       beforeStartTime: '',
       beforeEndTime: '',
       afterStartTime: '',
@@ -310,6 +344,80 @@
 
   methods: {
     moment,
+    getModalContainer() {
+      return document.body
+    },
+    getTrendDetailColumnsByType() {
+      let commonIndexColumn = {
+        title: '搴忓彿',
+        dataIndex: '',
+        key: 'rowIndex',
+        width: 80,
+        align: 'center',
+        customRender: function (t, r, index) {
+          return parseInt(index) + 1
+        },
+      }
+      if (this.trendAnalysisType == 0) {
+        return [
+          commonIndexColumn,
+          { title: '鎶撴媿鏃堕棿', align: 'center', dataIndex: 'captureTime' },
+          { title: '杞︽祦閲�', align: 'center', dataIndex: 'carCount' },
+          { title: '杞﹀瀷缂栫爜', align: 'center', dataIndex: 'modelCode' },
+          { title: '璁惧缂栫爜', align: 'center', dataIndex: 'cameraCode' },
+        ]
+      }
+      if (this.trendAnalysisType == 4 || this.trendAnalysisType == 5) {
+        return [
+          commonIndexColumn,
+          { title: '鏇存柊鏃堕棿', align: 'center', dataIndex: 'updateTimeSelf' },
+          { title: '杞︾墝鍙�', align: 'center', dataIndex: 'licenseNum' },
+          { title: '瀹㈡埛绫诲瀷', align: 'center', dataIndex: 'clientName' },
+          { title: '绱鍔犳补娆℃暟', align: 'center', dataIndex: 'oilCount' },
+          { title: '绱娌瑰搧閿�閲�', align: 'center', dataIndex: 'oilSum' },
+        ]
+      }
+      return [
+        commonIndexColumn,
+        { title: '杩涚珯鏃堕棿', align: 'center', dataIndex: 'startTime' },
+        { title: '杞︾墝鍙�', align: 'center', dataIndex: 'licenseNum' },
+        { title: '琛屼负绫诲瀷', align: 'center', dataIndex: 'behaviorText' },
+        { title: '鍔犳补浣�', align: 'center', dataIndex: 'oilPosition' },
+        { title: '娌瑰搧閿�閲�', align: 'center', dataIndex: 'oilVolume' },
+        { title: '閫氳繃鐜�(鍒�)', align: 'center', dataIndex: 'spandTime' },
+      ]
+    },
+    handleTrendChartClick(params) {
+      if (!params || !params.name) {
+        return
+      }
+      if (this.$refs.trendAnalysisLineRef && this.$refs.trendAnalysisLineRef.hideTooltip) {
+        this.$refs.trendAnalysisLineRef.hideTooltip()
+      }
+      this.trendDetailVisible = true
+      this.trendDetailTitle = '瓒嬪娍鍒嗘瀽鏄庣粏 - ' + params.name
+      this.trendDetailColumns = this.getTrendDetailColumnsByType()
+      this.trendDetailLoading = true
+      postAction('/jyz/dataTable/statTrendDetail', {
+        orgCode: this.selectTreeObj.orgCode,
+        startTime: this.startTime,
+        endTime: this.endTime,
+        trendType: this.trendAnalysisType,
+        timeUnit: this.trendAnalysisUnit,
+        statTime: params.name,
+        seriesName: params.seriesName,
+      })
+        .then((res) => {
+          this.trendDetailData = res.result || []
+        })
+        .finally(() => {
+          this.trendDetailLoading = false
+        })
+    },
+    closeTrendDetail() {
+      this.trendDetailVisible = false
+      this.trendDetailData = []
+    },
     //鑾峰彇杞﹀瀷/鍔犳补浣嶆姌绾垮浘鏁版嵁
     getVehicleTypeLineData() {
       postAction('/jyz/dataTable/statisMidTable', {
@@ -554,7 +662,29 @@
   background: #fff;
 }
 .data-reMechanism {
+  position: relative;
+  isolation: isolate;
+  > div {
+    position: relative;
+    z-index: 2;
+  }
+  > div:nth-child(2) {
+    z-index: 1;
+  }
+  &.trend-detail-open {
+    pointer-events: none;
+  }
+  .trend-analysis-chart {
+    position: relative;
+    z-index: 1;
+    overflow: hidden;
+  }
+  .trend-analysis-chart.is-modal-open {
+    pointer-events: none;
+  }
   .table-operator {
+    position: relative;
+    z-index: 2;
     margin: 24px 0 0 0;
   }
   .block-title {
@@ -562,6 +692,8 @@
     font-size: 16px;
   }
   .fueling-overview-ct {
+    position: relative;
+    z-index: 2;
     // margin: 0 12px;
     .fueling-overview-block {
       display: flex;
@@ -578,6 +710,8 @@
     }
   }
   .oil-freq-compare-ct {
+    position: relative;
+    z-index: 2;
     margin: 8px 12px 24px 12px;
     .oil-freq-compare-operator {
       display: flex;
@@ -597,3 +731,11 @@
   }
 }
 </style>
+<style lang="less">
+.trend-detail-modal-wrap {
+  z-index: 5000 !important;
+}
+.trend-detail-modal-wrap + .ant-modal-mask {
+  z-index: 4999 !important;
+}
+</style>
diff --git a/src/views/dataAnalysis/components/DataReLineChart.vue b/src/views/dataAnalysis/components/DataReLineChart.vue
index 764b5d8..1c698ba 100644
--- a/src/views/dataAnalysis/components/DataReLineChart.vue
+++ b/src/views/dataAnalysis/components/DataReLineChart.vue
@@ -22,13 +22,204 @@
       type: Boolean,
       default: false,
     },
+    enablePointClick: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {
       chartEntity: null,
+      zrClickHandler: null,
+      zrMoveHandler: null,
+      zrMouseOutHandler: null,
+      lastHoverIndex: -1,
+      lastEmitName: '',
+      lastEmitAt: 0,
+      lastLegendToggleAt: 0,
     }
   },
   methods: {
+    getOffsetPoint(event) {
+      if (!event) {
+        return null
+      }
+      if (event.offsetX !== undefined && event.offsetY !== undefined) {
+        return [event.offsetX, event.offsetY]
+      }
+      if (event.event && event.event.offsetX !== undefined && event.event.offsetY !== undefined) {
+        return [event.event.offsetX, event.event.offsetY]
+      }
+      return null
+    },
+    isPointInGrid(point) {
+      if (!this.chartEntity || !this.chartEntity.containPixel || !point) {
+        return false
+      }
+      return this.chartEntity.containPixel({ gridIndex: 0 }, point)
+    },
+    getXData() {
+      return this.chartData && this.chartData.xData ? this.chartData.xData : []
+    },
+    resolveNearestIndexByOffsetX(offsetX) {
+      let xData = this.getXData()
+      if (!this.chartEntity || !this.chartEntity.convertToPixel || !xData.length) {
+        return -1
+      }
+      let nearestIndex = -1
+      let minDistance = Number.MAX_VALUE
+      for (let i = 0; i < xData.length; i++) {
+        let xPixel = this.chartEntity.convertToPixel({ xAxisIndex: 0 }, xData[i])
+        if (Array.isArray(xPixel)) {
+          xPixel = xPixel[0]
+        }
+        if (xPixel === undefined || xPixel === null || Number.isNaN(Number(xPixel))) {
+          continue
+        }
+        let distance = Math.abs(Number(offsetX) - Number(xPixel))
+        if (distance < minDistance) {
+          minDistance = distance
+          nearestIndex = i
+        }
+      }
+      if (nearestIndex === -1) {
+        return -1
+      }
+      return nearestIndex
+    },
+    resolveClickIndex(event, params) {
+      let xData = this.getXData()
+      if (!xData.length) {
+        return -1
+      }
+      let point = this.getOffsetPoint(event)
+      if (!this.isPointInGrid(point)) {
+        return -1
+      }
+      if (params && typeof params.dataIndex === 'number' && xData[params.dataIndex] !== undefined) {
+        return params.dataIndex
+      }
+      if (params && params.name) {
+        let nameIndex = xData.findIndex((item) => item === params.name)
+        if (nameIndex > -1) {
+          return nameIndex
+        }
+      }
+      if (this.chartEntity && this.chartEntity.convertFromPixel && event) {
+        let xAxisValue = this.chartEntity.convertFromPixel({ xAxisIndex: 0 }, [event.offsetX, event.offsetY])
+        if (xAxisValue !== undefined && xAxisValue !== null && !Number.isNaN(Number(xAxisValue))) {
+          let xIndex = Math.round(Number(xAxisValue))
+          if (xIndex >= 0 && xIndex < xData.length) {
+            return xIndex
+          }
+        }
+      }
+      if (event && event.offsetX !== undefined && event.offsetX !== null) {
+        return this.resolveNearestIndexByOffsetX(event.offsetX)
+      }
+      return -1
+    },
+    emitChartClickByIndex(index, seriesName) {
+      let xData = this.getXData()
+      if (index < 0 || index >= xData.length) {
+        return
+      }
+      let clickName = xData[index]
+      let now = Date.now()
+      if (this.lastEmitName === clickName && now - this.lastEmitAt < 120) {
+        return
+      }
+      this.lastEmitName = clickName
+      this.lastEmitAt = now
+      this.$emit('chart-click', {
+        name: clickName,
+        seriesName: seriesName || null,
+      })
+    },
+    hideTooltip() {
+      if (!this.chartEntity) {
+        return
+      }
+      this.chartEntity.dispatchAction({
+        type: 'hideTip',
+      })
+    },
+    bindChartClick() {
+      if (!this.chartEntity) {
+        return
+      }
+      this.chartEntity.off('click')
+      if (this.chartEntity.getZr) {
+        let zr = this.chartEntity.getZr()
+        if (this.zrClickHandler) {
+          zr.off('click', this.zrClickHandler)
+        }
+        if (this.zrMoveHandler) {
+          zr.off('mousemove', this.zrMoveHandler)
+        }
+        if (this.zrMouseOutHandler) {
+          zr.off('globalout', this.zrMouseOutHandler)
+        }
+      }
+      if (!this.enablePointClick) {
+        let chartDom = document.getElementById(this.domId)
+        if (chartDom) {
+          chartDom.style.cursor = 'default'
+        }
+        return
+      }
+      let chartDom = document.getElementById(this.domId)
+      if (chartDom) {
+        chartDom.style.cursor = 'pointer'
+      }
+      this.chartEntity.on('legendselectchanged', () => {
+        this.lastLegendToggleAt = Date.now()
+      })
+      this.chartEntity.on('click', (params) => {
+        if (params && params.componentType === 'legend') {
+          return
+        }
+        if (Date.now() - this.lastLegendToggleAt < 180) {
+          return
+        }
+        let index = this.resolveClickIndex(params && params.event ? params.event : null, params)
+        this.emitChartClickByIndex(index, params ? params.seriesName : null)
+      })
+      this.zrMoveHandler = (event) => {
+        let xData = this.getXData()
+        if (!xData.length) {
+          return
+        }
+        let xIndex = this.resolveClickIndex(event, null)
+        if (xIndex < 0 || xIndex >= xData.length) {
+          return
+        }
+        if (this.lastHoverIndex === xIndex) {
+          return
+        }
+        this.lastHoverIndex = xIndex
+        this.chartEntity.dispatchAction({
+          type: 'showTip',
+          seriesIndex: 0,
+          dataIndex: xIndex,
+        })
+      }
+      this.zrMouseOutHandler = () => {
+        this.lastHoverIndex = -1
+        this.hideTooltip()
+      }
+      this.zrClickHandler = (event) => {
+        if (Date.now() - this.lastLegendToggleAt < 180) {
+          return
+        }
+        let index = this.resolveClickIndex(event, null)
+        this.emitChartClickByIndex(index, null)
+      }
+      let zr = this.chartEntity.getZr()
+      zr.on('mousemove', this.zrMoveHandler)
+      zr.on('globalout', this.zrMouseOutHandler)
+      zr.on('click', this.zrClickHandler)
+    },
     setChart() {
       if (!this.chartEntity) {
         let chartDom = document.getElementById(this.domId)
@@ -38,6 +229,8 @@
       var option = {
         tooltip: {
           trigger: 'axis',
+          confine: true,
+          extraCssText: 'pointer-events:none;',
           axisPointer: {
             // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥
             type: 'line', // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow'
@@ -208,6 +401,7 @@
         ],
       }
       option && this.chartEntity.setOption(option, true)
+      this.bindChartClick()
     },
     setPieUpChart() {
       if (!this.chartEntity) {
@@ -233,6 +427,8 @@
       var option = {
         tooltip: {
           trigger: 'axis',
+          confine: true,
+          extraCssText: 'pointer-events:none;',
           axisPointer: {
             // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥
             type: 'line', // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow'
@@ -291,6 +487,7 @@
         series: [...data],
       }
       option && this.chartEntity.setOption(option, true)
+      this.bindChartClick()
     },
     setOnlyLineChart() {
       if (!this.chartEntity) {
@@ -301,6 +498,8 @@
       var option = {
         tooltip: {
           trigger: 'axis',
+          confine: true,
+          extraCssText: 'pointer-events:none;',
           axisPointer: {
             // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥
             type: 'line', // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow'
@@ -434,6 +633,7 @@
         ],
       }
       option && this.chartEntity.setOption(option, true)
+      this.bindChartClick()
     },
   },
 }
@@ -441,5 +641,7 @@
 <style lang="less" scoped>
 .line-chart {
   height: 20vh;
+  position: relative;
+  overflow: hidden;
 }
 </style>

--
Gitblit v1.8.0