瀏覽代碼

feat: 调整添加设备的设备类型值;调整智慧大屏的历史展示组件;

liujia 1 月之前
父節點
當前提交
f7a5401

+ 52 - 3
src/views/dashboard/components/AlarmHistoryCard/index.vue

@@ -1,5 +1,12 @@
 <template>
   <TechCard>
+    <template #extra>
+      <div class="toggle-group">
+        <button :class="{ active: mode === 'day' }" @click="mode = 'day'">按日</button>
+        <button :class="{ active: mode === 'month' }" @click="mode = 'month'">按月</button>
+      </div>
+    </template>
+
     <div class="card-title">历史告警统计</div>
     <BaseChart :option="chartOption" :height="175" />
   </TechCard>
@@ -12,9 +19,30 @@ import * as echarts from 'echarts'
 
 defineOptions({ name: 'AlarmHistoryCard' })
 
-const alarmHistoryData = ref({
-  dates: ['2024-07-01', '2024-07-02', '2024-07-03', '2024-07-04', '2024-07-05'],
-  values: [10, 15, 20, 12, 8],
+// 切换模式:按日 / 按月
+const mode = ref<'day' | 'month'>('day')
+
+// 模拟接口数据结构
+const rawData = ref({
+  dayStatInfo: [
+    { date: '2024-07-01', fallingCount: 10 },
+    { date: '2024-07-02', fallingCount: 15 },
+    { date: '2024-07-03', fallingCount: 20 },
+    { date: '2024-07-04', fallingCount: 12 },
+    { date: '2024-07-05', fallingCount: 8 },
+  ],
+  monthStatInfo: [
+    { month: '2024-06', fallingCount: 50 },
+    { month: '2024-07', fallingCount: 65 },
+  ],
+})
+
+// 根据模式转换图表数据
+const alarmHistoryData = computed(() => {
+  const source = mode.value === 'day' ? rawData.value.dayStatInfo : rawData.value.monthStatInfo
+  const dates = source.map((item) => ('date' in item ? item.date : item.month))
+  const values = source.map((item) => item.fallingCount ?? 0)
+  return { dates, values }
 })
 
 // 图表配置项
@@ -71,4 +99,25 @@ const chartOption = computed(() => ({
   margin-bottom: 12px;
   text-align: center;
 }
+
+.toggle-group {
+  display: flex;
+  gap: 8px;
+  justify-content: flex-end;
+
+  button {
+    background: none;
+    border: 1px solid #f39c12;
+    color: #f39c12;
+    padding: 4px 10px;
+    border-radius: 4px;
+    font-size: 12px;
+    cursor: pointer;
+
+    &.active {
+      background-color: #f39c12;
+      color: #fff;
+    }
+  }
+}
 </style>

+ 53 - 3
src/views/dashboard/components/FallingHistoryCard/index.vue

@@ -1,5 +1,12 @@
 <template>
   <TechCard>
+    <template #extra>
+      <div class="toggle-group">
+        <button :class="{ active: mode === 'day' }" @click="mode = 'day'">按日</button>
+        <button :class="{ active: mode === 'month' }" @click="mode = 'month'">按月</button>
+      </div>
+    </template>
+
     <div class="card-title">历史跌倒统计</div>
     <BaseChart :option="chartOption" :height="175" />
   </TechCard>
@@ -12,11 +19,33 @@ import TechCard from '../TechCard/index.vue'
 
 defineOptions({ name: 'FallingHistoryCard' })
 
-const fallingHistoryData = ref({
-  dates: ['2024-07-01', '2024-07-02', '2024-07-03', '2024-07-04', '2024-07-05'],
-  values: [5, 8, 6, 10, 7],
+// 切换模式:按日 / 按月
+const mode = ref<'day' | 'month'>('day')
+
+// 模拟接口数据结构
+const rawData = ref({
+  dayStatInfo: [
+    { date: '2024-07-01', fallingCount: 5 },
+    { date: '2024-07-02', fallingCount: 8 },
+    { date: '2024-07-03', fallingCount: 6 },
+    { date: '2024-07-04', fallingCount: 10 },
+    { date: '2024-07-05', fallingCount: 7 },
+  ],
+  monthStatInfo: [
+    { month: '2024-06', fallingCount: 32 },
+    { month: '2024-07', fallingCount: 41 },
+  ],
+})
+
+// 根据模式转换图表数据
+const fallingHistoryData = computed(() => {
+  const source = mode.value === 'day' ? rawData.value.dayStatInfo : rawData.value.monthStatInfo
+  const dates = source.map((item) => ('date' in item ? item.date : item.month))
+  const values = source.map((item) => item.fallingCount ?? 0)
+  return { dates, values }
 })
 
+// 图表配置项
 const chartOption = computed(() => ({
   grid: { top: 10, right: 20, bottom: 30, left: 30 },
   tooltip: {
@@ -70,4 +99,25 @@ const chartOption = computed(() => ({
   margin-bottom: 12px;
   text-align: center;
 }
+
+.toggle-group {
+  display: flex;
+  gap: 8px;
+  justify-content: flex-end;
+
+  button {
+    background: none;
+    border: 1px solid #e74c3c;
+    color: #e74c3c;
+    padding: 4px 10px;
+    border-radius: 4px;
+    font-size: 12px;
+    cursor: pointer;
+
+    &.active {
+      background-color: #e74c3c;
+      color: #fff;
+    }
+  }
+}
 </style>

+ 126 - 0
src/views/dashboard/components/HistoryChartCard/index.vue

@@ -0,0 +1,126 @@
+<template>
+  <TechCard>
+    <template #extra>
+      <div class="toggle-group">
+        <button :class="{ active: mode === 'day' }" @click="mode = 'day'">按日</button>
+        <button :class="{ active: mode === 'month' }" @click="mode = 'month'">按月</button>
+      </div>
+    </template>
+
+    <div class="card-title">{{ title }}</div>
+    <BaseChart :option="chartOption" :height="175" />
+  </TechCard>
+</template>
+
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import * as echarts from 'echarts'
+import TechCard from '../TechCard/index.vue'
+
+defineOptions({ name: 'HistoryChartCard' })
+
+interface DayItem {
+  date: string
+  fallingCount: number
+}
+
+interface MonthItem {
+  month: string
+  fallingCount: number
+}
+
+const props = defineProps<{
+  title: string
+  dayStatInfo: DayItem[]
+  monthStatInfo: MonthItem[]
+  color: string
+  seriesName: string
+}>()
+
+const mode = ref<'day' | 'month'>('day')
+
+const chartData = computed(() => {
+  const source = mode.value === 'day' ? props.dayStatInfo : props.monthStatInfo
+  const dates = source.map((item) => ('date' in item ? item.date : item.month))
+  const values = source.map((item) => item.fallingCount ?? 0)
+  return { dates, values }
+})
+
+const chartOption = computed(() => ({
+  grid: { top: 10, right: 20, bottom: 30, left: 30 },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: { type: 'shadow' },
+  },
+  xAxis: {
+    type: 'category',
+    data: chartData.value.dates,
+    axisLine: { lineStyle: { color: '#2a3b5a' } },
+    axisLabel: { color: '#9cc5e0', fontSize: 12 },
+  },
+  yAxis: {
+    type: 'value',
+    axisLine: { lineStyle: { color: '#2a3b5a' } },
+    axisLabel: { color: '#9cc5e0', fontSize: 12 },
+    splitLine: { lineStyle: { color: 'rgba(42, 59, 90, 0.3)' } },
+  },
+  series: [
+    {
+      name: props.seriesName,
+      type: mode.value === 'day' ? 'line' : 'bar', // ✅ 动态切换图表类型
+      smooth: mode.value === 'day',
+      symbol: 'circle',
+      symbolSize: 8,
+      data: chartData.value.values,
+      itemStyle: { color: props.color },
+      lineStyle: {
+        width: 3,
+        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+          { offset: 0, color: props.color },
+          { offset: 1, color: props.color },
+        ]),
+      },
+      areaStyle:
+        mode.value === 'day'
+          ? {
+              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                { offset: 0, color: `${props.color}4D` },
+                { offset: 1, color: `${props.color}1A` },
+              ]),
+            }
+          : undefined,
+    },
+  ],
+}))
+</script>
+
+<style scoped lang="less">
+.card-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin-bottom: 12px;
+  text-align: center;
+  color: v-bind(color);
+}
+
+.toggle-group {
+  display: flex;
+  gap: 8px;
+  justify-content: flex-end;
+
+  button {
+    background: none;
+    border: 1px solid v-bind(color);
+    color: v-bind(color);
+    padding: 4px 10px;
+    border-radius: 4px;
+    font-size: 12px;
+    cursor: pointer;
+
+    &.active {
+      background-color: v-bind(color);
+      color: #fff;
+    }
+  }
+}
+</style>

+ 12 - 0
src/views/dashboard/components/TechCard/index.vue

@@ -5,6 +5,10 @@
     <div class="corner bottom-left"></div>
     <div class="corner bottom-right"></div>
 
+    <div class="card-header">
+      <slot name="extra" />
+    </div>
+
     <div class="card-content">
       <slot />
     </div>
@@ -63,6 +67,14 @@ defineOptions({ name: 'TechCard' })
     animation: rainbowBorder 3s linear infinite;
   }
 
+  .card-header {
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 8px;
+    z-index: 1;
+    position: relative;
+  }
+
   .card-content {
     position: relative;
     z-index: 1;

+ 49 - 4
src/views/dashboard/index.vue

@@ -48,8 +48,52 @@
         </div>
 
         <div class="data-line">
-          <AlarmHistoryCard></AlarmHistoryCard>
-          <FallingHistoryCard></FallingHistoryCard>
+          <!-- <AlarmHistoryCard></AlarmHistoryCard>
+          <FallingHistoryCard></FallingHistoryCard> -->
+
+          <HistoryChartCard
+            title="历史告警统计"
+            :dayStatInfo="[
+              { date: '2024-07-01', fallingCount: 5 },
+              { date: '2024-07-02', fallingCount: 8 },
+              { date: '2024-07-03', fallingCount: 6 },
+              { date: '2024-07-04', fallingCount: 10 },
+              { date: '2024-07-05', fallingCount: 7 },
+            ]"
+            :monthStatInfo="[
+              { month: '2024-06', fallingCount: 32 },
+              { month: '2024-07', fallingCount: 41 },
+              { month: '2024-08', fallingCount: 45 },
+              { month: '2024-09', fallingCount: 30 },
+              { month: '2024-10', fallingCount: 60 },
+              { month: '2024-11', fallingCount: 35 },
+              { month: '2024-12', fallingCount: 50 },
+            ]"
+            color="#f39c12"
+            seriesName="告警次数"
+          />
+
+          <HistoryChartCard
+            title="历史跌倒统计"
+            :dayStatInfo="[
+              { date: '2024-07-01', fallingCount: 5 },
+              { date: '2024-07-02', fallingCount: 8 },
+              { date: '2024-07-03', fallingCount: 6 },
+              { date: '2024-07-04', fallingCount: 10 },
+              { date: '2024-07-05', fallingCount: 7 },
+            ]"
+            :monthStatInfo="[
+              { month: '2024-06', fallingCount: 32 },
+              { month: '2024-07', fallingCount: 41 },
+              { month: '2024-08', fallingCount: 60 },
+              { month: '2024-09', fallingCount: 30 },
+              { month: '2024-10', fallingCount: 35 },
+              { month: '2024-11', fallingCount: 45 },
+              { month: '2024-12', fallingCount: 70 },
+            ]"
+            color="#e74c3c"
+            seriesName="跌倒次数"
+          />
         </div>
       </div>
     </div>
@@ -66,8 +110,9 @@ import PeopleDetectedCard from './components/PeopleDetectedCard/index.vue'
 import DeviceLocationCard from './components/DeviceLocationCard/index.vue'
 import DeviceAgeCard from './components/DeviceAgeCard/index.vue'
 import ObjectDistributionCard from './components/ObjectDistributionCard/index.vue'
-import AlarmHistoryCard from './components/AlarmHistoryCard/index.vue'
-import FallingHistoryCard from './components/FallingHistoryCard/index.vue'
+// import AlarmHistoryCard from './components/AlarmHistoryCard/index.vue'
+// import FallingHistoryCard from './components/FallingHistoryCard/index.vue'
+import HistoryChartCard from './components/HistoryChartCard/index.vue'
 import { useUserStore } from '@/stores/user'
 import type { TodayData } from './types'
 import { ZoomInOutlined, ZoomOutOutlined, RedoOutlined } from '@ant-design/icons-vue'

+ 2 - 2
src/views/device/list/components/addDevice/index.vue

@@ -34,8 +34,8 @@
           :rules="[{ required: true, message: '请选择设备类型' }]"
         >
           <a-select v-model:value="formState.deviceType" placeholder="请选择设备类型">
-            <a-select-option value="1">LNA</a-select-option>
-            <a-select-option value="2">LNB</a-select-option>
+            <a-select-option value="LNA">LNA</a-select-option>
+            <a-select-option value="LNB">LNB</a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item