Explorar o código

feat: 宇信首页

liujt hai 4 días
pai
achega
5c6893b6e8
Modificáronse 1 ficheiros con 121 adicións e 71 borrados
  1. 121 71
      src/views/home/yuxin.vue

+ 121 - 71
src/views/home/yuxin.vue

@@ -40,14 +40,14 @@
                 <span class="date-text">{{ currentDate }}</span>
                 <span class="time-text">{{ currentTime }}</span>
             </div>
-            <!-- <span class="fullscreen-toggle" @click.passive="onFullscreen">
+            <span class="fullscreen-toggle" @click.passive="onFullscreen">
                 <i
                 v-if="isFullscreen"
                 title="取消全屏"
                 class="el-icon-_screen-restore"
                 />
                 <i v-else title="全屏" class="el-icon-_screen-full" />
-            </span> -->
+            </span>
           </div>
         </div>
       </div>
@@ -179,17 +179,42 @@
 
 <script>
 import * as echarts from 'echarts'
+import { component } from 'vue-fullscreen'
 import TrendChart from './components/TrendChart.vue'
 import StatCard from './components/StatCard.vue'
 import { deviceIndexStatistics } from '@/api/main/index.js'
 
 
-// 模拟数据
-const yearMonths = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+// 默认周 x 轴数据(无真实数据时的占位)
 const weekDays = ['第1周', '第2周', '第3周', '第4周']
 
-function genData(base, variance, count) {
-  return Array.from({ length: count }, () => Math.round(base + (Math.random() - 0.5) * variance))
+// 固定场站列表
+const FIXED_STATIONS = ['5#站', '6#站', '7#站']
+
+// 固定 12 个月份的 x 轴标签
+const MONTHS_12 = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+
+// 将 API 数据 [{stationName, dateTime, rate}] 格式化为 chart 所需的 xData(固定12月) + seriesConfig
+// 始终按 FIXED_STATIONS 顺序输出,无数据月份补 0
+function formatTrendData(list, valueKey, colors) {
+  const valueField = valueKey || 'rate'
+  const stationMap = {}
+
+  list.forEach((item) => {
+    const station = item.stationName
+    const month = parseInt(item.dateTime.split('-')[1])       // "2026-05" → 5
+    const monthLabel = MONTHS_12[month - 1]                    // 5 → "5月"
+    if (!stationMap[station]) stationMap[station] = {}
+    stationMap[station][monthLabel] = item[valueField]
+  })
+
+  const seriesConfig = FIXED_STATIONS.map((name, idx) => ({
+    name,
+    data: MONTHS_12.map((m) => stationMap[name]?.[m] ?? 0),    // 缺月/缺站统一补 0
+    color: colors[idx % colors.length]
+  }))
+
+  return { xData: MONTHS_12, seriesConfig }
 }
 
 const palette = ['#3b82f6', '#22d3ee', '#facc15', '#f87171', '#a78bfa', '#34d399']
@@ -252,26 +277,18 @@ function makeMultiLineOption(xData, seriesConfig, unit) {
 
 export default {
   name: 'DeviceDashboard',
-  components: { TrendChart, StatCard },
+  components: { VueFullscreen: component, TrendChart, StatCard },
   data() {
     return {
       isFullscreen: false,
+      currentDate: '',
+      currentTime: '',
       selectedStation: 'station-6',
       stationList: [
         { label: '5#场站', value: 'station-5' },
         { label: '6#场站', value: 'station-6' },
         { label: '7#场站', value: 'station-7' }
       ],
-      comprehensiveList: [
-        { label: '设备总数', value: 350, unit: '台' },
-        { label: '运行中', value: 345, unit: '台' },
-        { label: '维修中', value: 5, unit: '台' },
-        { label: '离线设备', value: 0, unit: '台' },
-        { label: '本年新增', value: 12, unit: '台' },
-        { label: '本月新增', value: 2, unit: '台' },
-        { label: '年运行率', value: 96.5, unit: '%' },
-        { label: '月运行率', value: 98.2, unit: '%' }
-      ],
       statsCardList: [
         { label: '设备总数', value: 350, unit: '台', key: 'totalNum', bgimg: require('@/assets/pcs/runDevice.png'), valueColor: '#409EFF', icon: 'el-icon-monitor', iconColor: '#409EFF', iconBg: '#ecf5ff'},
         { label: '运行数', value: 345, unit: '台', key: 'runNum', bgimg: require('@/assets/pcs/successInfo.png'), valueColor: '#67C23A', icon: 'el-icon-play', iconColor: '#67C23A', iconBg: '#ecf5ff'},
@@ -285,80 +302,113 @@ export default {
       monthRepairCountOption: {}
     }
   },
-  computed: {
-    currentDate() {
-      const d = new Date()
-      return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate()
-    },
-    currentTime() {
-      const d = new Date()
-      return d.getHours().toString().padStart(2, '0') + ':' +
-        d.getMinutes().toString().padStart(2, '0') + ':' +
-        d.getSeconds().toString().padStart(2, '0')
-    }
-  },
+  computed: {},
   mounted() {
-    this.initStatisticsCard()
+    this.updateTime()
     this.initCharts()
     this.updateTimer = setInterval(this.updateTime, 1000)
+    window.addEventListener('resize', this.handleResize)
   },
   beforeDestroy() {
     clearInterval(this.updateTimer)
+    window.removeEventListener('resize', this.handleResize)
+  },
+  watch: {
+    isFullscreen: {
+      handler() {
+        this.$nextTick(() => this.handleResize())
+      }
+    }
   },
   methods: {
     onFullscreen() {
         this.isFullscreen = !this.isFullscreen;
     },
-    async initStatisticsCard() {
-      const res = await deviceIndexStatistics()
-      console.log('res', res)
-      this.statsCardList.forEach((item) => {
-          item.value = res[item.key];
-        });
+    handleResize() {
+      const { clientWidth, clientHeight } = document.documentElement
+      const containers = document.getElementsByClassName('box-container')
+      Array.from(containers).forEach((item) => {
+        if (this.isFullscreen) {
+          item.style.height = clientHeight + 'px'
+          item.style.width = clientWidth + 'px'
+        } else {
+          item.style.height = clientHeight - 100 + 'px'
+          item.style.width = clientWidth - 240 + 'px'
+        }
+      })
+      this.$nextTick(() => {
+        Object.values(this.$children).forEach(child => {
+          child.chartInstance && child.chartInstance.resize()
+        })
+      })
     },
+
     updateTime() {
-      this.$forceUpdate()
+      const now = new Date()
+      const y = now.getFullYear()
+      const m = (now.getMonth() + 1)
+      const d = now.getDate()
+      this.currentDate = y + '-' + m + '-' + d
+      this.currentTime =
+        now.getHours().toString().padStart(2, '0') + ':' +
+        now.getMinutes().toString().padStart(2, '0') + ':' +
+        now.getSeconds().toString().padStart(2, '0')
     },
-    initCharts() {
-      this.yearRunRateOption = makeMultiLineOption(yearMonths, [
-        { name: '5#场站', data: genData(96, 6, 12), color: '#3b82f6' },
-        { name: '6#场站', data: genData(94, 8, 12), color: '#22d3ee' },
-        { name: '7#场站', data: genData(97, 5, 12), color: '#facc15' }
-      ], '%')
+    async initCharts() {
+      const res = await deviceIndexStatistics()
+      console.log('res', res)
+      this.statsCardList.forEach((item) => {
+        item.value = res[item.key];
+      });
+
+      // ========== 年运行率趋势图 — nyxlList ==========
+      if (res.nyxlList && res.nyxlList.length) {
+        const { xData, seriesConfig } = formatTrendData(res.nyxlList, 'rate', palette)
+        this.yearRunRateOption = makeMultiLineOption(xData, seriesConfig, '%')
+      } else {
+        this.yearRunRateOption = makeMultiLineOption(MONTHS_12, [
+          { name: '暂无数据', data: new Array(12).fill(0), color: '#8ba3c7' }
+        ], '%')
+      }
 
-      this.monthRunRateOption = makeMultiLineOption(yearMonths, [
-        { name: '5#场站', data: genData(96, 5, 12), color: '#3b82f6' },
-        { name: '6#场站', data: genData(95, 7, 12), color: '#22d3ee' },
-        { name: '7#场站', data: genData(95, 7, 12), color: '#22d3ee' }
-      ], '%')
+      // ========== 月运行率趋势图 — byList ==========
+      if (res.byList && res.byList.length) {
+        const { xData: x2, seriesConfig: sc2 } = formatTrendData(res.byList, 'rate', palette)
+        this.monthRunRateOption = makeMultiLineOption(x2, sc2, '%')
+      } else {
+        this.monthRunRateOption = makeMultiLineOption(MONTHS_12, [
+          { name: '暂无数据', data: new Array(12).fill(0), color: '#8ba3c7' }
+        ], '%')
+      }
 
-      this.yearFaultRateOption = makeMultiLineOption(yearMonths, [
-        { name: '5#场站', data: genData(4, 3, 12), color: '#f87171' },
-        { name: '6#场站', data: genData(3, 4, 12), color: '#facc15' },
-        { name: '7#场站', data: genData(2, 3, 12), color: '#8ba3c7' }
-      ], '%')
+      // ========== 年故障率趋势图 — gzwxList ==========
+      if (res.gzwxList && res.gzwxList.length) {
+        const { xData: x3, seriesConfig: sc3 } = formatTrendData(res.gzwxList, 'rate', ['#f87171', '#facc15', '#8ba3c7'])
+        this.yearFaultRateOption = makeMultiLineOption(x3, sc3, '%')
+      } else {
+        this.yearFaultRateOption = makeMultiLineOption(MONTHS_12, [
+          { name: '暂无数据', data: new Array(12).fill(0), color: '#8ba3c7' }
+        ], '%')
+      }
 
-      this.monthRunRateOption2 = makeMultiLineOption(yearMonths, [
-        { name: '5#场站', data: genData(97, 4, 12), color: '#3b82f6' },
-        { name: '6#场站', data: genData(95, 6, 12), color: '#22d3ee' },
-        { name: '7#场站', data: genData(98, 3, 12), color: '#a78bfa' }
+      // ========== 月运行率趋势图2(暂用模拟,后续可接入其他数据源)==========
+      this.monthRunRateOption2 = makeMultiLineOption(MONTHS_12, [
+        { name: '暂无数据', data: new Array(12).fill(0), color: '#a78bfa' }
       ], '%')
 
-      const repairTotal = genData(8, 6, 12).map(v => Math.max(2, v))
-      const repairDevice = genData(5, 4, 12).map(v => Math.max(1, v))
-      const repairOther = genData(3, 3, 12).map(v => Math.max(0, v))
-      this.yearRepairCountOption = makeMultiLineOption(yearMonths, [
-        { name: '5#场站', data: repairTotal, color: '#f87171' },
-        { name: '6#场站', data: repairDevice, color: '#facc15' },
-        { name: '7#场站', data: repairOther, color: '#3b82f6' }
-      ], '次')
+      // ========== 年维修次数趋势图 — jhwxList ==========
+      if (res.jhwxList && res.jhwxList.length) {
+        const { xData: x5, seriesConfig: sc5 } = formatTrendData(res.jhwxList, 'rate', ['#f87171', '#facc15', '#3b82f6'])
+        this.yearRepairCountOption = makeMultiLineOption(x5, sc5, '次')
+      } else {
+        this.yearRepairCountOption = makeMultiLineOption(MONTHS_12, [
+          { name: '暂无数据', data: new Array(12).fill(0), color: '#8ba3c7' }
+        ], '次')
+      }
 
-      const monthRepair1 = genData(2, 3, 4).map(v => Math.max(0, v))
-      const monthRepair2 = genData(1, 2, 4).map(v => Math.max(0, v))
-      this.monthRepairCountOption = makeMultiLineOption(weekDays, [
-        { name: '5#场站', data: monthRepair1, color: '#f87171' },
-        { name: '6#场站', data: monthRepair2, color: '#3b82f6' },
-        { name: '7#场站', data: monthRepair1, color: '#f87171' },
+      // ========== 月维修次数趋势图(暂用默认占位)==========
+      this.monthRepairCountOption = makeMultiLineOption(MONTHS_12, [
+        { name: '暂无数据', data: new Array(12).fill(0), color: '#f87171' }
       ], '次')
     },
   }