소스 검색

新增首页消息列表组件

画安 3 일 전
부모
커밋
fd38e248dd
2개의 변경된 파일241개의 추가작업 그리고 1개의 파일을 삭제
  1. 195 0
      src/components/ui/AlarmMessageList.vue
  2. 46 1
      src/views/Home.vue

+ 195 - 0
src/components/ui/AlarmMessageList.vue

@@ -0,0 +1,195 @@
+<template>
+    <div class="alarm-list-container">
+        <div v-if="!listData || listData.length === 0" class="empty-text">
+            暂无消息
+        </div>
+
+        <div class="alarm-item" v-for="(item, index) in listData" :key="item.id || index">
+            <div class="item-header">
+                <span class="title" :class="getTitleClass(item.type)">
+                    {{ item.title }}
+                </span>
+                <span class="time" v-if="item.time">{{ item.time }}</span>
+            </div>
+
+            <div class="item-body">
+                <span class="desc">{{ item.description }}</span>
+                <div class="actions">
+                    <button class="btn btn-ignore" @click="handleIgnore(item, index)">忽略</button>
+                    <button class="btn btn-view" @click="handleView(item, index)">查看</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'AlarmMessageList',
+    props: {
+        // 列表数据源
+        listData: {
+            type: Array,
+            default: () => []
+        }
+    },
+    methods: {
+        // 根据告警级别返回对应的颜色 class
+        getTitleClass(type) {
+            const typeMap = {
+                'error': 'text-red',
+                'warning': 'text-yellow',
+                'info': 'text-blue',
+                'success': 'text-green'
+            };
+            return typeMap[type] || 'text-default';
+        },
+        // 触发忽略事件
+        handleIgnore(item, index) {
+            this.$emit('ignore', { item, index });
+        },
+        // 触发查看事件
+        handleView(item, index) {
+            this.$emit('view', { item, index });
+        }
+    }
+}
+</script>
+
+<style scoped>
+.alarm-list-container {
+    width: 100%;
+    height: 100%;
+    overflow-y: auto;
+}
+
+/* 隐藏滚动条但保留滚动功能 */
+.alarm-list-container::-webkit-scrollbar {
+    display: none;
+}
+
+.empty-text {
+    text-align: center;
+    color: #64748b;
+    padding: 20px 0;
+    font-size: 14px;
+}
+
+/* 每条消息的容器 */
+.alarm-item {
+    display: flex;
+    flex-direction: column;
+    border-bottom: 1px solid rgba(208,222,238,0.15);
+    padding: 15px 0;
+}
+
+.alarm-item:first-child {
+    padding-top: 13px;
+}
+
+/* 去掉最后一条的下划线 */
+.alarm-item:last-child {
+    border-bottom: none;
+}
+
+/* 第一行:头部布局 */
+.item-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 4px;
+}
+
+.title {
+    font-size: 14px;
+}
+
+/* 状态颜色 */
+.text-red {
+    color: #FF3838;
+}
+
+.text-yellow {
+    color: #FFCE34;
+}
+
+.text-blue {
+    color: #32F6F8;
+}
+
+.text-green {
+    color: #10b981;
+}
+
+.text-default {
+    color: #ffffff;
+}
+
+.time {
+    font-size: 12px;
+    color: rgba(255, 255, 255, 0.65);
+    /* 次要文字颜色 */
+}
+
+/* 第二行:主体布局 */
+.item-body {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+
+.desc {
+    font-size: 12px;
+    color: rgba(255, 255, 255, 0.65);
+    flex: 1;
+    padding-right: 15px;
+
+    /* 超出部分省略号显示 (防止文字过长折行破坏布局) */
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.actions {
+    display: flex;
+    gap: 10px;
+    flex-shrink: 0;
+    /* 防止按钮被长文本挤压变形 */
+}
+
+/* 通用按钮样式清除 */
+.btn {
+    background: transparent;
+    border: none;
+    outline: none;
+    cursor: pointer;
+    font-size: 14px;
+    padding: 5px 8px;
+    border-radius: 4px;
+    transition: all 0.2s;
+}
+
+/* 忽略按钮:低调的文字按钮 */
+.btn-ignore {
+    background-color: #0D2244;
+    color: #ffffff;
+}
+
+.btn-ignore:hover {
+    color: #ffffff;
+    background: rgba(255, 255, 255, 0.1);
+}
+
+/* 查看按钮:科技感蓝色渐变边框按钮 */
+.btn-view {
+    color: #ffffff;
+    background: linear-gradient(180deg, rgba(24, 144, 255, 0.1) 0%, rgba(24, 144, 255, 0.3) 100%);
+    box-shadow: inset 0 0 8px rgba(24, 144, 255, 0.2);
+}
+
+.btn-view:hover {
+    background: linear-gradient(180deg, rgba(24, 144, 255, 0.2) 0%, rgba(24, 144, 255, 0.5) 100%);
+    box-shadow: inset 0 0 12px rgba(24, 144, 255, 0.4);
+    border-color: #32F6F8;
+}
+</style>

+ 46 - 1
src/views/Home.vue

@@ -44,6 +44,15 @@
             />
           </PanelContainer>
         </div>
+        <div class="panel-item">
+          <PanelContainer title="在线状态">
+            <AlarmMessageList 
+              :listData="alarmData" 
+              @ignore="onAlarmIgnore" 
+              @view="onAlarmView" 
+            />
+          </PanelContainer>
+        </div>
       </div>
     </template>
 
@@ -59,6 +68,7 @@ import DynamicDonutChart from '@/components/ui/DynamicDonutChart.vue';
 import TechTabs from '@/components/ui/TechTabs.vue';
 import TechTabPane from '@/components/ui/TechTabPane.vue';
 import TickDonutChart from '@/components/ui/TickDonutChart.vue';
+import AlarmMessageList from '@/components/ui/AlarmMessageList.vue';
 
 
 const mockDeviceData = {
@@ -99,7 +109,8 @@ export default {
     DynamicDonutChart,
     TechTabs,
     TechTabPane,
-    TickDonutChart
+    TickDonutChart,
+    AlarmMessageList
   },
   data() {
     return {
@@ -115,6 +126,29 @@ export default {
         { name: '自适应控制', value: 10,  color: '#2dd4bf' }, // 青色
         { name: '中心控制',   value: null,color: '#8b5cf6' }, // 紫色
         { name: '全红控制',   value: null,color: '#f43f5e' }  // 红色
+      ],
+      alarmData: [
+        {
+          id: '1',
+          title: '通讯中断',
+          type: 'error', // 渲染为红色
+          time: '16:28:28',
+          description: '中关村大街-科学院南路口-设备离线'
+        },
+        {
+          id: '2',
+          title: '2.降级黄闪',
+          type: 'warning', // 渲染为黄色
+          time: '', // 
+          description: '中关村大街-科学院南路口-设备离线'
+        },
+        {
+          id: '3',
+          title: '3.降级黄闪',
+          type: 'warning',
+          time: '16:28:28',
+          description: '中关村大街-科学院南路口-设备离线'
+        }
       ]
     };
   },
@@ -130,6 +164,17 @@ export default {
       if (mockDeviceData[selectedTabName]) {
         this.onlineStatusDisplayData = mockDeviceData[selectedTabName];
       }
+    },
+    // 处理忽略逻辑
+    onAlarmIgnore({ item, index }) {
+      console.log('点击了忽略:', item.title);
+      // 真实业务中可能会调接口,这里我们可以演示本地移除:
+      // this.alarmData.splice(index, 1);
+    },
+    // 处理查看逻辑
+    onAlarmView({ item, index }) {
+      console.log('点击了查看:', item.title);
+      // 这里可以触发打开一个弹窗 (调用你之前的 SmartDialog 或者路由跳转)
     }
   }
 }