4 Commits 91c3ecd8f4 ... 77d20ff045

Auteur SHA1 Message Date
  jc-wangyt 77d20ff045 #fix 修改字段 il y a 6 jours
  jc-wangyt 36a9d303e0 #add 告警数据驾驶肠接口适配修改 il y a 6 jours
  jc-wangyt f7635ba530 #fix 优化字段 il y a 6 jours
  jc-wangyt 4364fa47ee #fix 修改已知问题 il y a 3 semaines

+ 32 - 0
src/api/newApi/alarm/index.js

@@ -23,3 +23,35 @@ export function exportAlarmData(month) {
     responseType: 'blob'
   })
 }
+
+
+
+
+
+
+/**
+ * 获取告警统计数据
+ * @param {*} month 格式为yyyy-MM
+ * @returns 
+ */
+export function getNewAlarmStats(month) {
+  return request({
+    url: '/dashboard/data?month=' + month,
+    method: 'get'
+  })
+}
+
+
+// /dashboard/export
+/**
+ * 导出告警数据
+ * @param {*} month 格式为yyyy-MM
+ * @returns 
+ */
+export function exportNewAlarmData(month) {
+  return request({
+    url: '/dashboard/export?month=' + month,
+    method: 'get',
+    responseType: 'blob'
+  })
+}

+ 9 - 0
src/api/newApi/driving/index.js

@@ -15,3 +15,12 @@ export function getAlarmDashboard(data) {
         params: data
     })
 }
+
+// /dashboard/dashboard
+export function getDashboardDashboard(data) {
+    return request({
+        url: '/dashboard/dashboard',
+        method: 'get',
+        params: data
+    })
+}

+ 77 - 86
src/views/alarm/index.vue

@@ -4,14 +4,9 @@
       <!-- 顶部操作区 -->
       <div class="operate-area">
         <el-button-group>
-          <!-- <el-button v-for="month in months" :key="month.value"
-            :type="currentMonth === month.value ? 'primary' : 'default'" @click="handleMonthChange(month.value)">
-            {{ month.label }}
-          </el-button> -->
-          <el-select v-model="currentMonth" clearable placeholder="请选择 " @change="handleMonthChange(currentMonth)">
-            <el-option v-for="item in months" :key="item.value" :label="item.label" :value="item.value">
-            </el-option>
-          </el-select>
+          <el-date-picker v-model="currentMonth" type="month" placeholder="选择月" @change="handleMonthChange"
+            value-format="yyyy-MM">
+          </el-date-picker>
         </el-button-group>
         <el-button type="default" @click="handleRefresh">
           <i class="el-icon-refresh"></i> 刷新
@@ -44,39 +39,39 @@
       <div slot="header" class="card-header">
         <span>各系统告警统计</span>
       </div>
-      <el-table :data="systemStatsData" style="width: 100%" v-loading="loadingsystemStats">
-        <el-table-column prop="systemName" label="系统名称" width="120" />
-        <el-table-column prop="totalAlarms" label="告警总数" align="center" />
-        <el-table-column prop="processedAlarms" label="已处理告警总数" align="center" />
-        <el-table-column prop="unprocessedAlarms" label="未处理告警总数" align="center" />
-        <el-table-column prop="contentAlarms" label="内容类告警总数" align="center" />
-        <el-table-column prop="thresholdAlarms" label="阈值类告警总数" align="center" />
-        <el-table-column prop="existenceAlarms" label="存在性告警总数" align="center" />
-
-        <el-table-column prop="indicator_dataNoDeliveredCount" label="数据未送达告警总数" align="center" />
-        <el-table-column prop="indicator_internalConnetCount" label="内部连接性告警总数" align="center" />
-        <el-table-column prop="indicator_interfaceFrequencyCount" label="访问接口频率告警总数" align="center" />
-        <el-table-column prop="indicator_databaseConnectCount" label="数据库连接数告警总数" align="center" />
-        <el-table-column prop="indicator_pageTamperProofCount" label="页面防篡改告警总数" align="center" />
-        <el-table-column prop="indicator_networkBoundaryConnectCount" label="网络边界连通性告警总数" align="center" />
-        <el-table-column prop="indicator_scheduledTaskCount" label="定时任务告警总数" align="center" />
-        <el-table-column prop="indicator_ossUseCount" label="OSS使用情况告警总数" align="center" />
-        <el-table-column prop="indicator_abnormalAccessCount" label="异常访问告警总数" align="center" />
-        <!-- <el-table-column prop="indicator" label="各指标的告警总数" align="center" /> -->
-      </el-table>
+      <div>
+        <el-table :data="systemStatsData" header-align="center" style="width: 100%" stripe
+          v-loading="loadingsystemStats">
+          <el-table-column prop="systemName" label="系统名称" width="120" fixed="left" />
+          <el-table-column prop="totalAlarms" label="告警总数" min-width="120" align="center" />
+          <el-table-column prop="processedCount" label="已处理告警总数" min-width="120" align="center" />
+          <el-table-column prop="untreatedCount" label="未处理告警总数" min-width="120" align="center" />
+          <el-table-column prop="contentAlarms" label="内容类告警" min-width="120" align="center" />
+          <el-table-column prop="thresholdAlarms" label="阈值类告警" min-width="120" align="center" />
+          <el-table-column prop="existenceAlarms" label="存在性告警总数" min-width="120" align="center" />
+          <el-table-column prop="permissionCount" label="用户权限变更监控数量" min-width="120" align="center" />
+          <el-table-column prop="dbCount" label="数据库监控数量" min-width="120" align="center" />
+          <el-table-column prop="connectCount" label="系统内部连接性监控数量" min-width="120" align="center" />
+          <el-table-column prop="ipCount" label="异常IP访问监控数量" min-width="120" align="center" />
+          <el-table-column prop="taskCount" label="定时任务异常情况监控数量" min-width="120" align="center" />
+        </el-table>
+      </div>
     </el-card>
   </div>
 </template>
 
 <script>
-import { getAlarmStats, exportAlarmData } from '@/api/newApi/alarm'
+import { getAlarmStats, exportAlarmData, getNewAlarmStats, exportNewAlarmData } from '@/api/newApi/alarm'
 
 export default {
   data() {
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, '0');
+    const currentMonthValue = `${year}-${month}`;
     return {
-      // monthsSelect: '2026-01',
       loadingsystemStats: false,
-      currentMonth: '2026-01',
+      currentMonth: currentMonthValue,
       months: [],
       alarmData: {//告警统计数据
         overall: {},
@@ -89,47 +84,29 @@ export default {
     overviewData() {
       const overall = this.alarmData.overall || {};
       return [
-        { label: '告警总数', value: overall.total },
-        { label: '已处理告警总数', value: overall.processed },
-        { label: '未处理告警总数', value: overall.unprocessed },
-        { label: '内容类告警总数', value: overall.contentCount },
-        { label: '阈值类告警总数', value: overall.thresholdCount },
-        { label: '存在性告警总数', value: overall.existenceCount }
+        { label: '告警总数', value: overall.totalAlarms },
+        { label: '已处理告警总数', value: overall.totalProcessed },
+        { label: '未处理告警总数', value: overall.totalUntreated },
+        { label: '内容行性告警', value: overall.toralContentAlarms },
+        { label: '阈值类告警', value: overall.totalThresholdAlarms },
+        { label: '存在性告警总数', value: overall.existenceAlarms },
       ];
     },
     // 根据当前选择的月份获取各系统告警统计数据
     systemStatsData() {
       return (this.alarmData.indicatorStats || []).map(item => ({
-        systemName: item.system_name,
-        totalAlarms: item.total,
-        processedAlarms: item.processed,
-        unprocessedAlarms: item.unprocessed,
-        contentAlarms: item.contentCount,
-        thresholdAlarms: item.thresholdCount,
-        existenceAlarms: item.existenceCount,
-        indicator: item.total,
-        dataNoDeliveredCount: item.dataNoDeliveredCount,
-        internalConnectCount: item.internalConnectCount,
-        interfaceFrequencyCount: item.interfaceFrequencyCount,
-        databaseConnectCount: item.databaseConnectCount,
-        pageTamperProofCount: item.pageTamperProofCount,
-        networkBoundaryConnectCount: item.networkBoundaryConnectCount,
-        scheduledTaskCount: item.scheduledTaskCount,
-        ossUseCount: item.indicator_ossUseCount,
-        abnormalAccessCount: item.abnormalAccessCount,
-
-        indicator_abnormalAccessCount: item.indicator_abnormalAccessCount,
-        indicator_dataNoDeliveredCount: item.indicator_dataNoDeliveredCount,
-        indicator_internalConnetCount: item.indicator_internalConnetCount,
-        indicator_interfaceFrequencyCount: item.indicator_interfaceFrequencyCount,
-        indicator_databaseConnectCount: item.indicator_databaseConnectCount,
-        indicator_pageTamperProofCount: item.indicator_pageTamperProofCount,
-        indicator_networkBoundaryConnectCount: item.indicator_networkBoundaryConnectCount,
-        indicator_scheduledTaskCount: item.indicator_scheduledTaskCount,
-        indicator_ossUseCount: item.indicator_ossUseCount,
-
-
-
+        systemName: item.systemName,
+        totalAlarms: item.totalAlarms,
+        processedCount: item.processedCount,
+        untreatedCount: item.untreatedCount,
+        contentAlarms: item.contentAlarms,
+        thresholdAlarms: item.thresholdAlarms,
+        existenceAlarms: item.existenceAlarms,
+        permissionCount: item.permissionCount,
+        dbCount: item.dbCount,
+        connectCount: item.connectCount,
+        ipCount: item.ipCount,
+        taskCount: item.taskCount
       }));
     }
   },
@@ -140,24 +117,34 @@ export default {
     //获取告警统计数据
     getAlarmEven() {
       this.loadingsystemStats = true;
-      getAlarmStats(this.currentMonth).then(res => {
+      getNewAlarmStats(this.currentMonth).then(res => {
+        // getAlarmStats(this.currentMonth).then(res => {
         if (res.code === 200) {
+
           this.alarmData = {
-            overall: res.data.overall || {},
-            indicatorStats: res.data.indicatorStats || []
+            overall: {
+              totalAlarms: res.data.totalAlarms,
+              totalProcessed: res.data.totalProcessed,
+              totalUntreated: res.data.totalUntreated,
+              toralContentAlarms: res.data.toralContentAlarms,
+              totalThresholdAlarms: res.data.totalThresholdAlarms,
+              existenceAlarms: res.data.existenceAlarms
+            },
+            indicatorStats: res.data.systemStats || []
           };
           console.log(this.alarmData, ' this.alarmData')
           // 更新月份列表
-          if (res.data.months && Array.isArray(res.data.months)) {
-            this.months = res.data.months.map(month => {
-              const [year, monthNum] = month.split('-');
-              return {
-                // label: `${monthNum}月`,
-                label: month,
-                value: month
-              };
-            });
-          }
+          // if (res.data.months && Array.isArray(res.data.months)) {
+          //   this.months = res.data.months.map(month => {
+          //      res.data.months=['2026-01','2026-02','2026-03','2026-04','2026-05','2026-06','2026-07','2026-08','2026-09','2026-10','2026-11','2026-12']
+          //     const [year, monthNum] = month.split('-');
+          //     return {
+          //       // label: `${monthNum}月`,
+          //       label: month,
+          //       value: month
+          //     };
+          //   });
+          // }
           this.loadingsystemStats = false;
         } else {
           this.$message.error('获取告警统计数据失败');
@@ -166,10 +153,13 @@ export default {
     },
     // 处理月份切换
     handleMonthChange(month) {
-      console.log(month)
-      this.currentMonth = month;
-      // 切换月份后重新获取数据
-      this.getAlarmEven();
+      console.log('Selected month:', month);
+      // 确保 month 是字符串格式的 YYYY-MM
+      if (month) {
+        this.currentMonth = month;
+        // 切换月份后重新获取数据
+        this.getAlarmEven();
+      }
     },
     // 处理刷新
     handleRefresh() {
@@ -184,8 +174,9 @@ export default {
         spinner: 'el-icon-loading',
         background: 'rgba(0, 0, 0, 0.7)'
       });
-      
-      exportAlarmData(this.currentMonth).then(res => {
+
+      // exportAlarmData(this.currentMonth).then(res => {
+      exportNewAlarmData(this.currentMonth).then(res => {
         // 处理导出成功逻辑
         const blob = new Blob([res], { type: 'application/vnd.ms-excel' });
         const url = window.URL.createObjectURL(blob);

+ 2 - 1
src/views/bizoppmanage/details.vue

@@ -21,7 +21,8 @@
           <el-descriptions-item label="商机单位">{{ currentData.opportunityUnit || '-' }}</el-descriptions-item>
           <el-descriptions-item label="客户需求简介">{{ currentData.customerRequirement || '-' }}</el-descriptions-item>
           <el-descriptions-item label="支撑负责人">{{ currentData.supportPerson || '-' }}</el-descriptions-item>
-          <el-descriptions-item label="支撑部门">{{ currentData.supportUnit || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="支撑部门">{{ currentData.supportDepartment || '-' }}</el-descriptions-item>
+          <el-descriptions-item label="支撑单位">{{ currentData.supportUnit || '-' }}</el-descriptions-item>
         </el-descriptions>
       </div>
     </div>

+ 3 - 3
src/views/bizoppmanage/index.vue

@@ -132,10 +132,10 @@
           </template>
         </el-table-column>
         <el-table-column prop="opportunityOwner" label="商机归属人" min-width="120" align="center"></el-table-column>
-        <el-table-column prop="opportunityUnit" label="商机单位" min-width="80" align="center"></el-table-column>
+        <el-table-column prop="opportunityUnit" label="商机单位" min-width="120" align="center"></el-table-column>
         <el-table-column prop="supportPerson" label="支撑负责人" min-width="120" align="center"></el-table-column>
-        <el-table-column prop="supportUnit" label="支撑单位" min-width="80" align="center"></el-table-column>
-        <el-table-column label="操作" min-width="80" fixed="right">
+        <el-table-column prop="supportUnit" label="支撑单位" min-width="120" align="center"></el-table-column>
+        <el-table-column label="操作" min-width="80" fixed="right" align="center">
           <template slot-scope="scope">
             <el-button type="text" @click="handleDetail(scope.row)">查看详情</el-button>
           </template>

+ 1082 - 0
src/views/driving/index copy.vue

@@ -0,0 +1,1082 @@
+<template>
+  <div class="driving-container" v-loading="loading" element-loading-text="数据加载中..."
+    element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
+    <!-- 页面头部 -->
+    <div class="page-header">
+      <h2>告警数据驾驶舱</h2>
+      <div class="header-right">
+        <el-date-picker disabled v-model="currentDate" type="datetime" placeholder="选择日期时间" format="yyyy-MM-dd HH:mm:ss"
+          value-format="yyyy-MM-dd HH:mm:ss" style="width: 200px; margin-right: 10px">
+        </el-date-picker>
+        <el-button type="primary" icon="el-icon-refresh" @click="refreshData">刷新</el-button>
+        <!-- <el-checkbox v-model="autoRefresh" style="margin-left: 10px">自动刷新</el-checkbox> -->
+      </div>
+    </div>
+
+    <!-- 第一行:指标分类数据获取情况 + 实时告警列表 + 七日告警数据分布 -->
+    <div class="row row-1">
+      <!-- 指标分类数据获取情况 -->
+      <div class="col col-1">
+        <div class="card">
+          <div class="card-header">
+            <h3>指标分类数据获取情况</h3>
+          </div>
+          <div class="card-body">
+            <div class="category-charts-container">
+              <div class="chart-item">
+                <div ref="contentChart" class="chart"></div>
+                <div class="chart-title">内容类</div>
+              </div>
+              <div class="chart-item">
+                <div ref="thresholdChart" class="chart"></div>
+                <div class="chart-title">阈值类</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 实时告警列表 -->
+      <div class="col col-2">
+        <div class="card">
+          <div class="card-header">
+            <h3>实时告警列表</h3>
+          </div>
+          <div class="card-body">
+            <div class="alarm-list" ref="alarmList">
+              <div class="alarm-items-container">
+                <div v-for="alarm in realTimeAlarms" :key="alarm.id" class="alarm-item">
+                  <div class="alarm-indicator">{{ alarm.indicator }}</div>
+                  <div class="alarm-time">{{ alarm.occurTime }}/{{ alarm.alarmType }}</div>
+                  <div class="alarm-status">
+                    <el-tag type="danger"> 未处理 </el-tag>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 七日告警数据分布 -->
+      <div class="col col-3">
+        <div class="card">
+          <div class="card-header">
+            <h3>七日告警数据分布</h3>
+          </div>
+          <div class="card-body">
+            <!-- <div class="total-alarms">
+              <div class="total-label">七日内总告警数</div>
+              <div class="total-count">{{this.alarmDistribution.reduce((acc, item) => acc + item.value, 0)}}</div>
+            </div> -->
+            <div class="chart-wrapper">
+              <div ref="distributionChart"></div>
+            </div>
+            <!-- <div class="legend">
+              <div v-for="item in alarmDistribution" :key="item.name" class="legend-item">
+                <span class="legend-color" :style="{ backgroundColor: item.color }"></span>
+                <span class="legend-text">{{ item.name }}: {{ item.value }}%</span>
+              </div>
+            </div> -->
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 第二行:七日告警趋势分析 + 各系统七日告警 -->
+    <div class="row row-2">
+      <!-- 七日告警趋势分析 -->
+      <div class="col col-4">
+        <div class="card">
+          <div class="card-header">
+            <h3>七日告警趋势分析</h3>
+          </div>
+          <div class="card-body">
+            <div class="chart-wrapper">
+              <div ref="trendChart"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 各系统七日告警 -->
+      <div class="col col-5">
+        <div class="card">
+          <div class="card-header">
+            <h3>各系统七日告警</h3>
+          </div>
+          <div class="card-body">
+            <div class="chart-wrapper">
+              <div ref="systemChart"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+// import { getRealTimeAlarm, getAlarmDashboard } from '@/api/newApi/driving'
+import { getDashboardDashboard } from '@/api/newApi/driving'
+
+export default {
+  data() {
+    return {
+      currentDate: new Date(),
+      autoRefresh: false,
+      refreshInterval: null,
+      activeCategoryTab: 'content',
+
+
+      loading: true,//全局加载状态
+      realTimeAlarms: [],//实时告警列表
+
+
+      sevenDayTotalAlarms: 365,
+
+      distributionLegend: [
+        { name: 'CPU使用率', value: 30, color: '#5470c6' },
+        { name: '内存使用率', value: 25, color: '#91cc75' },
+        { name: '磁盘空间', value: 20, color: '#fac858' },
+        { name: '网络延迟', value: 15, color: '#ee6666' },
+        { name: '服务可用性', value: 10, color: '#73c0de' }
+      ],
+
+      // 图表实例
+      charts: {},
+
+
+      alarmDistribution: [],//告警分布
+      indicatorStatus: [],//指标状态 - 内容类
+      thresholdStatus: [],//指标状态 - 阈值类
+
+      alarmTrend: [],//七日告警趋势分析
+      systemAlarms: [],//各系统七日告警
+    }
+  },
+  mounted() {
+
+    this.initCharts()
+    // 只有在autoRefresh为true时才启动自动刷新
+    if (this.autoRefresh) {
+      this.startAutoRefresh()
+    }
+  },
+  beforeDestroy() {
+    this.stopAutoRefresh()
+    this.destroyCharts()
+  },
+  watch: {
+    autoRefresh(val) {
+      if (val) {
+        this.startAutoRefresh()
+      } else {
+        this.stopAutoRefresh()
+      }
+    }
+  },
+  methods: {
+    // async getRealEvent() {
+    //   // 初始化实时告警列表
+    //   try {
+    //     const res = await getRealTimeAlarm()
+    //     if (res.code === 200) {
+    //       this.realTimeAlarms = res.data || []
+    //     }
+    //   } catch (error) {
+    //     console.error('获取实时告警失败:', error)
+    //   }
+    // },
+    async initCharts() {
+      this.loading = true
+      try {
+        await this.getAlarmEvent()
+        this.initCategoryCharts()
+        this.initDistributionChart()
+        // this.initTrendChart()
+        this.initSystemChart()
+        // await this.getRealEvent()
+      } finally {
+        this.loading = false
+      }
+    },
+    async getAlarmEvent() {
+      try {
+        // const res = await getAlarmDashboard()
+        const res = await getDashboardDashboard()
+        if (res) {
+          console.log('告警数据驾驶舱全量数据:', res)
+          let resData = res.data
+          // if (res.alarmDistribution && res.alarmDistribution.length > 0) {
+          //   this.alarmDistribution = res.alarmDistribution.map(item => ({
+          //     value: item.count,
+          //     name: item.indicator,
+          //   }))
+          //   console.log(this.alarmDistribution)
+          // }
+          if (resData.metricCategory) {
+            this.indicatorStatus = resData.metricCategory.content
+            console.log(this.indicatorStatus)
+            console.log('按类型分组的指标状态:', this.indicatorStatus)
+          }
+          if (resData.alarmTrend && resData.alarmTrend.length > 0) {
+            // 按照type分类
+            const groupedTrend = {}
+            resData.alarmTrend.forEach(item => {
+              if (!groupedTrend[item.type]) {
+                groupedTrend[item.type] = []
+              }
+              groupedTrend[item.type].push({
+                value: item.count,
+                name: item.date,
+                type: item.type,
+              })
+            })
+            this.alarmTrend = groupedTrend
+            console.log('按类型分组的告警趋势:', this.alarmTrend)
+          }
+          if (resData.systemAlarms && resData.systemAlarms.length > 0) {
+            // 按照systemName分类
+            const groupedSystem = {}
+            resData.systemAlarms.forEach(item => {
+              if (!groupedSystem[item.systemName]) {
+                groupedSystem[item.systemName] = {}
+              }
+              groupedSystem[item.systemName][item.type] = item.count
+            })
+            this.systemAlarms = groupedSystem
+            console.log('按系统分组的系统告警:', this.systemAlarms)
+          }
+        }
+      } catch (error) {
+        console.error('获取告警数据失败:', error)
+      }
+    },
+    initCategoryCharts() {
+      // 同时初始化内容类和阈值类图表
+      this.initCategoryChart('content')
+      this.initCategoryChart('threshold')
+    },
+
+    initDistributionChart() {
+      const chartRef = this.$refs.distributionChart
+      // console.log('初始化分布图表:', chartRef)
+      if (!chartRef) {
+        console.error('未找到分布图表引用')
+        return
+      }
+
+      // 确保容器有正确的尺寸
+      chartRef.style.width = '100%'
+      chartRef.style.height = '100%'
+      chartRef.style.minHeight = '200px'
+
+      try {
+        const distributionChart = echarts.init(chartRef)
+        // console.log('分布图表初始化成功')
+        distributionChart.setOption({
+          tooltip: {
+            trigger: 'item',
+            formatter: '{a} <br/>{b}: {c} ({d}%)'
+          },
+          legend: {
+            orient: 'vertical',
+            left: 'right'
+          },
+          series: [
+            {
+              name: '告警分布',
+              type: 'pie',
+              radius: ['40%', '70%'],
+              center: ['25%', '50%'],
+              label: {
+                show: true,
+                position: 'center',
+                formatter: function () {
+                  const total = this.alarmDistribution.reduce((sum, item) => sum + item.value, 0);
+                  return total + '\n七日告警数分布';
+                }.bind(this),
+                fontSize: 16,
+              },
+              data: this.alarmDistribution,
+              emphasis: {
+                itemStyle: {
+                  shadowBlur: 10,
+                  shadowOffsetX: 0,
+                  shadowColor: 'rgba(0, 0, 0, 0.5)'
+                }
+              }
+            }
+          ]
+        })
+        this.charts.distributionChart = distributionChart
+        // console.log('分布图表配置设置成功')
+      } catch (error) {
+        console.error('初始化分布图表时出错:', error)
+      }
+    },
+
+    initTrendChart() {
+      const chartRef = this.$refs.trendChart
+      // console.log('初始化趋势图表:', chartRef)
+      if (!chartRef) {
+        console.error('未找到趋势图表引用')
+        return
+      }
+
+      // 确保容器有正确的尺寸
+      chartRef.style.width = '100%'
+      chartRef.style.height = '100%'
+      chartRef.style.minHeight = '200px'
+
+      try {
+        const trendChart = echarts.init(chartRef)
+        // console.log('趋势图表初始化成功')
+        trendChart.setOption({
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'cross',
+              label: {
+                backgroundColor: '#6a7985'
+              }
+            }
+          },
+          legend: {
+            data: Object.keys(this.alarmTrend)
+          },
+
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            containLabel: true
+          },
+          xAxis: [
+            {
+              type: 'category',
+              boundaryGap: false,
+              data: [...new Set(Object.values(this.alarmTrend).flat().map(item => item.name))]
+            }
+          ],
+          yAxis: [
+            {
+              type: 'value'
+            }
+          ],
+          // dataZoom: [
+          //   {
+          //     type: 'slider',
+          //     orient: 'horizontal',
+          //     xAxisIndex: 0,
+          //     start: 0,
+          //     end: 50
+          //   }
+          // ],
+          series: [
+            {
+              name: '内容类',
+              type: 'line',
+              stack: 'Total',
+              areaStyle: {},
+              emphasis: {
+                focus: 'series'
+              },
+              data: (this.alarmTrend['内容类'] || []).map(item => item.value),
+              lineStyle: {
+                color: '#ee6666'
+              },
+              itemStyle: {
+                color: '#ee6666'
+              }
+            },
+            {
+              name: '阈值类',
+              type: 'line',
+              stack: 'Total',
+              areaStyle: {},
+              emphasis: {
+                focus: 'series'
+              },
+              data: (this.alarmTrend['阈值类'] || []).map(item => item.value),
+              lineStyle: {
+                color: '#5470c6'
+              },
+              itemStyle: {
+                color: '#5470c6'
+              }
+            },
+            {
+              name: '存在性',
+              type: 'line',
+              stack: 'Total',
+              areaStyle: {},
+              emphasis: {
+                focus: 'series'
+              },
+              data: this.alarmTrend['存在性'].map(item => item.value),
+              lineStyle: {
+                color: '#91cc75'
+              },
+              itemStyle: {
+                color: '#91cc75'
+              }
+            }
+          ]
+        })
+        this.charts.trendChart = trendChart
+        // console.log('趋势图表配置设置成功')
+      } catch (error) {
+        console.error('初始化趋势图表时出错:', error)
+      }
+    },
+
+    initSystemChart() {
+      const chartRef = this.$refs.systemChart
+      // console.log('初始化系统图表:', chartRef)
+      if (!chartRef) {
+        console.error('未找到系统图表引用')
+        return
+      }
+
+      // 确保容器有正确的尺寸
+      chartRef.style.width = '100%'
+      chartRef.style.height = '100%'
+      chartRef.style.minHeight = '200px'
+
+      try {
+        const systemChart = echarts.init(chartRef)
+        // console.log('系统图表初始化成功')
+        systemChart.setOption({
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'shadow'
+            }
+          },
+          legend: {
+            data: ['内容类', '阈值类', '存在性']
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            containLabel: true
+          },
+          xAxis: [
+            {
+              type: 'category',
+              data: Object.keys(this.systemAlarms || {})
+            }
+          ],
+          yAxis: [
+            {
+              type: 'value'
+            }
+          ],
+          dataZoom: [
+            {
+              type: 'slider',
+              orient: 'horizontal',
+              xAxisIndex: 0,
+              start: 0,
+              end: 50
+            }
+          ],
+          series: [
+            {
+              name: '内容类',
+              type: 'bar',
+              emphasis: {
+                focus: 'series'
+              },
+              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['内容类'] || 0),
+              itemStyle: {
+                color: '#ee6666'
+              }
+            },
+            {
+              name: '阈值类',
+              type: 'bar',
+              emphasis: {
+                focus: 'series'
+              },
+              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['阈值类'] || 0),
+              itemStyle: {
+                color: '#5470c6'
+              }
+            },
+            {
+              name: '存在性',
+              type: 'bar',
+              emphasis: {
+                focus: 'series'
+              },
+              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['存在性'] || 0),
+              itemStyle: {
+                color: '#91cc75'
+              }
+            }
+          ]
+        })
+        this.charts.systemChart = systemChart
+        // console.log('系统图表配置设置成功')
+      } catch (error) {
+        console.error('初始化系统图表时出错:', error)
+      }
+    },
+
+    handleTabClick(tab) {
+      // 当切换选项卡时,确保图表能够正确显示
+      setTimeout(() => {
+        // 无论之前是否存在图表实例,都重新初始化图表
+        if (tab.name === 'content' && this.$refs.contentChart) {
+          // 销毁旧图表实例
+          if (this.charts.contentChart) {
+            this.charts.contentChart.dispose()
+            this.charts.contentChart = null
+          }
+          // 创建新图表实例
+          this.initCategoryChart('content')
+        } else if (tab.name === 'threshold' && this.$refs.thresholdChart) {
+          // 销毁旧图表实例
+          if (this.charts.thresholdChart) {
+            this.charts.thresholdChart.dispose()
+            this.charts.thresholdChart = null
+          }
+          // 创建新图表实例
+          this.initCategoryChart('threshold')
+        } else if (tab.name === 'existence' && this.$refs.existenceChart) {
+          // 销毁旧图表实例
+          if (this.charts.existenceChart) {
+            this.charts.existenceChart.dispose()
+            this.charts.existenceChart = null
+          }
+          // 创建新图表实例
+          this.initCategoryChart('existence')
+        }
+      }, 100)
+    },
+
+    initCategoryChart(type) {
+      // 初始化单个分类图表
+      const chartRef = this.$refs[`${type}Chart`]
+      // console.log('初始化图表类型:', type, '图表引用:', chartRef)
+      if (!chartRef) {
+        console.error('未找到图表引用,类型:', type)
+        return
+      }
+
+      // 确保容器有正确的尺寸
+      chartRef.style.width = '100%'
+      chartRef.style.height = '100%'
+      chartRef.style.minHeight = '200px'
+
+      try {
+        const chart = echarts.init(chartRef)
+        // console.log('图表初始化成功:', type)
+        let option = {}
+
+        if (type === 'content') {
+          option = {
+            tooltip: {
+              trigger: 'item',
+              formatter: '{a} <br/>{b}: {c} ({d}%)'
+            },
+            legend: {
+              orient: 'horizontal',
+              bottom: 0,
+              data: ['正常', '无数据', '未配置'],
+              width: '100%',
+              itemWidth: 10,
+              itemHeight: 10,
+              textStyle: {
+                fontSize: 12
+              }
+            },
+            series: [
+              {
+                name: '内容类',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: false,
+                itemStyle: {
+                  borderRadius: 0,
+                  borderColor: '#fff',
+                  borderWidth: 0
+                },
+                label: {
+                  show: false
+                },
+                emphasis: {
+                  label: {
+                    show: false
+                  }
+                },
+                labelLine: {
+                  show: false
+                },
+                data:
+                  this.indicatorStatus,
+                color: ['#F44336', '#BDBDBD', '#8BC34A']
+              }
+            ]
+          }
+        } else if (type === 'threshold') {
+          option = {
+            tooltip: {
+              trigger: 'item',
+              formatter: '{a} <br/>{b}: {c} ({d}%)'
+            },
+            legend: {
+              orient: 'horizontal',
+              bottom: 0,
+              data: ['正常', '无数据', '未配置'],
+              width: '100%',
+              itemWidth: 10,
+              itemHeight: 10,
+              textStyle: {
+                fontSize: 12
+              }
+            },
+            series: [
+              {
+                name: '阈值类',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: false,
+                itemStyle: {
+                  borderRadius: 0,
+                  borderColor: '#fff',
+                  borderWidth: 0
+                },
+                label: {
+                  show: false
+                },
+                emphasis: {
+                  label: {
+                    show: false
+                  }
+                },
+                labelLine: {
+                  show: false
+                },
+                data:
+                  this.indicatorStatus['阈值类'] || [
+                    { value: 4, name: '正常' },
+                    { value: 0, name: '无数据' },
+                    { value: 6, name: '未配置' }
+                  ],
+                color: ['#F44336', '#BDBDBD', '#8BC34A']
+
+              }
+            ]
+          }
+        } else if (type === 'existence') {
+          option = {
+            tooltip: {
+              trigger: 'item',
+              formatter: '{a} <br/>{b}: {c} ({d}%)'
+            },
+            legend: {
+              orient: 'vertical',
+              left: 10,
+              data: ['正常', '无数据', '未配置']
+            },
+            series: [
+              {
+                name: '存在性',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: false,
+                itemStyle: {
+                  borderRadius: 10,
+                  borderColor: '#fff',
+                  borderWidth: 2
+                },
+                label: {
+                  show: false,
+                  position: 'center'
+                },
+                emphasis: {
+                  label: {
+                    show: true,
+                    fontSize: '18',
+                    fontWeight: 'bold'
+                  }
+                },
+                labelLine: {
+                  show: false
+                },
+                data: this.indicatorStatus['存在性']
+              }
+            ]
+          }
+        }
+
+        if (option && chart) {
+          chart.setOption(option)
+          this.charts[`${type}Chart`] = chart
+          // console.log('图表配置设置成功:', type)
+        }
+      } catch (error) {
+        console.error('初始化图表时出错:', type, error)
+      }
+    },
+
+    async refreshData() {
+      // 模拟数据刷新
+      console.log('刷新数据...')
+      this.currentDate = new Date().toISOString().slice(0, 19).replace('T', ' ')
+      this.loading = true
+
+      try {
+        // 随机更新实时告警列表
+        await this.getRealEvent()
+
+        // 重新初始化图表以确保正确显示
+        this.destroyCharts()
+        await this.initCharts()
+      } finally {
+        this.loading = false
+      }
+    },
+
+    startAutoRefresh() {
+      this.stopAutoRefresh()
+      this.refreshInterval = setInterval(() => {
+        this.refreshData()
+      }, 5000)
+    },
+
+    stopAutoRefresh() {
+      if (this.refreshInterval) {
+        clearInterval(this.refreshInterval)
+        this.refreshInterval = null
+      }
+    },
+
+    resizeCharts() {
+      Object.values(this.charts).forEach(chart => {
+        chart.resize()
+      })
+    },
+
+    destroyCharts() {
+      Object.values(this.charts).forEach(chart => {
+        chart.dispose()
+      })
+    },
+
+    formatTime(date) {
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      const hours = String(date.getHours()).padStart(2, '0')
+      const minutes = String(date.getMinutes()).padStart(2, '0')
+      return `${year}-${month}-${day} ${hours}:${minutes}`
+    }
+  }
+}
+</script>
+
+<style scoped>
+.driving-container {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+  height: 100vh;
+  box-sizing: border-box;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 15px 20px;
+  background-color: #ffffff;
+  border-radius: 4px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.page-header h2 {
+  margin: 0;
+  color: #303133;
+}
+
+.header-right {
+  display: flex;
+  align-items: center;
+}
+
+.row {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+  flex: 1;
+  min-height: 0;
+}
+
+.row-1 {
+  flex: 1;
+  min-height: 300px;
+}
+
+.row-2 {
+  flex: 1;
+  min-height: 350px;
+}
+
+.col {
+  background-color: #ffffff;
+  border-radius: 4px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+  overflow: hidden;
+  flex: 1;
+  min-width: 0;
+}
+
+.category-charts-container {
+  display: flex;
+  gap: 20px;
+  padding: 10px;
+  height: 100%;
+  min-height: 250px;
+}
+
+.chart-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 100%;
+}
+
+.chart {
+  width: 100%;
+  height: 100%;
+  min-height: 200px;
+}
+
+.chart-title {
+  margin-top: 10px;
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+  display: flex;
+  flex-direction: column;
+}
+
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5 {
+  flex: 1;
+}
+
+.card {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+}
+
+.card-header {
+  padding: 15px 20px;
+  border-bottom: 1px solid #ebeef5;
+  background-color: #fafafa;
+  flex-shrink: 0;
+}
+
+.card-header h3 {
+  margin: 0;
+  font-size: 16px;
+  color: #303133;
+}
+
+.card-body {
+  flex: 1;
+  padding: 20px;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+}
+
+.el-tabs {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.el-tabs__header {
+  flex-shrink: 0;
+}
+
+.el-tabs__content {
+  flex: 1;
+  overflow: hidden;
+  display: flex;
+}
+
+.el-tab-pane {
+  flex: 1;
+  display: flex;
+}
+
+.chart-wrapper {
+  flex: 1;
+  min-height: 200px;
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.chart-wrapper>div {
+  width: 100%;
+  height: 100%;
+  min-height: 200px;
+}
+
+.alarm-list {
+  flex: 1;
+  overflow: hidden;
+  position: relative;
+}
+
+.alarm-items-container {
+  height: 100%;
+  animation: scroll 20s linear infinite;
+}
+
+.alarm-item {
+  display: flex;
+  align-items: center;
+  padding: 10px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.alarm-indicator {
+  flex: 1;
+  font-weight: 500;
+}
+
+.alarm-time {
+  width: 180px;
+  font-size: 12px;
+  color: #909399;
+}
+
+.alarm-status {
+  width: 80px;
+  text-align: right;
+}
+
+.total-alarms {
+  text-align: center;
+  margin-bottom: 20px;
+}
+
+.total-label {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 5px;
+}
+
+.total-count {
+  font-size: 36px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.legend {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  margin-top: 10px;
+}
+
+.legend-item {
+  display: flex;
+  align-items: center;
+  font-size: 12px;
+}
+
+.legend-color {
+  width: 12px;
+  height: 12px;
+  border-radius: 2px;
+  margin-right: 5px;
+}
+
+@keyframes scroll {
+  0% {
+    transform: translateY(0);
+  }
+
+  100% {
+    transform: translateY(-100%);
+  }
+}
+
+/* 响应式设计 */
+@media screen and (max-width: 1200px) {
+  .driving-container {
+    height: auto;
+    min-height: 100vh;
+    overflow: auto;
+  }
+
+  .row {
+    flex-direction: column;
+    height: auto;
+    min-height: 400px;
+  }
+
+  .row-1,
+  .row-2 {
+    min-height: 400px;
+  }
+
+  .col {
+    min-height: 400px;
+    margin-bottom: 20px;
+  }
+
+  .chart-wrapper {
+    min-height: 300px;
+  }
+}
+
+@media screen and (max-width: 768px) {
+  .page-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 10px;
+  }
+
+  .header-right {
+    width: 100%;
+    justify-content: space-between;
+  }
+
+  .driving-container {
+    padding: 10px;
+  }
+
+  .card-body {
+    padding: 15px;
+  }
+
+  .chart-wrapper {
+    min-height: 250px;
+  }
+}
+</style>

+ 309 - 0
src/views/driving/index.txt

@@ -0,0 +1,309 @@
+{
+    "msg": "操作成功",
+    "code": 200,
+    "data": {
+        "metricCategory": {
+            "content": {
+                "totalSystems": 5,
+                "configuredCount": 0,
+                "unconfiguredCount": 5,
+                "noDataCount": 0
+            },
+            "threshold": {
+                "totalSystems": 5,
+                "configuredCount": 0,
+                "unconfiguredCount": 5,
+                "noDataCount": 0
+            }
+        },
+        "alarmList": [
+            {
+                "monitorName": "数据库监控",
+                "tableName": "cus_db_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 22:55:00",
+                "category": "内容类"
+            },
+            {
+                "monitorName": "数据库监控",
+                "tableName": "cus_db_monitor",
+                "systemId": "2e319c",
+                "systemName": "系统2",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 18:55:00",
+                "category": "内容类"
+            },
+            {
+                "monitorName": "数据库监控",
+                "tableName": "cus_db_monitor",
+                "systemId": "2e319c",
+                "systemName": "系统2",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 16:55:00",
+                "category": "内容类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "定时任务异常监控",
+                "tableName": "cus_task_exception_monitor",
+                "systemId": "2e319c",
+                "systemName": "系统2",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "systemId": "4c984c",
+                "systemName": "系统5",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "systemId": "1631b4",
+                "systemName": "系统1",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "systemId": "4c984c",
+                "systemName": "系统5",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "systemId": "4c984c",
+                "systemName": "系统5",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "定时任务异常监控",
+                "tableName": "cus_task_exception_monitor",
+                "systemId": "1631b4",
+                "systemName": "系统1",
+                "alarmStatus": "untreated",
+                "triggerTime": "2026-02-12 15:55:19",
+                "category": "阈值类"
+            }
+        ],
+        "monitorPointCounts": [
+            {
+                "monitorName": "数据库监控",
+                "tableName": "cus_db_monitor",
+                "count": 0,
+                "category": "内容类"
+            },
+            {
+                "monitorName": "用户权限变更监控",
+                "tableName": "sec_permission_monitor",
+                "count": 0,
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "系统内部连接性监控",
+                "tableName": "cus_internal_connect_monitor",
+                "count": 0,
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "异常IP访问监控",
+                "tableName": "cus_ip_abnormal_monitor",
+                "count": 0,
+                "category": "阈值类"
+            },
+            {
+                "monitorName": "定时任务异常监控",
+                "tableName": "cus_task_exception_monitor",
+                "count": 0,
+                "category": "阈值类"
+            }
+        ],
+        "trend": {
+            "dates": [
+                "02-18",
+                "02-19",
+                "02-20",
+                "02-21",
+                "02-22",
+                "02-23",
+                "02-24"
+            ],
+            "contentCounts": [
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0
+            ],
+            "thresholdCounts": [
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0
+            ],
+            "existenceCounts": [
+                528,
+                528,
+                528,
+                528,
+                528,
+                528,
+                528
+            ]
+        },
+        "systemCategories": [
+            {
+                "systemId": "1631b4",
+                "systemName": "系统1",
+                "contentCount": 0,
+                "thresholdCount": 0,
+                "existenceCount": 840
+            },
+            {
+                "systemId": "2e319c",
+                "systemName": "系统2",
+                "contentCount": 0,
+                "thresholdCount": 0,
+                "existenceCount": 336
+            },
+            {
+                "systemId": "4c984c",
+                "systemName": "系统5",
+                "contentCount": 0,
+                "thresholdCount": 0,
+                "existenceCount": 840
+            },
+            {
+                "systemId": "7c110d",
+                "systemName": "系统4",
+                "contentCount": 0,
+                "thresholdCount": 0,
+                "existenceCount": 840
+            },
+            {
+                "systemId": "e6a6e3",
+                "systemName": "系统3",
+                "contentCount": 0,
+                "thresholdCount": 0,
+                "existenceCount": 840
+            }
+        ]
+    }
+}

+ 118 - 161
src/views/driving/index.vue

@@ -1,5 +1,6 @@
 <template>
-  <div class="driving-container">
+  <div class="driving-container" v-loading="loading" element-loading-text="数据加载中..."
+    element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
     <!-- 页面头部 -->
     <div class="page-header">
       <h2>告警数据驾驶舱</h2>
@@ -117,7 +118,8 @@
 
 <script>
 import * as echarts from 'echarts'
-import { getRealTimeAlarm, getAlarmDashboard } from '@/api/newApi/driving'
+// import { getRealTimeAlarm, getAlarmDashboard } from '@/api/newApi/driving'
+import { getDashboardDashboard } from '@/api/newApi/driving'
 
 export default {
   data() {
@@ -128,27 +130,21 @@ export default {
       activeCategoryTab: 'content',
 
 
+      loading: true,//全局加载状态
       realTimeAlarms: [],//实时告警列表
 
 
       sevenDayTotalAlarms: 365,
-
-      distributionLegend: [
-        { name: 'CPU使用率', value: 30, color: '#5470c6' },
-        { name: '内存使用率', value: 25, color: '#91cc75' },
-        { name: '磁盘空间', value: 20, color: '#fac858' },
-        { name: '网络延迟', value: 15, color: '#ee6666' },
-        { name: '服务可用性', value: 10, color: '#73c0de' }
-      ],
-
       // 图表实例
       charts: {},
 
 
       alarmDistribution: [],//告警分布
-      indicatorStatus: [],//指标状态
-      alarmTrend: [],//七日告警趋势分析
-      systemAlarms: [],//各系统七日告警
+      metricCategory: {},//指标分类数据
+      alarmList: [],//告警列表
+      monitorPointCounts: [],//监测点数量
+      trend: {},//趋势数据
+      systemCategories: [],//系统分类数据
     }
   },
   mounted() {
@@ -173,79 +169,70 @@ export default {
     }
   },
   methods: {
-    getRealEvent() {
-      // 初始化实时告警列表
-      getRealTimeAlarm().then(res => {
-        if (res.code === 200) {
-          this.realTimeAlarms = res.data || []
-        }
-      })
-    },
     async initCharts() {
-      await this.getAlarmEvent()
-      this.initCategoryCharts()
-      this.initDistributionChart()
-      this.initTrendChart()
-      this.initSystemChart()
-      this.getRealEvent()
+      this.loading = true
+      try {
+        await this.getAlarmEvent()
+        this.initCategoryCharts()
+        this.initDistributionChart()
+        this.initTrendChart()
+        this.initSystemChart()
+      } finally {
+        this.loading = false
+      }
     },
     async getAlarmEvent() {
       try {
-        const res = await getAlarmDashboard()
-        if (res) {
+        // const res = await getAlarmDashboard()
+        const res = await getDashboardDashboard()
+        if (res && res.code === 200) {
           console.log('告警数据驾驶舱全量数据:', res)
-          if (res.alarmDistribution && res.alarmDistribution.length > 0) {
-            this.alarmDistribution = res.alarmDistribution.map(item => ({
-              value: item.count,
-              name: item.indicator,
+          let resData = res.data
+
+          // 指标分类数据
+          if (resData.metricCategory) {
+            this.metricCategory = resData.metricCategory
+            console.log('指标分类数据:', this.metricCategory)
+          }
+
+          // 告警列表
+          if (resData.alarmList && resData.alarmList.length > 0) {
+            this.alarmList = resData.alarmList
+            console.log('告警列表:', this.alarmList)
+            // 处理实时告警列表
+            this.realTimeAlarms = resData.alarmList.map(alarm => ({
+              indicator: alarm.monitorName,
+              occurTime: alarm.triggerTime,
+              alarmType: alarm.category,
+              status: alarm.alarmStatus
             }))
-            console.log(this.alarmDistribution)
           }
-          if (res.indicatorStatus && res.indicatorStatus.length > 0) {
-            // 根据type分类
-            const groupedData = {}
-            res.indicatorStatus.forEach(item => {
-              if (!groupedData[item.type]) {
-                groupedData[item.type] = []
-              }
-              groupedData[item.type].push({
-                value: item.count,
-                type: item.type,
-                name: item.situation
-              })
-            })
-            this.indicatorStatus = groupedData
-            console.log(this.indicatorStatus['内容类'])
-            console.log('按类型分组的指标状态:', this.indicatorStatus)
+
+          // 监测点数量
+          if (resData.monitorPointCounts && resData.monitorPointCounts.length > 0) {
+            this.monitorPointCounts = resData.monitorPointCounts
+            console.log('监测点数量:', this.monitorPointCounts)
           }
-          if (res.alarmTrend && res.alarmTrend.length > 0) {
-            // 按照type分类
-            const groupedTrend = {}
-            res.alarmTrend.forEach(item => {
-              if (!groupedTrend[item.type]) {
-                groupedTrend[item.type] = []
-              }
-              groupedTrend[item.type].push({
-                value: item.count,
-                name: item.date,
-                type: item.type,
-              })
-            })
-            this.alarmTrend = groupedTrend
-            console.log('按类型分组的告警趋势:', this.alarmTrend)
+
+          // 趋势数据
+          if (resData.trend) {
+            this.trend = resData.trend
+            console.log('趋势数据:', this.trend)
           }
-          if (res.systemAlarms && res.systemAlarms.length > 0) {
-            // 按照systemName分类
-            const groupedSystem = {}
-            res.systemAlarms.forEach(item => {
-              if (!groupedSystem[item.systemName]) {
-                groupedSystem[item.systemName] = {}
-              }
-              groupedSystem[item.systemName][item.type] = item.count
-            })
-            this.systemAlarms = groupedSystem
-            console.log('按系统分组的系统告警:', this.systemAlarms)
+
+          // 系统分类数据
+          if (resData.systemCategories && resData.systemCategories.length > 0) {
+            this.systemCategories = resData.systemCategories
+            console.log('系统分类数据:', this.systemCategories)
           }
+
+          // 告警分布
+          this.alarmDistribution = resData.monitorPointCounts.map(item => ({
+            value: item.count,
+            name: item.monitorName,
+          }))
+
+          this.sevenDayTotalAlarms = resData.monitorPointCounts.reduce((acc, cur) => acc + cur.count, 0)
         }
       } catch (error) {
         console.error('获取告警数据失败:', error)
@@ -292,12 +279,15 @@ export default {
                 show: true,
                 position: 'center',
                 formatter: function () {
-                  const total = this.alarmDistribution.reduce((sum, item) => sum + item.value, 0);
+                  const total = this.sevenDayTotalAlarms;
                   return total + '\n七日告警数分布';
                 }.bind(this),
                 fontSize: 16,
               },
-              data: this.alarmDistribution,
+              data: this.monitorPointCounts.map(point => ({
+                name: point.monitorName,
+                value: point.count
+              })),
               emphasis: {
                 itemStyle: {
                   shadowBlur: 10,
@@ -342,7 +332,7 @@ export default {
             }
           },
           legend: {
-            data: Object.keys(this.alarmTrend)
+            data: ['内容类', '阈值类', '存在性']
           },
 
           grid: {
@@ -355,7 +345,7 @@ export default {
             {
               type: 'category',
               boundaryGap: false,
-              data: [...new Set(Object.values(this.alarmTrend).flat().map(item => item.name))]
+              data: this.trend.dates || []
             }
           ],
           yAxis: [
@@ -381,7 +371,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: (this.alarmTrend['内容类'] || []).map(item => item.value),
+              data: this.trend.contentCounts || [],
               lineStyle: {
                 color: '#ee6666'
               },
@@ -397,7 +387,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: (this.alarmTrend['阈值类'] || []).map(item => item.value),
+              data: this.trend.thresholdCounts || [],
               lineStyle: {
                 color: '#5470c6'
               },
@@ -413,7 +403,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: this.alarmTrend['存在性'].map(item => item.value),
+              data: this.trend.existenceCounts || [],
               lineStyle: {
                 color: '#91cc75'
               },
@@ -465,7 +455,7 @@ export default {
           xAxis: [
             {
               type: 'category',
-              data: Object.keys(this.systemAlarms || {})
+              data: this.systemCategories.map(system => system.systemName)
             }
           ],
           yAxis: [
@@ -489,7 +479,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['内容类'] || 0),
+              data: this.systemCategories.map(system => system.contentCount || 0),
               itemStyle: {
                 color: '#ee6666'
               }
@@ -500,7 +490,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['阈值类'] || 0),
+              data: this.systemCategories.map(system => system.thresholdCount || 0),
               itemStyle: {
                 color: '#5470c6'
               }
@@ -511,7 +501,7 @@ export default {
               emphasis: {
                 focus: 'series'
               },
-              data: Object.keys(this.systemAlarms || {}).map(system => this.systemAlarms[system]['存在性'] || 0),
+              data: this.systemCategories.map(system => system.existenceCount || 0),
               itemStyle: {
                 color: '#91cc75'
               }
@@ -545,14 +535,6 @@ export default {
           }
           // 创建新图表实例
           this.initCategoryChart('threshold')
-        } else if (tab.name === 'existence' && this.$refs.existenceChart) {
-          // 销毁旧图表实例
-          if (this.charts.existenceChart) {
-            this.charts.existenceChart.dispose()
-            this.charts.existenceChart = null
-          }
-          // 创建新图表实例
-          this.initCategoryChart('existence')
         }
       }, 100)
     },
@@ -577,6 +559,7 @@ export default {
         let option = {}
 
         if (type === 'content') {
+          const contentData = this.metricCategory.content || {}
           option = {
             tooltip: {
               trigger: 'item',
@@ -585,7 +568,7 @@ export default {
             legend: {
               orient: 'horizontal',
               bottom: 0,
-              data: ['正常', '无数据', '未配置'],
+              data: ['正常', '未配置', '无数据'],
               width: '100%',
               itemWidth: 10,
               itemHeight: 10,
@@ -615,17 +598,23 @@ export default {
                 labelLine: {
                   show: false
                 },
-                data:
-                  this.indicatorStatus['内容类'] || [
-                    { value: 3, name: '正常' },
-                    { value: 1, name: '无数据' },
-                    { value: 4, name: '未配置' }
-                  ],
-                color: ['#F44336', '#BDBDBD', '#8BC34A']
+                data: [
+                  {
+                    value: contentData.configuredCount || 0, name: '正常'
+                  },
+                  {
+                    value: contentData.unconfiguredCount || 0, name: '未配置'
+                  },
+                  {
+                    value: contentData.noDataCount || 0, name: '无数据'
+                  }
+                ],
+                color: ['#8BC34A', '#BDBDBD', '#F44336']
               }
             ]
           }
         } else if (type === 'threshold') {
+          const thresholdData = this.metricCategory.threshold || {}
           option = {
             tooltip: {
               trigger: 'item',
@@ -634,7 +623,7 @@ export default {
             legend: {
               orient: 'horizontal',
               bottom: 0,
-              data: ['正常', '无数据', '未配置'],
+              data: ['正常', '未配置', '无数据'],
               width: '100%',
               itemWidth: 10,
               itemHeight: 10,
@@ -664,54 +653,18 @@ export default {
                 labelLine: {
                   show: false
                 },
-                data:
-                  this.indicatorStatus['阈值类'] || [
-                    { value: 4, name: '正常' },
-                    { value: 0, name: '无数据' },
-                    { value: 6, name: '未配置' }
-                  ],
-                color: ['#F44336', '#BDBDBD', '#8BC34A']
-
-              }
-            ]
-          }
-        } else if (type === 'existence') {
-          option = {
-            tooltip: {
-              trigger: 'item',
-              formatter: '{a} <br/>{b}: {c} ({d}%)'
-            },
-            legend: {
-              orient: 'vertical',
-              left: 10,
-              data: ['正常', '无数据', '未配置']
-            },
-            series: [
-              {
-                name: '存在性',
-                type: 'pie',
-                radius: ['40%', '70%'],
-                avoidLabelOverlap: false,
-                itemStyle: {
-                  borderRadius: 10,
-                  borderColor: '#fff',
-                  borderWidth: 2
-                },
-                label: {
-                  show: false,
-                  position: 'center'
-                },
-                emphasis: {
-                  label: {
-                    show: true,
-                    fontSize: '18',
-                    fontWeight: 'bold'
+                data: [
+                  {
+                    value: thresholdData.configuredCount || 0, name: '正常'
+                  },
+                  {
+                    value: thresholdData.unconfiguredCount || 0, name: '未配置'
+                  },
+                  {
+                    value: thresholdData.noDataCount || 0, name: '无数据'
                   }
-                },
-                labelLine: {
-                  show: false
-                },
-                data: this.indicatorStatus['存在性']
+                ],
+                color: ['#8BC34A', '#BDBDBD', '#F44336']
               }
             ]
           }
@@ -727,19 +680,18 @@ export default {
       }
     },
 
-    refreshData() {
+    async refreshData() {
       // 模拟数据刷新
       console.log('刷新数据...')
       this.currentDate = new Date().toISOString().slice(0, 19).replace('T', ' ')
+      this.loading = true
 
-      // 随机更新实时告警列表
-      this.getRealEvent()
-
-      // 重新初始化图表以确保正确显示
-      setTimeout(() => {
-        this.destroyCharts()
-        this.initCharts()
-      }, 100)
+      try {
+        // 重新获取数据
+        await this.initCharts()
+      } finally {
+        this.loading = false
+      }
     },
 
     startAutoRefresh() {
@@ -775,6 +727,11 @@ export default {
       const hours = String(date.getHours()).padStart(2, '0')
       const minutes = String(date.getMinutes()).padStart(2, '0')
       return `${year}-${month}-${day} ${hours}:${minutes}`
+    },
+
+    getRealEvent() {
+      // 这里可以添加获取实时事件的逻辑
+      return Promise.resolve()
     }
   }
 }

+ 69 - 9
src/views/openMarketBid/details.vue

@@ -12,7 +12,7 @@
                             </el-form-item>
                         </el-col>
                         <el-col :span="12">
-                            <el-form-item label="公告类">
+                            <el-form-item label="公告类">
                                 {{ formData.announcementType || '-' }}
                             </el-form-item>
                         </el-col>
@@ -31,10 +31,10 @@
                     </el-row>
                     <el-row :gutter="20">
                         <el-col :span="12">
-                            <el-form-item label="是否关">
+                            <el-form-item label="是否关">
                                 <span class="bool-value"
-                                    :class="{ true: formData.isRelevant === 1, false: formData.isRelevant === 0 }">
-                                    {{ formData.isRelevant === 1 ? '是' : formData.isRelevant === 0 ? '否' : '-' }}
+                                    :class="{ true: formData.isRelevant === 1, false: formData.isRelevant === 0, 'duplicate': formData.isRelevant === 2 }">
+                                    {{ formData.isRelevant === 1 ? '是' : formData.isRelevant === 0 ? '否' :formData.isRelevant === 2 ? '重复': '-' }}
                                 </span>
                             </el-form-item>
                         </el-col>
@@ -53,13 +53,13 @@
                             </el-form-item>
                         </el-col>
                         <el-col :span="12">
-                            <el-form-item label="剑鱼地址">
-                                <a v-if="formData.jianyuUrl" :href="formData.jianyuUrl" target="_blank"
-                                    class="link-text">{{ formData.jianyuUrl }}</a>
-                                <span v-else>-</span>
+                            <el-form-item label="购买标书截止时间">
+                                {{ formData.bidDocumentDeadline ? new
+                                    Date(formData.bidDocumentDeadline).toLocaleString() : '-' }}
                             </el-form-item>
                         </el-col>
                     </el-row>
+                   
 
                 </el-form>
             </div>
@@ -93,6 +93,31 @@
                         </el-col>
                     </el-row>
 
+                    <el-row :gutter="20">
+                        <el-col :span="12">
+                            <el-form-item label="对应自然客户ID">
+                                {{ formData.fmNaturalCustomerId || '-' }}
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="行业">
+                                {{ formData.industry || '-' }}
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row :gutter="20">
+                        <el-col :span="12">
+                            <el-form-item label="业务类型">
+                                {{ formData.businessCategory || '-' }}
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="业务需求">
+                                {{ formData.businessDemand || '-' }}
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+
                     <el-row :gutter="20">
                         <el-col :span="12">
                             <el-form-item label="招标信息发布时间">
@@ -139,6 +164,7 @@
                         </el-col>
                     </el-row>
 
+
                 </el-form>
             </div>
 
@@ -188,6 +214,37 @@
                             </el-form-item>
                         </el-col>
                     </el-row>
+                    <el-row :gutter="20">
+                        <el-col :span="12">
+                            <el-form-item label="红黄绿牌">
+                               {{formData.rbgLabel||'-'}}
+                            </el-form-item>
+                        </el-col>
+                          <el-col :span="12">
+                            <el-form-item label="弃标审批单号">
+                                {{ formData.discardApprovalNumber || '-' }}
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <!-- <el-row :gutter="20">
+                        <el-col :span="12">
+                            <el-form-item label="商机ID">
+                                {{ formData.opportunityId || '-' }}
+                            </el-form-item>
+                        </el-col>
+                        <el-col :span="12">
+                            <el-form-item label="创建时间">
+                                {{ formData.createTime ? new Date(formData.createTime).toLocaleString() : '-' }}
+                            </el-form-item>
+                        </el-col>
+                    </el-row>
+                    <el-row :gutter="20">
+                        <el-col :span="12">
+                            <el-form-item label="更新时间">
+                                {{ formData.updateTime ? new Date(formData.updateTime).toLocaleString() : '-' }}
+                            </el-form-item>
+                        </el-col>
+                    </el-row> -->
                 </el-form>
             </div>
 
@@ -401,7 +458,10 @@ export default {
     font-size: 12px;
     font-weight: 500;
 }
-
+.duplicate {
+    background-color: #fef0f0;
+    color: #f56c6c;
+}
 .bool-value.true {
     background-color: #f0f9eb;
     color: #67c23a;

+ 3 - 4
src/views/openMarketBid/index.vue

@@ -141,7 +141,6 @@
         <div class="list-container">
             <el-table :data="noticeList" header-align="center" style="width: 100%" stripe v-loading="tableLoading"
                 border>
-            
                 <el-table-column prop="announcementType" label="公告类型" fixed="left" min-width="100"
                     align="center"></el-table-column>
                 <el-table-column prop="announcementTitle" label="公告标题" fixed="left" min-width="200"
@@ -170,16 +169,16 @@
                     align="center"></el-table-column>
                 <el-table-column prop="industry" label="行业" min-width="100" align="center"></el-table-column>
                 <el-table-column prop="branchCompany" label="分公司" min-width="100" align="center"></el-table-column>
-                <el-table-column prop="businessCategory" label="业务类" min-width="100" align="center"></el-table-column>
+                <el-table-column prop="businessCategory" label="业务类" min-width="100" align="center"></el-table-column>
                 <el-table-column prop="businessDemand" label="业务需求" min-width="120" align="center"></el-table-column>
                 <el-table-column prop="budget" label="预算(万元)" min-width="100" align="center"></el-table-column>
                 <el-table-column prop="bidOpeningDate" label="开标日期" min-width="120" align="center"></el-table-column>
                 <el-table-column prop="announcementUrl" label="公告地址" min-width="200" align="center"></el-table-column>
-                <el-table-column prop="jianyuUrl" label="剑鱼地址" min-width="200" align="center"></el-table-column>
+                <!-- <el-table-column prop="jianyuUrl" label="剑鱼地址" min-width="200" align="center"></el-table-column> -->
                 <el-table-column prop="tenderInfoPublishTime" label="招标信息发布时间" min-width="150"
                     align="center"></el-table-column>
                 <el-table-column prop="publishTime" label="发布时间" min-width="120" align="center"></el-table-column>
-                <el-table-column label="操作" min-width="100" fixed="right">
+                <el-table-column label="操作" min-width="100" fixed="right" align="center">
                     <template slot-scope="scope">
                         <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
                         <el-button type="text" @click="handleCommand(`detail`, scope.row)">详情</el-button>

+ 2 - 2
vue.config.js

@@ -9,8 +9,8 @@ const CompressionPlugin = require('compression-webpack-plugin')
 
 const name = process.env.VUE_APP_TITLE || '黑龙江运行保障能力' // 网页标题
 
-const baseUrl = 'http://10.130.22.73:1090/' // 后端接口
-// const baseUrl = 'http://10.64.12.216:12321' // 后端接口
+// const baseUrl = 'http://10.130.22.73:1090/' // 后端接口
+const baseUrl = 'http://10.64.12.216:12321' // 后端接口
 
 
 const port = process.env.port || process.env.npm_config_port || 80 // 端口