Przeglądaj źródła

Merge branch 'master' of http://git.fmode.cn:3000/0235699/industry-monitor

未来全栈 2 dni temu
rodzic
commit
55d1b675e1

+ 2 - 6
REDEME.md

@@ -21,10 +21,6 @@
         刘家昊 0230791 15122906621
         刘家昊 0230791 15122906621
 
 
  ```bash
  ```bash
-        -组长:徐福静  0235668  18370353938
-  -成员:曾露 0235699 19870555569
-        陈飞羽 0235635 13970419048
-        张喆  0224986  15070059526
-        刘家昊 0230791 15122906621
+ git config --global user.name "工业检测"
+ git config --global user.email "19870555569@163.com"
  ```
  ```
-

+ 786 - 0
docs/1.html

@@ -0,0 +1,786 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>工厂振动检测系统 - 总览看板</title>
+  <script src="https://cdn.tailwindcss.com"></script>
+  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
+  <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
+  
+  <!-- Tailwind 配置 -->
+  <script>
+    tailwind.config = {
+      theme: {
+        extend: {
+          colors: {
+            primary: '#165DFF',
+            secondary: '#0A2463',
+            warning: '#FF7D00',
+            danger: '#F53F3F',
+            success: '#00B42A',
+            dark: {
+              100: '#1D2129',
+              200: '#141414',
+              300: '#0A0A0A',
+              400: '#050505'
+            },
+            'neutral-light': '#86909C'
+          },
+          fontFamily: {
+            inter: ['Inter', 'system-ui', 'sans-serif'],
+          },
+        },
+      }
+    }
+  </script>
+  
+  <style type="text/tailwindcss">
+    @layer utilities {
+      .content-auto {
+        content-visibility: auto;
+      }
+      .text-shadow {
+        text-shadow: 0 0 8px rgba(22, 93, 255, 0.5);
+      }
+      .card-hover {
+        transition: all 0.3s ease;
+      }
+      .card-hover:hover {
+        transform: translateY(-5px);
+        box-shadow: 0 12px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(22, 93, 255, 0.5);
+      }
+      .scrollbar-hide::-webkit-scrollbar {
+        display: none;
+      }
+      .scrollbar-hide {
+        -ms-overflow-style: none;
+        scrollbar-width: none;
+      }
+      .animate-pulse-slow {
+        animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+      }
+      .bg-grid {
+        background-image: 
+          linear-gradient(rgba(22, 93, 255, 0.05) 1px, transparent 1px),
+          linear-gradient(90deg, rgba(22, 93, 255, 0.05) 1px, transparent 1px);
+        background-size: 20px 20px;
+      }
+    }
+  </style>
+</head>
+
+<body class="bg-dark-200 text-gray-100 font-inter min-h-screen flex flex-col bg-grid">
+  <div class="flex flex-1 overflow-hidden">
+    <!-- 侧边导航 -->
+    <aside id="sidebar" class="w-64 bg-dark-100 border-r border-dark-300 flex-shrink-0 transition-all duration-300 z-30">
+      <div class="p-4 border-b border-dark-300">
+        <h1 class="text-2xl font-bold text-primary flex items-center">
+          <i class="fa fa-industry mr-3"></i>
+          <span>振动检测系统</span>
+        </h1>
+      </div>
+      
+      <nav class="p-4">
+        <ul class="space-y-1">
+          <li>
+            <a href="#" class="flex items-center px-4 py-3 rounded-lg bg-primary/20 text-primary border-l-4 border-primary">
+              <i class="fa fa-dashboard w-6 text-center"></i>
+              <span>总览看板</span>
+            </a>
+          </li>
+          <li>
+            <a href="#" class="flex items-center px-4 py-3 rounded-lg hover:bg-dark-300 transition-colors">
+              <i class="fa fa-microphone w-6 text-center"></i>
+              <span>设备监控</span>
+            </a>
+          </li>
+          <li>
+            <a href="#" class="flex items-center px-4 py-3 rounded-lg hover:bg-dark-300 transition-colors">
+              <i class="fa fa-bell w-6 text-center"></i>
+              <span>预警管理</span>
+              <span class="ml-auto bg-danger text-white text-xs px-2 py-1 rounded-full">3</span>
+            </a>
+          </li>
+          <li>
+            <a href="#" class="flex items-center px-4 py-3 rounded-lg hover:bg-dark-300 transition-colors">
+              <i class="fa fa-line-chart w-6 text-center"></i>
+              <span>数据分析</span>
+            </a>
+          </li>
+          <li>
+            <a href="#" class="flex items-center px-4 py-3 rounded-lg hover:bg-dark-300 transition-colors">
+              <i class="fa fa-cog w-6 text-center"></i>
+              <span>系统设置</span>
+            </a>
+          </li>
+        </ul>
+      </nav>
+      
+      <div class="absolute bottom-0 w-full p-4 border-t border-dark-300">
+        <div class="flex items-center">
+          <img src="https://picsum.photos/id/1005/40/40" alt="用户头像" class="w-10 h-10 rounded-full border-2 border-primary">
+          <div class="ml-3">
+            <p class="text-sm font-medium">管理员</p>
+            <p class="text-xs text-neutral-light">在线</p>
+          </div>
+        </div>
+      </div>
+    </aside>
+
+    <!-- 主内容区 -->
+    <div class="flex-1 flex flex-col overflow-hidden">
+      <!-- 顶部导航 -->
+      <header class="bg-dark-100 border-b border-dark-300 px-6 py-4 flex items-center justify-between">
+        <div class="flex items-center">
+          <button id="sidebarToggle" class="mr-4 lg:hidden text-gray-300 hover:text-white">
+            <i class="fa fa-bars text-xl"></i>
+          </button>
+          
+          <div class="relative mr-6">
+            <select class="bg-dark-300 border border-dark-400 text-sm rounded-lg px-4 py-2 pr-10 appearance-none focus:outline-none focus:border-primary">
+              <option>主工厂</option>
+              <option>分工厂A</option>
+              <option>分工厂B</option>
+            </select>
+            <i class="fa fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-light"></i>
+          </div>
+        </div>
+        
+        <div class="flex items-center space-x-4">
+          <div id="currentTime" class="text-sm text-neutral-light"></div>
+          <button class="relative p-2 text-gray-300 hover:text-white">
+            <i class="fa fa-bell text-xl"></i>
+            <span class="absolute top-1 right-1 w-2 h-2 bg-danger rounded-full"></span>
+          </button>
+          <button class="p-2 text-gray-300 hover:text-white">
+            <i class="fa fa-cog text-xl"></i>
+          </button>
+        </div>
+      </header>
+
+      <!-- 内容滚动区 -->
+      <main class="flex-1 overflow-y-auto p-6 scrollbar-hide">
+        <div class="max-w-7xl mx-auto">
+          <!-- 页面标题 -->
+          <div class="mb-6">
+            <h2 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-white">工厂振动检测总览</h2>
+            <p class="text-neutral-light mt-1">实时监控全厂设备振动状态与关键指标</p>
+          </div>
+          
+          <!-- 核心指标卡片 -->
+          <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+              <div class="flex justify-between items-start">
+                <div>
+                  <p class="text-neutral-light text-sm">运行设备</p>
+                  <h3 class="text-3xl font-bold mt-1">186 <span class="text-sm font-normal text-success ml-2"><i class="fa fa-arrow-up"></i> 5%</span></h3>
+                </div>
+                <div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center text-primary">
+                  <i class="fa fa-machine text-xl"></i>
+                </div>
+              </div>
+              <div class="mt-4 text-xs text-neutral-light">
+                总设备数: 200台
+              </div>
+            </div>
+            
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+              <div class="flex justify-between items-start">
+                <div>
+                  <p class="text-neutral-light text-sm">今日预警</p>
+                  <h3 class="text-3xl font-bold mt-1">12 <span class="text-sm font-normal text-danger ml-2"><i class="fa fa-arrow-up"></i> 2</span></h3>
+                </div>
+                <div class="w-12 h-12 rounded-full bg-warning/20 flex items-center justify-center text-warning">
+                  <i class="fa fa-exclamation-triangle text-xl"></i>
+                </div>
+              </div>
+              <div class="mt-4 text-xs text-neutral-light">
+                高风险: 2, 中风险: 5, 低风险: 5
+              </div>
+            </div>
+            
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+              <div class="flex justify-between items-start">
+                <div>
+                  <p class="text-neutral-light text-sm">设备健康指数</p>
+                  <h3 class="text-3xl font-bold mt-1">78 <span class="text-sm font-normal text-success ml-2"><i class="fa fa-arrow-up"></i> 3%</span></h3>
+                </div>
+                <div class="w-12 h-12 rounded-full bg-success/20 flex items-center justify-center text-success">
+                  <i class="fa fa-heartbeat text-xl"></i>
+                </div>
+              </div>
+              <div class="mt-4">
+                <div class="w-full bg-dark-300 rounded-full h-2">
+                  <div class="bg-gradient-to-r from-success to-primary h-2 rounded-full" style="width: 78%"></div>
+                </div>
+              </div>
+            </div>
+            
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+              <div class="flex justify-between items-start">
+                <div>
+                  <p class="text-neutral-light text-sm">平均振动值</p>
+                  <h3 class="text-3xl font-bold mt-1">18.5 <span class="text-sm font-normal text-danger ml-2"><i class="fa fa-arrow-up"></i> 1.2</span> mm/s</h3>
+                </div>
+                <div class="w-12 h-12 rounded-full bg-danger/20 flex items-center justify-center text-danger">
+                  <i class="fa fa-tachometer text-xl"></i>
+                </div>
+              </div>
+              <div class="mt-4 text-xs text-neutral-light">
+                阈值: 25 mm/s
+              </div>
+            </div>
+          </div>
+          
+          <!-- 图表区域 -->
+          <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
+            <!-- 设备状态分布饼图 -->
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300 lg:col-span-1">
+              <div class="flex justify-between items-center mb-6">
+                <h3 class="font-semibold text-lg">设备状态分布</h3>
+                <div class="text-xs text-neutral-light">更新于: <span id="updateTime">10:24:36</span></div>
+              </div>
+              <div class="h-64">
+                <div id="statusPieChart" class="w-full h-full"></div>
+              </div>
+              <div class="mt-6 grid grid-cols-2 gap-4">
+                <div class="flex items-center">
+                  <span class="w-3 h-3 rounded-full bg-success mr-2"></span>
+                  <span class="text-sm">正常: 168台</span>
+                </div>
+                <div class="flex items-center">
+                  <span class="w-3 h-3 rounded-full bg-warning mr-2"></span>
+                  <span class="text-sm">警告: 28台</span>
+                </div>
+                <div class="flex items-center">
+                  <span class="w-3 h-3 rounded-full bg-danger mr-2"></span>
+                  <span class="text-sm">危险: 4台</span>
+                </div>
+                <div class="flex items-center">
+                  <span class="w-3 h-3 rounded-full bg-neutral-light/50 mr-2"></span>
+                  <span class="text-sm">停机: 0台</span>
+                </div>
+              </div>
+            </div>
+            
+            <!-- 健康指数柱状图 -->
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300 lg:col-span-2">
+              <div class="flex justify-between items-center mb-6">
+                <h3 class="font-semibold text-lg">车间健康指数</h3>
+                <div class="flex space-x-2">
+                  <button class="px-3 py-1 text-xs bg-primary/20 text-primary rounded-lg">今日</button>
+                  <button class="px-3 py-1 text-xs bg-dark-300 text-neutral-light rounded-lg hover:bg-dark-400">本周</button>
+                  <button class="px-3 py-1 text-xs bg-dark-300 text-neutral-light rounded-lg hover:bg-dark-400">本月</button>
+                </div>
+              </div>
+              <div class="h-64">
+                <div id="healthBarChart" class="w-full h-full"></div>
+              </div>
+            </div>
+          </div>
+          
+          <!-- 设备地图与预警列表 -->
+          <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
+            <!-- 设备地图视图 -->
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300 lg:col-span-2">
+              <div class="flex justify-between items-center mb-6">
+                <h3 class="font-semibold text-lg">设备位置热力图</h3>
+                <div class="text-xs text-neutral-light">刷新: <button class="text-primary hover:underline">手动</button></div>
+              </div>
+              <div class="h-80 relative bg-dark-300 rounded-lg overflow-hidden">
+                <!-- 工厂地图背景 -->
+                <img src="https://picsum.photos/id/1029/800/400" alt="工厂地图" class="w-full h-full object-cover opacity-20">
+                
+                <!-- 设备位置标记 - 动态生成 -->
+                <div class="absolute top-1/4 left-1/3" data-vibration="12">
+                  <div class="w-4 h-4 rounded-full bg-success animate-pulse-slow border-2 border-success/50 cursor-pointer" title="设备A-01: 正常 (12.5 mm/s)"></div>
+                </div>
+                <div class="absolute top-1/3 right-1/4" data-vibration="22">
+                  <div class="w-4 h-4 rounded-full bg-warning animate-pulse-slow border-2 border-warning/50 cursor-pointer" title="设备B-05: 警告 (22.3 mm/s)"></div>
+                </div>
+                <div class="absolute bottom-1/3 left-1/5" data-vibration="35">
+                  <div class="w-4 h-4 rounded-full bg-danger animate-pulse-slow border-2 border-danger/50 cursor-pointer" title="设备C-02: 危险 (35.1 mm/s)"></div>
+                </div>
+                <div class="absolute top-2/3 right-1/3" data-vibration="18">
+                  <div class="w-4 h-4 rounded-full bg-success animate-pulse-slow border-2 border-success/50 cursor-pointer" title="设备D-10: 正常 (18.2 mm/s)"></div>
+                </div>
+                
+                <!-- 图例 -->
+                <div class="absolute bottom-4 right-4 bg-dark-100/80 backdrop-blur-sm p-3 rounded-lg border border-dark-300">
+                  <div class="flex items-center mb-2">
+                    <span class="w-3 h-3 rounded-full bg-success mr-2"></span>
+                    <span class="text-xs">正常 &lt;20</span>
+                  </div>
+                  <div class="flex items-center mb-2">
+                    <span class="w-3 h-3 rounded-full bg-warning mr-2"></span>
+                    <span class="text-xs">警告 20-25</span>
+                  </div>
+                  <div class="flex items-center">
+                    <span class="w-3 h-3 rounded-full bg-danger mr-2"></span>
+                    <span class="text-xs">危险 &gt;25</span>
+                  </div>
+                </div>
+              </div>
+            </div>
+            
+            <!-- 实时警报列表 -->
+            <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+              <div class="flex justify-between items-center mb-6">
+                <h3 class="font-semibold text-lg">实时警报</h3>
+                <span class="text-xs bg-danger/20 text-danger px-2 py-1 rounded-full">紧急</span>
+              </div>
+              <div class="space-y-4 max-h-80 overflow-y-auto pr-2 scrollbar-hide">
+                <!-- 警报项1 - 危险 -->
+                <div class="bg-dark-300/50 border-l-4 border-danger p-4 rounded-lg">
+                  <div class="flex justify-between items-start">
+                    <div>
+                      <h4 class="font-medium text-sm">设备C-02振动异常</h4>
+                      <p class="text-xs text-neutral-light mt-1">振动值: 35.1 mm/s (阈值: 25 mm/s)</p>
+                    </div>
+                    <span class="text-xs text-danger">10:22</span>
+                  </div>
+                  <div class="mt-3 flex justify-between items-center">
+                    <span class="text-xs bg-danger/20 text-danger px-2 py-1 rounded-full">高风险</span>
+                    <button class="text-xs text-primary hover:underline">处理</button>
+                  </div>
+                </div>
+                
+                <!-- 警报项2 - 警告 -->
+                <div class="bg-dark-300/50 border-l-4 border-warning p-4 rounded-lg">
+                  <div class="flex justify-between items-start">
+                    <div>
+                      <h4 class="font-medium text-sm">设备B-05振动升高</h4>
+                      <p class="text-xs text-neutral-light mt-1">振动值: 22.3 mm/s (阈值: 25 mm/s)</p>
+                    </div>
+                    <span class="text-xs text-warning">10:15</span>
+                  </div>
+                  <div class="mt-3 flex justify-between items-center">
+                    <span class="text-xs bg-warning/20 text-warning px-2 py-1 rounded-full">中风险</span>
+                    <button class="text-xs text-primary hover:underline">确认</button>
+                  </div>
+                </div>
+                
+                <!-- 警报项3 - 警告 -->
+                <div class="bg-dark-300/50 border-l-4 border-warning p-4 rounded-lg">
+                  <div class="flex justify-between items-start">
+                    <div>
+                      <h4 class="font-medium text-sm">设备E-08轴承振动异常</h4>
+                      <p class="text-xs text-neutral-light mt-1">振动值: 21.8 mm/s (阈值: 25 mm/s)</p>
+                    </div>
+                    <span class="text-xs text-warning">10:08</span>
+                  </div>
+                  <div class="mt-3 flex justify-between items-center">
+                    <span class="text-xs bg-warning/20 text-warning px-2 py-1 rounded-full">中风险</span>
+                    <button class="text-xs text-primary hover:underline">确认</button>
+                  </div>
+                </div>
+                
+                <!-- 警报项4 - 正常 -->
+                <div class="bg-dark-300/50 border-l-4 border-success p-4 rounded-lg">
+                  <div class="flex justify-between items-start">
+                    <div>
+                      <h4 class="font-medium text-sm">设备A-01恢复正常</h4>
+                      <p class="text-xs text-neutral-light mt-1">振动值: 12.5 mm/s (阈值: 25 mm/s)</p>
+                    </div>
+                    <span class="text-xs text-success">09:55</span>
+                  </div>
+                  <div class="mt-3 flex justify-between items-center">
+                    <span class="text-xs bg-success/20 text-success px-2 py-1 rounded-full">已恢复</span>
+                    <button class="text-xs text-primary hover:underline">已处理</button>
+                  </div>
+                </div>
+              </div>
+              <button class="w-full mt-4 text-sm text-primary hover:underline flex items-center justify-center">
+                查看全部警报 <i class="fa fa-angle-right ml-2"></i>
+              </button>
+            </div>
+          </div>
+          
+          <!-- 健康指数趋势图 -->
+          <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300 mb-8">
+            <div class="flex justify-between items-center mb-6">
+              <h3 class="font-semibold text-lg">健康指数趋势</h3>
+              <div class="flex space-x-2">
+                <button class="px-3 py-1 text-xs bg-primary/20 text-primary rounded-lg">24小时</button>
+                <button class="px-3 py-1 text-xs bg-dark-300 text-neutral-light rounded-lg hover:bg-dark-400">7天</button>
+                <button class="px-3 py-1 text-xs bg-dark-300 text-neutral-light rounded-lg hover:bg-dark-400">30天</button>
+              </div>
+            </div>
+            <div class="h-64">
+              <div id="trendLineChart" class="w-full h-full"></div>
+            </div>
+          </div>
+          
+          <!-- 关键设备监控 -->
+          <div class="bg-dark-100 rounded-xl p-6 card-hover border border-dark-300">
+            <div class="flex justify-between items-center mb-6">
+              <h3 class="font-semibold text-lg">关键设备监控</h3>
+              <div class="relative">
+                <select class="bg-dark-300 border border-dark-400 text-sm rounded-lg px-4 py-2 pr-10 appearance-none focus:outline-none focus:border-primary">
+                  <option>全部车间</option>
+                  <option>装配车间</option>
+                  <option>加工车间</option>
+                  <option>涂装车间</option>
+                </select>
+                <i class="fa fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-light"></i>
+              </div>
+            </div>
+            
+            <div class="overflow-x-auto">
+              <table class="min-w-full">
+                <thead>
+                  <tr class="border-b border-dark-300">
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">设备编号</th>
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">设备名称</th>
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">车间</th>
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">振动值 (mm/s)</th>
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">健康状态</th>
+                    <th class="text-left py-3 px-4 text-xs font-medium text-neutral-light">操作</th>
+                  </tr>
+                </thead>
+                <tbody>
+                  <!-- 设备行1 - 危险 -->
+                  <tr class="border-b border-dark-300 hover:bg-dark-300/50 transition-colors">
+                    <td class="py-3 px-4 text-sm">C-02</td>
+                    <td class="py-3 px-4 text-sm">主轴电机</td>
+                    <td class="py-3 px-4 text-sm">加工车间</td>
+                    <td class="py-3 px-4 text-sm">35.1 <span class="text-danger ml-1"><i class="fa fa-arrow-up"></i></span></td>
+                    <td class="py-3 px-4">
+                      <span class="px-2 py-1 text-xs rounded-full bg-danger/20 text-danger">危险</span>
+                    </td>
+                    <td class="py-3 px-4">
+                      <button class="text-primary hover:underline text-sm">详情</button>
+                    </td>
+                  </tr>
+                  
+                  <!-- 设备行2 - 警告 -->
+                  <tr class="border-b border-dark-300 hover:bg-dark-300/50 transition-colors">
+                    <td class="py-3 px-4 text-sm">B-05</td>
+                    <td class="py-3 px-4 text-sm">传送带电机</td>
+                    <td class="py-3 px-4 text-sm">装配车间</td>
+                    <td class="py-3 px-4 text-sm">22.3 <span class="text-warning ml-1"><i class="fa fa-arrow-up"></i></span></td>
+                    <td class="py-3 px-4">
+                      <span class="px-2 py-1 text-xs rounded-full bg-warning/20 text-warning">警告</span>
+                    </td>
+                    <td class="py-3 px-4">
+                      <button class="text-primary hover:underline text-sm">详情</button>
+                    </td>
+                  </tr>
+                  
+                  <!-- 设备行3 - 正常 -->
+                  <tr class="border-b border-dark-300 hover:bg-dark-300/50 transition-colors">
+                    <td class="py-3 px-4 text-sm">A-01</td>
+                    <td class="py-3 px-4 text-sm">冲压机</td>
+                    <td class="py-3 px-4 text-sm">加工车间</td>
+                    <td class="py-3 px-4 text-sm">12.5 <span class="text-success ml-1"><i class="fa fa-arrow-down"></i></span></td>
+                    <td class="py-3 px-4">
+                      <span class="px-2 py-1 text-xs rounded-full bg-success/20 text-success">正常</span>
+                    </td>
+                    <td class="py-3 px-4">
+                      <button class="text-primary hover:underline text-sm">详情</button>
+                    </td>
+                  </tr>
+                  
+                  <!-- 设备行4 - 正常 -->
+                  <tr class="border-b border-dark-300 hover:bg-dark-300/50 transition-colors">
+                    <td class="py-3 px-4 text-sm">D-10</td>
+                    <td class="py-3 px-4 text-sm">烘干机</td>
+                    <td class="py-3 px-4 text-sm">涂装车间</td>
+                    <td class="py-3 px-4 text-sm">18.2 <span class="text-neutral-light ml-1"><i class="fa fa-minus"></i></span></td>
+                    <td class="py-3 px-4">
+                      <span class="px-2 py-1 text-xs rounded-full bg-success/20 text-success">正常</span>
+                    </td>
+                    <td class="py-3 px-4">
+                      <button class="text-primary hover:underline text-sm">详情</button>
+                    </td>
+                  </tr>
+                  
+                  <!-- 设备行5 - 正常 -->
+                  <tr class="hover:bg-dark-300/50 transition-colors">
+                    <td class="py-3 px-4 text-sm">E-08</td>
+                    <td class="py-3 px-4 text-sm">风机</td>
+                    <td class="py-3 px-4 text-sm">装配车间</td>
+                    <td class="py-3 px-4 text-sm">21.8 <span class="text-warning ml-1"><i class="fa fa-arrow-up"></i></span></td>
+                    <td class="py-3 px-4">
+                      <span class="px-2 py-1 text-xs rounded-full bg-warning/20 text-warning">警告</span>
+                    </td>
+                    <td class="py-3 px-4">
+                      <button class="text-primary hover:underline text-sm">详情</button>
+                    </td>
+                  </tr>
+                </tbody>
+              </table>
+            </div>
+            
+            <button class="mt-6 w-full py-2 border border-primary text-primary rounded-lg hover:bg-primary/10 transition-colors">
+              加载更多设备
+            </button>
+          </div>
+        </div>
+      </main>
+    </div>
+  </div>
+
+  <script>
+    // 更新当前时间
+    function updateTime() {
+      const now = new Date();
+      const timeString = now.toLocaleTimeString('zh-CN', {
+        hour: '2-digit',
+        minute: '2-digit',
+        second: '2-digit'
+      });
+      document.getElementById('currentTime').textContent = timeString;
+      document.getElementById('updateTime').textContent = timeString;
+    }
+    
+    setInterval(updateTime, 1000);
+    updateTime(); // 初始调用
+    
+    // 侧边栏切换
+    document.getElementById('sidebarToggle').addEventListener('click', function() {
+      const sidebar = document.getElementById('sidebar');
+      sidebar.classList.toggle('translate-x-0');
+      sidebar.classList.toggle('-translate-x-full');
+    });
+    
+    // ECharts 图表初始化
+    document.addEventListener('DOMContentLoaded', function() {
+      // 设备状态分布饼图
+      const statusPieChart = echarts.init(document.getElementById('statusPieChart'));
+      const statusPieOption = {
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b}: {c} ({d}%)'
+        },
+        series: [
+          {
+            name: '设备状态',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderRadius: 10,
+              borderColor: '#1D2129',
+              borderWidth: 1
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: '16',
+                fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              {value: 168, name: '正常', itemStyle: {color: '#00B42A'}},
+              {value: 28, name: '警告', itemStyle: {color: '#FF7D00'}},
+              {value: 4, name: '危险', itemStyle: {color: '#F53F3F'}},
+              {value: 0, name: '停机', itemStyle: {color: '#86909C'}}
+            ]
+          }
+        ]
+      };
+      statusPieChart.setOption(statusPieOption);
+      
+      // 车间健康指数柱状图
+      const healthBarChart = echarts.init(document.getElementById('healthBarChart'));
+      const healthBarOption = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        xAxis: {
+          type: 'category',
+          data: ['装配车间', '加工车间', '涂装车间', '仓储车间', '动力车间'],
+          axisTick: {
+            alignWithLabel: true
+          },
+          axisLine: {
+            lineStyle: {
+              color: '#333'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          min: 0,
+          max: 100,
+          splitLine: {
+            lineStyle: {
+              color: '#333'
+            }
+          }
+        },
+        series: [
+          {
+            name: '健康指数',
+            type: 'bar',
+            barWidth: '60%',
+            data: [85, 68, 92, 76, 88],
+            itemStyle: {
+              color: function(params) {
+                const colorList = ['#165DFF', '#165DFF', '#165DFF', '#165DFF', '#165DFF'];
+                if (params.data < 70) colorList[params.dataIndex] = '#F53F3F';
+                else if (params.data < 80) colorList[params.dataIndex] = '#FF7D00';
+                return colorList[params.dataIndex];
+              },
+              borderRadius: 4
+            }
+          }
+        ]
+      };
+      healthBarChart.setOption(healthBarOption);
+      
+      // 健康指数趋势图
+      const trendLineChart = echarts.init(document.getElementById('trendLineChart'));
+      const trendLineOption = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'cross'
+          }
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: Array(24).fill('').map((_, i) => i + '时'),
+          axisLine: {
+            lineStyle: {
+              color: '#333'
+            }
+          }
+        },
+        yAxis: [
+          {
+            type: 'value',
+            name: '健康指数',
+            min: 0,
+            max: 100,
+            interval: 20,
+            axisLine: {
+              lineStyle: {
+                color: '#165DFF'
+              }
+            },
+            splitLine: {
+              lineStyle: {
+                color: '#333'
+              }
+            },
+            axisLabel: {
+              textStyle: {
+                color: '#165DFF'
+              }
+            }
+          },
+          {
+            type: 'value',
+            name: '振动值 (mm/s)',
+            min: 0,
+            max: 40,
+            interval: 10,
+            axisLine: {
+              lineStyle: {
+                color: '#F53F3F'
+              }
+            },
+            splitLine: {
+              show: false
+            },
+            axisLabel: {
+              textStyle: {
+                color: '#F53F3F'
+              }
+            }
+          }
+        ],
+        series: [
+          {
+            name: '健康指数',
+            type: 'line',
+            yAxisIndex: 0,
+            data: [75, 76, 77, 78, 76, 75, 74, 73, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 81, 80, 79, 78, 77],
+            symbolSize: 6,
+            itemStyle: {
+              color: '#165DFF'
+            },
+            lineStyle: {
+              color: '#165DFF'
+            },
+            areaStyle: {
+              color: {
+                type: 'linear',
+                x: 0,
+                y: 0,
+                x2: 0,
+                y2: 1,
+                colorStops: [{
+                  offset: 0,
+                  color: 'rgba(22, 93, 255, 0.5)'
+                }, {
+                  offset: 1,
+                  color: 'rgba(22, 93, 255, 0.05)'
+                }]
+              }
+            }
+          },
+          {
+            name: '振动值',
+            type: 'line',
+            yAxisIndex: 1,
+            data: [18, 17, 16, 15, 17, 19, 21, 22, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 15, 16, 17, 18, 19, 20],
+            symbolSize: 6,
+            itemStyle: {
+              color: '#F53F3F'
+            },
+            lineStyle: {
+              color: '#F53F3F'
+            },
+            areaStyle: {
+              color: {
+                type: 'linear',
+                x: 0,
+                y: 0,
+                x2: 0,
+                y2: 1,
+                colorStops: [{
+                  offset: 0,
+                  color: 'rgba(245, 63, 63, 0.5)'
+                }, {
+                  offset: 1,
+                  color: 'rgba(245, 63, 63, 0.05)'
+                }]
+              }
+            }
+          }
+        ]
+      };
+      trendLineChart.setOption(trendLineOption);
+      
+      // 窗口大小改变时重新渲染图表
+      window.addEventListener('resize', function() {
+        statusPieChart.resize();
+        healthBarChart.resize();
+        trendLineChart.resize();
+      });
+    });
+    
+    // 设备地图标记交互效果
+    document.querySelectorAll('[data-vibration]').forEach(marker => {
+      marker.addEventListener('mouseenter', function() {
+        this.querySelector('div').classList.add('scale-150');
+      });
+      marker.addEventListener('mouseleave', function() {
+        this.querySelector('div').classList.remove('scale-150');
+      });
+    });
+  </script>
+</body>
+</html>

+ 6 - 1
industry-monitor-web/src/app/layout/main-layout/main-layout.css

@@ -12,6 +12,8 @@
   color: white;
   color: white;
   padding: 20px 0;
   padding: 20px 0;
   box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
   box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
+  border-radius: 6px;
+  margin: 8px 0 8px 8px; /* 添加少量外边距让圆角可见 */
 }
 }
 
 
 .nav-header {
 .nav-header {
@@ -29,7 +31,7 @@
 .nav-links {
 .nav-links {
   list-style: none;
   list-style: none;
   padding: 0;
   padding: 0;
-  margin: 0;
+  margin: 0 10px; /* 添加边距让圆角可见 */
 }
 }
 
 
 .nav-links li {
 .nav-links li {
@@ -42,6 +44,7 @@
   text-decoration: none;
   text-decoration: none;
   padding: 12px 20px;
   padding: 12px 20px;
   transition: all 0.3s ease;
   transition: all 0.3s ease;
+  border-radius: 4px;
 }
 }
 
 
 .nav-links a:hover {
 .nav-links a:hover {
@@ -63,4 +66,6 @@
   padding: 20px;
   padding: 20px;
   background-color: white;
   background-color: white;
   overflow-y: auto;
   overflow-y: auto;
+  border-radius: 6px;
+  margin: 8px 8px 8px 0; /* 添加少量外边距让圆角可见 */
 }
 }

+ 42 - 68
industry-monitor-web/src/app/pages/device-monitor/device-monitor.component.html

@@ -1,37 +1,41 @@
-
 <!-- device-monitor.component.html -->
 <!-- device-monitor.component.html -->
 <div class="monitor-container">
 <div class="monitor-container">
   <div class="monitor-header">
   <div class="monitor-header">
     <h2><i class="fa fa-microchip"></i> 单设备监测面板</h2>
     <h2><i class="fa fa-microchip"></i> 单设备监测面板</h2>
-    <div class="device-info">
-      <div><strong>设备名称:</strong> CNC 铣床 #01</div>
-      <div><strong>设备编号:</strong> DEV-2023-001</div>
-      <div><strong>位置:</strong> 车间A - 产线3</div>
-      <div><strong>设备类型:</strong> CNC加工中心</div>
+    <div class="header-info">
+      <div class="device-info">
+        <div><strong>设备名称:</strong> CNC 铣床 #01</div>
+        <div><strong>设备编号:</strong> DEV-2023-001</div>
+        <div><strong>位置:</strong> 车间A - 产线3</div>
+        <div><strong>设备类型:</strong> CNC加工中心</div>
+      </div>
+      <div class="current-time">
+        <strong>当前时间:</strong> {{ currentTime | date: 'yyyy-MM-dd HH:mm:ss' }}
+      </div>
     </div>
     </div>
   </div>
   </div>
 
 
   <div class="monitor-row">
   <div class="monitor-row">
     <div class="waveform-card">
     <div class="waveform-card">
       <h3><i class="fa fa-wave-square"></i> 振动波形图 (40秒周期)</h3>
       <h3><i class="fa fa-wave-square"></i> 振动波形图 (40秒周期)</h3>
-      <div class="waveform-container">
-        <div class="waveform-grid">
-          <div class="grid-line"></div>
-          <div class="grid-line"></div>
-          <div class="grid-line"></div>
-          <div class="waveform-line"></div>
-          <div class="threshold upper"></div>
-          <div class="threshold lower"></div>
-        </div>
+      <!-- 修改1: 使用 appEchart 指令和 echartOptions 绑定 -->
+      <div class="waveform-container"
+           appEchart
+           [echartOptions]="chartOptions">
       </div>
       </div>
       <div class="waveform-controls">
       <div class="waveform-controls">
         <div class="threshold-control">
         <div class="threshold-control">
-          <label>阈值上限: <span id="upperValue">0.8</span> mm/s</label>
-          <input type="range" min="0" max="1.5" step="0.1" value="0.8" id="upperThreshold">
+          <label>阈值上限: {{ upperThreshold }} mm/s</label>
+          <!-- 修改2: 更新滑块绑定 -->
+          <input type="range" min="0.1" max="1.5" step="0.05"
+                 [(ngModel)]="upperThreshold"
+                 (input)="updateThreshold()">
         </div>
         </div>
         <div class="threshold-control">
         <div class="threshold-control">
-          <label>阈值下限: <span id="lowerValue">0.2</span> mm/s</label>
-          <input type="range" min="0" max="1.5" step="0.1" value="0.2" id="lowerThreshold">
+          <label>阈值下限: {{ lowerThreshold }} mm/s</label>
+          <input type="range" min="0.1" max="1.5" step="0.05"
+                 [(ngModel)]="lowerThreshold"
+                 (input)="updateThreshold()">
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
@@ -39,44 +43,18 @@
     <div class="status-panel">
     <div class="status-panel">
       <h3><i class="fa fa-heartbeat"></i> 实时状态</h3>
       <h3><i class="fa fa-heartbeat"></i> 实时状态</h3>
       <div class="status-grid">
       <div class="status-grid">
-        <div class="status-card">
-          <div class="status-icon blue">
-            <i class="fa fa-wave-square"></i>
+        <!-- 修改3: 修复 ngClass 绑定 -->
+        <div class="status-card" *ngFor="let status of statusValues">
+          <div class="status-icon" [ngClass]="status.color">
+            <i class="fa" [ngClass]="status.icon"></i>
           </div>
           </div>
           <div class="status-data">
           <div class="status-data">
-            <div class="status-label">当前振幅</div>
-            <div class="status-value">0.58 mm/s</div>
-          </div>
-        </div>
-        <div class="status-card">
-          <div class="status-icon green">
-            <i class="fa fa-heartbeat"></i>
-          </div>
-          <div class="status-data">
-            <div class="status-label">健康指数</div>
-            <div class="status-value">89%</div>
-          </div>
-        </div>
-        <div class="status-card">
-          <div class="status-icon orange">
-            <i class="fa fa-thermometer-half"></i>
-          </div>
-          <div class="status-data">
-            <div class="status-label">温度</div>
-            <div class="status-value">68°C</div>
-          </div>
-        </div>
-        <div class="status-card">
-          <div class="status-icon purple">
-            <i class="fa fa-tachometer-alt"></i>
-          </div>
-          <div class="status-data">
-            <div class="status-label">转速</div>
-            <div class="status-value">1420 RPM</div>
+            <div class="status-label">{{ status.label }}</div>
+            <div class="status-value">{{ status.value }} {{ status.unit }}</div>
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
-      
+
       <div class="progress-container">
       <div class="progress-container">
         <h4>工序进度</h4>
         <h4>工序进度</h4>
         <div class="progress-steps">
         <div class="progress-steps">
@@ -100,23 +78,19 @@
         <button class="btn"><i class="fa fa-download"></i> 数据导出</button>
         <button class="btn"><i class="fa fa-download"></i> 数据导出</button>
       </div>
       </div>
     </div>
     </div>
-    
+
     <div class="alert-history">
     <div class="alert-history">
-      <div class="history-item">
-        <div class="alert-time">14:30:22</div>
-        <div class="alert-desc">振动超标 (0.92 mm/s)</div>
-        <div class="alert-level warning">警告</div>
-      </div>
-      <div class="history-item">
-        <div class="alert-time">11:45:10</div>
-        <div class="alert-desc">温度异常 (78°C)</div>
-        <div class="alert-level critical">严重</div>
-      </div>
-      <div class="history-item">
-        <div class="alert-time">09:15:33</div>
-        <div class="alert-desc">转速波动超出范围</div>
-        <div class="alert-level info">注意</div>
+      <!-- 修改4: 修复 ngClass 绑定 -->
+      <div class="history-item" *ngFor="let alert of alertHistory">
+        <div class="alert-time">{{ alert.time }}</div>
+        <div class="alert-desc">{{ alert.desc }}</div>
+        <div class="alert-level" [ngClass]="alert.level">
+          {{
+            alert.level === 'warning' ? '警告' :
+            alert.level === 'critical' ? '严重' : '注意'
+          }}
+        </div>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
-</div>
+</div>

+ 151 - 8
industry-monitor-web/src/app/pages/device-monitor/device-monitor.component.ts

@@ -1,21 +1,164 @@
-import { Component, ViewEncapsulation } from '@angular/core';
+import { Component, ViewEncapsulation, OnInit } from '@angular/core';
 import { DatePipe } from '@angular/common';
 import { DatePipe } from '@angular/common';
+import * as echarts from 'echarts';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { EchartDirective } from '../../shared/directives/echarts.directive';
 
 
 @Component({
 @Component({
   standalone: true,
   standalone: true,
   selector: 'app-device-monitor',
   selector: 'app-device-monitor',
-  styleUrls: ['./device-monitor.css'],
-  imports: [DatePipe],
   templateUrl: './device-monitor.component.html',
   templateUrl: './device-monitor.component.html',
+  styleUrls: ['./device-monitor.css'],
+  imports: [
+    DatePipe,
+    CommonModule,
+    FormsModule,
+    EchartDirective
+  ],
   encapsulation: ViewEncapsulation.None
   encapsulation: ViewEncapsulation.None
 })
 })
-export class DeviceMonitorComponent {
-currentTime: Date = new Date();
-   ngOnInit(): void {
-    // 更新时间,每秒更新一次
+export class DeviceMonitorComponent implements OnInit {
+  currentTime: Date = new Date();
+  vibrationData: number[] = [];
+  upperThreshold = 0.8;
+  lowerThreshold = 0.2;
+  currentAmplitude = 0.58;
+  healthIndex = 89;
+  temperature = 68;
+  rotationSpeed = 1420;
+  chartOptions: any;
+
+  statusValues = [
+    { label: '当前振幅', value: 0.58, unit: 'mm/s', icon: 'fa-wave-square', color: 'blue' },
+    { label: '健康指数', value: 89, unit: '%', icon: 'fa-heartbeat', color: 'green' },
+    { label: '温度', value: 68, unit: '°C', icon: 'fa-thermometer-half', color: 'orange' },
+    { label: '转速', value: 1420, unit: 'RPM', icon: 'fa-tachometer-alt', color: 'purple' }
+  ];
+
+  alertHistory = [
+    { time: '14:30:22', desc: '振动超标 (0.92 mm/s)', level: 'warning' },
+    { time: '11:45:10', desc: '温度异常 (78°C)', level: 'critical' },
+    { time: '09:15:33', desc: '转速波动超出范围', level: 'info' }
+  ];
+
+  ngOnInit(): void {
     setInterval(() => {
     setInterval(() => {
       this.currentTime = new Date();
       this.currentTime = new Date();
     }, 1000);
     }, 1000);
 
 
-   }
+    this.generateVibrationData();
+    this.updateChartOptions();
+
+    setInterval(() => {
+      this.updateSensorData();
+    }, 3000);
+  }
+
+  generateVibrationData(): void {
+    for (let i = 0; i < 200; i++) {
+      const baseValue = Math.sin(i * 0.2) * 0.5;
+      const noise = (Math.random() - 0.5) * 0.2;
+      this.vibrationData.push(baseValue + noise + 0.5);
+    }
+  }
+
+  updateSensorData(): void {
+    this.currentAmplitude = 0.4 + Math.random() * 0.5;
+    this.healthIndex = Math.max(70, Math.min(95, this.healthIndex + (Math.random() - 0.5) * 5));
+    this.temperature = Math.max(60, Math.min(75, this.temperature + (Math.random() - 0.5) * 2));
+    this.rotationSpeed = 1400 + Math.floor(Math.random() * 50);
+
+    this.statusValues[0].value = parseFloat(this.currentAmplitude.toFixed(2));
+    this.statusValues[1].value = Math.round(this.healthIndex);
+    this.statusValues[2].value = Math.round(this.temperature);
+    this.statusValues[3].value = this.rotationSpeed;
+
+    // 更新振动数据
+    this.vibrationData.shift();
+    const newValue = 0.4 + Math.random() * 0.6;
+    this.vibrationData.push(newValue);
+
+    // 更新图表
+    this.updateChartOptions();
+  }
+
+  updateChartOptions(): void {
+    this.chartOptions = {
+      tooltip: {
+        trigger: 'axis',
+        formatter: (params: any) => {
+          const value = params[0].value;
+          let status = '正常';
+          if (value > this.upperThreshold) status = '超标';
+          if (value < this.lowerThreshold) status = '过低';
+
+          return `时间: ${params[0].name}<br/>振幅: ${value.toFixed(2)} mm/s<br/>状态: ${status}`;
+        }
+      },
+      grid: {
+        left: '3%',
+        right: '4%',
+        bottom: '12%',
+        top: '10%',
+        containLabel: true
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: Array.from({length: 200}, (_, i) => `${i*0.2}s`),
+        axisLine: { show: false },
+        axisTick: { show: false },
+        axisLabel: { show: false }
+      },
+      yAxis: {
+        type: 'value',
+        min: 0,
+        max: 1.5,
+        splitLine: {
+          lineStyle: { color: 'rgba(0, 0, 0, 0.05)' }
+        },
+        axisLabel: { formatter: '{value} mm/s' }
+      },
+      series: [
+        {
+          name: '振动波形',
+          type: 'line',
+          smooth: true,
+          symbol: 'none',
+          sampling: 'average',
+          data: this.vibrationData,
+          lineStyle: { width: 2, color: '#3498db' },
+          areaStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: 'rgba(52, 152, 219, 0.3)' },
+              { offset: 1, color: 'rgba(52, 152, 219, 0.1)' }
+            ])
+          },
+          markLine: {
+            silent: true,
+            symbol: 'none',
+            lineStyle: { color: '#e74c3c', width: 1, type: 'dashed' },
+            data: [
+              {
+                name: '阈值上限',
+                yAxis: this.upperThreshold,
+                label: { formatter: '上限: {c} mm/s', position: 'end' }
+              },
+              {
+                name: '阈值下限',
+                yAxis: this.lowerThreshold,
+                label: { formatter: '下限: {c} mm/s', position: 'end' }
+              }
+            ]
+          }
+        }
+      ],
+      animation: false
+    };
+  }
+
+  updateThreshold(): void {
+    this.updateChartOptions();
+  }
 }
 }

+ 116 - 52
industry-monitor-web/src/app/pages/device-monitor/device-monitor.css

@@ -1,8 +1,9 @@
-/* device-monitor.component.css */
+device-monitor.component.css
 :host {
 :host {
   display: block;
   display: block;
   width: 100%;
   width: 100%;
   padding: 15px;
   padding: 15px;
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 }
 
 
 .monitor-container {
 .monitor-container {
@@ -31,6 +32,12 @@
   color: #2c3e50;
   color: #2c3e50;
 }
 }
 
 
+.header-info {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+}
+
 .device-info {
 .device-info {
   display: grid;
   display: grid;
   grid-template-columns: repeat(2, 1fr);
   grid-template-columns: repeat(2, 1fr);
@@ -39,6 +46,15 @@
   background: #f8fafc;
   background: #f8fafc;
   padding: 15px;
   padding: 15px;
   border-radius: 6px;
   border-radius: 6px;
+  margin-bottom: 10px;
+}
+
+.current-time {
+  font-size: 14px;
+  background: #f8fafc;
+  padding: 8px 15px;
+  border-radius: 4px;
+  font-weight: 500;
 }
 }
 
 
 .monitor-row {
 .monitor-row {
@@ -47,12 +63,20 @@
   margin-bottom: 20px;
   margin-bottom: 20px;
 }
 }
 
 
+@media (max-width: 1200px) {
+  .monitor-row {
+    flex-direction: column;
+  }
+}
+
 .waveform-card {
 .waveform-card {
   flex: 2;
   flex: 2;
   background: white;
   background: white;
   border-radius: 8px;
   border-radius: 8px;
   padding: 20px;
   padding: 20px;
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+  display: flex;
+  flex-direction: column;
 }
 }
 
 
 .status-panel {
 .status-panel {
@@ -61,66 +85,24 @@
   border-radius: 8px;
   border-radius: 8px;
   padding: 20px;
   padding: 20px;
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+  display: flex;
+  flex-direction: column;
 }
 }
 
 
 .waveform-container {
 .waveform-container {
   height: 250px;
   height: 250px;
-  background: #f1f8ff;
+  background: #f8fafc;
   border-radius: 6px;
   border-radius: 6px;
-  margin: 20px 0;
+  margin: 15px 0;
   position: relative;
   position: relative;
   overflow: hidden;
   overflow: hidden;
+  border: 1px solid #eee;
 }
 }
 
 
-.waveform-grid {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-}
-
-.grid-line {
-  position: absolute;
-  height: 1px;
-  background: rgba(0, 0, 0, 0.05);
-  left: 0;
-  right: 0;
-}
-
-.grid-line:nth-child(1) { top: 25%; }
-.grid-line:nth-child(2) { top: 50%; }
-.grid-line:nth-child(3) { top: 75%; }
-
-.waveform-line {
-  position: absolute;
-  top: 50%;
-  left: 0;
-  right: 0;
-  height: 3px;
-  background: #3498db;
-  animation: waveform 8s infinite linear;
-}
-
-@keyframes waveform {
-  0% { transform: translateX(0); }
-  100% { transform: translateX(-100%); }
-}
-
-.threshold {
-  position: absolute;
-  left: 0;
-  right: 0;
-  height: 2px;
-  background: #e74c3c;
-}
-
-.threshold.upper { top: 25%; }
-.threshold.lower { top: 75%; }
-
 .waveform-controls {
 .waveform-controls {
   display: flex;
   display: flex;
   gap: 20px;
   gap: 20px;
+  margin-top: 15px;
 }
 }
 
 
 .threshold-control {
 .threshold-control {
@@ -131,10 +113,26 @@
   display: block;
   display: block;
   margin-bottom: 8px;
   margin-bottom: 8px;
   font-size: 14px;
   font-size: 14px;
+  font-weight: 500;
 }
 }
 
 
 .threshold-control input {
 .threshold-control input {
   width: 100%;
   width: 100%;
+  height: 6px;
+  border-radius: 3px;
+  background: #e0e7ff;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.threshold-control input::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  width: 18px;
+  height: 18px;
+  border-radius: 50%;
+  background: #3498db;
+  cursor: pointer;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
 }
 }
 
 
 .status-grid {
 .status-grid {
@@ -150,8 +148,14 @@
   gap: 15px;
   gap: 15px;
   padding: 15px;
   padding: 15px;
   background: #f8fafc;
   background: #f8fafc;
-  border-radius: 6px;
-  border-left: 3px solid #3498db;
+  border-radius: 8px;
+  transition: all 0.3s ease;
+  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+}
+
+.status-card:hover {
+  transform: translateY(-3px);
+  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
 }
 }
 
 
 .status-icon {
 .status-icon {
@@ -163,6 +167,7 @@
   justify-content: center;
   justify-content: center;
   font-size: 18px;
   font-size: 18px;
   color: white;
   color: white;
+  flex-shrink: 0;
 }
 }
 
 
 .status-icon.blue { background: #3498db; }
 .status-icon.blue { background: #3498db; }
@@ -186,6 +191,10 @@
   color: #2c3e50;
   color: #2c3e50;
 }
 }
 
 
+.progress-container {
+  margin-top: auto;
+}
+
 .progress-steps {
 .progress-steps {
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
@@ -202,6 +211,23 @@
   justify-content: center;
   justify-content: center;
   font-weight: 700;
   font-weight: 700;
   color: #95a5a6;
   color: #95a5a6;
+  position: relative;
+  transition: all 0.3s ease;
+}
+
+.step::after {
+  content: '';
+  position: absolute;
+  top: 50%;
+  left: 100%;
+  width: 20px;
+  height: 2px;
+  background: #ecf0f1;
+  z-index: 1;
+}
+
+.step:last-child::after {
+  display: none;
 }
 }
 
 
 .step.active {
 .step.active {
@@ -209,10 +235,15 @@
   color: white;
   color: white;
 }
 }
 
 
+.step.active::after {
+  background: #3498db;
+}
+
 .step.current {
 .step.current {
   background: #27ae60;
   background: #27ae60;
   color: white;
   color: white;
   transform: scale(1.2);
   transform: scale(1.2);
+  box-shadow: 0 0 0 4px rgba(39, 174, 96, 0.3);
 }
 }
 
 
 .history-panel {
 .history-panel {
@@ -229,6 +260,30 @@
   margin-bottom: 15px;
   margin-bottom: 15px;
 }
 }
 
 
+.controls {
+  display: flex;
+  gap: 10px;
+}
+
+.btn {
+  padding: 8px 15px;
+  border-radius: 4px;
+  border: none;
+  background: #3498db;
+  color: white;
+  font-weight: 500;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  transition: all 0.2s;
+}
+
+.btn:hover {
+  background: #2980b9;
+  transform: translateY(-2px);
+}
+
 .alert-history {
 .alert-history {
   border: 1px solid #eee;
   border: 1px solid #eee;
   border-radius: 6px;
   border-radius: 6px;
@@ -240,6 +295,11 @@
   align-items: center;
   align-items: center;
   padding: 12px 15px;
   padding: 12px 15px;
   border-bottom: 1px solid #eee;
   border-bottom: 1px solid #eee;
+  transition: background 0.2s;
+}
+
+.history-item:hover {
+  background: #f9f9f9;
 }
 }
 
 
 .history-item:last-child {
 .history-item:last-child {
@@ -250,6 +310,7 @@
   width: 90px;
   width: 90px;
   font-weight: 500;
   font-weight: 500;
   color: #2c3e50;
   color: #2c3e50;
+  flex-shrink: 0;
 }
 }
 
 
 .alert-desc {
 .alert-desc {
@@ -261,6 +322,9 @@
   border-radius: 4px;
   border-radius: 4px;
   font-size: 13px;
   font-size: 13px;
   font-weight: 500;
   font-weight: 500;
+  width: 60px;
+  text-align: center;
+  flex-shrink: 0;
 }
 }
 
 
 .alert-level.warning {
 .alert-level.warning {
@@ -279,4 +343,4 @@
   background: #ebf5fb;
   background: #ebf5fb;
   color: #3498db;
   color: #3498db;
   border: 1px solid #3498db;
   border: 1px solid #3498db;
-}
+}

+ 151 - 60
industry-monitor-web/src/app/pages/factory-overview/factory-overview.component.html

@@ -1,14 +1,32 @@
-
+<!-- factory-overview.component.html -->
 <div class="dashboard">
 <div class="dashboard">
   <div class="dashboard-header">
   <div class="dashboard-header">
-    <h2><i class="fa fa-industry"></i> 工厂总览看板</h2>
-    <div class="time-display">
-      <i class="fa fa-clock"></i> {{ currentTime | date:'yyyy-MM-dd HH:mm:ss' }}
+    <div class="header-left">
+      <h2><i class="fa fa-industry"></i> 工厂总览看板</h2>
+      <div class="quick-nav">
+        <button class="nav-btn active">总览</button>
+        <button class="nav-btn">设备管理</button>
+        <button class="nav-btn">生产监控</button>
+        <button class="nav-btn">数据分析</button>
+      </div>
+    </div>
+
+    <div class="header-right">
+      <div class="user-info">
+        <i class="fa fa-user-circle"></i>
+        <span>管理员</span>
+      </div>
+      <div class="time-display">
+        <i class="fa fa-clock"></i> {{ currentTime | date:'yyyy-MM-dd HH:mm:ss' }}
+      </div>
+      <button class="refresh-btn" (click)="refreshData()">
+        <i class="fa fa-sync-alt"></i> 刷新数据
+      </button>
     </div>
     </div>
   </div>
   </div>
 
 
   <div class="metric-grid">
   <div class="metric-grid">
-    <div class="metric-card">
+    <div class="metric-card" (mouseenter)="cardHover(0)" [class.hover]="hoverIndex === 0">
       <div class="metric-icon blue">
       <div class="metric-icon blue">
         <i class="fa fa-cogs"></i>
         <i class="fa fa-cogs"></i>
       </div>
       </div>
@@ -16,10 +34,16 @@
         <h3>设备运行状态</h3>
         <h3>设备运行状态</h3>
         <p class="metric-value">45/50</p>
         <p class="metric-value">45/50</p>
         <p class="metric-label">运行设备数/总设备数</p>
         <p class="metric-label">运行设备数/总设备数</p>
+        <div class="metric-progress">
+          <div class="progress-bar" [style.width.%]="90"></div>
+        </div>
+      </div>
+      <div class="metric-hover">
+        <i class="fa fa-arrow-right"></i> 查看详情
       </div>
       </div>
     </div>
     </div>
 
 
-    <div class="metric-card">
+    <div class="metric-card" (mouseenter)="cardHover(1)" [class.hover]="hoverIndex === 1">
       <div class="metric-icon orange">
       <div class="metric-icon orange">
         <i class="fa fa-exclamation-triangle"></i>
         <i class="fa fa-exclamation-triangle"></i>
       </div>
       </div>
@@ -27,10 +51,16 @@
         <h3>今日预警</h3>
         <h3>今日预警</h3>
         <p class="metric-value">12</p>
         <p class="metric-value">12</p>
         <p class="metric-label">预警总数</p>
         <p class="metric-label">预警总数</p>
+        <div class="metric-progress">
+          <div class="progress-bar" [style.width.%]="24"></div>
+        </div>
+      </div>
+      <div class="metric-hover">
+        <i class="fa fa-arrow-right"></i> 查看详情
       </div>
       </div>
     </div>
     </div>
 
 
-    <div class="metric-card">
+    <div class="metric-card" (mouseenter)="cardHover(2)" [class.hover]="hoverIndex === 2">
       <div class="metric-icon green">
       <div class="metric-icon green">
         <i class="fa fa-heartbeat"></i>
         <i class="fa fa-heartbeat"></i>
       </div>
       </div>
@@ -38,10 +68,16 @@
         <h3>设备健康指数</h3>
         <h3>设备健康指数</h3>
         <p class="metric-value">92%</p>
         <p class="metric-value">92%</p>
         <p class="metric-label">整体设备健康</p>
         <p class="metric-label">整体设备健康</p>
+        <div class="metric-progress">
+          <div class="progress-bar" [style.width.%]="92"></div>
+        </div>
+      </div>
+      <div class="metric-hover">
+        <i class="fa fa-arrow-right"></i> 查看详情
       </div>
       </div>
     </div>
     </div>
 
 
-    <div class="metric-card">
+    <div class="metric-card" (mouseenter)="cardHover(3)" [class.hover]="hoverIndex === 3">
       <div class="metric-icon purple">
       <div class="metric-icon purple">
         <i class="fa fa-tachometer-alt"></i>
         <i class="fa fa-tachometer-alt"></i>
       </div>
       </div>
@@ -49,98 +85,153 @@
         <h3>运行参数</h3>
         <h3>运行参数</h3>
         <p class="metric-value">65°C / 1450 RPM</p>
         <p class="metric-value">65°C / 1450 RPM</p>
         <p class="metric-label">平均温度/转速</p>
         <p class="metric-label">平均温度/转速</p>
+        <div class="metric-progress">
+          <div class="progress-bar" [style.width.%]="75"></div>
+        </div>
+      </div>
+      <div class="metric-hover">
+        <i class="fa fa-arrow-right"></i> 查看详情
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
 
 
   <div class="dashboard-row">
   <div class="dashboard-row">
-    <div class="chart-card">
-      <h3><i class="fa fa-chart-pie"></i> 设备状态分布</h3>
-      <div class="pie-chart">
-        <div class="chart-container">
-          <div class="chart-slice normal" style="--value: 80;"></div>
-          <div class="chart-slice warning" style="--value: 15;"></div>
-          <div class="chart-slice danger" style="--value: 5;"></div>
-          <div class="chart-center"></div>
+    <div class="chart-card with-tabs">
+      <div class="chart-header">
+        <h3><i class="fa fa-chart-pie"></i> 设备状态分析</h3>
+        <div class="chart-tabs">
+          <button class="tab-btn active">实时状态</button>
+          <button class="tab-btn">历史趋势</button>
+          <button class="tab-btn">对比分析</button>
         </div>
         </div>
-        <div class="chart-legend">
-          <div><span class="dot normal"></span> 正常 80%</div>
-          <div><span class="dot warning"></span> 警告 15%</div>
-          <div><span class="dot danger"></span> 危险 5%</div>
+      </div>
+
+      <div class="chart-container-wrapper">
+        <div class="pie-chart">
+          <div class="chart-container">
+            <div class="chart-slice normal" style="--value: 80;"></div>
+            <div class="chart-slice warning" style="--value: 15;"></div>
+            <div class="chart-slice danger" style="--value: 5;"></div>
+            <div class="chart-center">
+              <div class="chart-center-text">92%</div>
+            </div>
+          </div>
+          <div class="chart-legend">
+            <div><span class="dot normal"></span> 正常 80%</div>
+            <div><span class="dot warning"></span> 警告 15%</div>
+            <div><span class="dot danger"></span> 危险 5%</div>
+          </div>
+        </div>
+        <div class="chart-details">
+          <div class="detail-item">
+            <div class="detail-label">设备总数</div>
+            <div class="detail-value">50台</div>
+          </div>
+          <div class="detail-item">
+            <div class="detail-label">在线设备</div>
+            <div class="detail-value">45台</div>
+          </div>
+          <div class="detail-item">
+            <div class="detail-label">离线设备</div>
+            <div class="detail-value">5台</div>
+          </div>
+          <div class="detail-item">
+            <div class="detail-label">平均在线率</div>
+            <div class="detail-value">92.5%</div>
+          </div>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
 
 
-    <div class="alert-card">
-      <h3><i class="fa fa-bell"></i> 实时警报</h3>
+    <div class="alert-card with-filter">
+      <div class="alert-header">
+        <h3><i class="fa fa-bell"></i> 实时警报 (12)</h3>
+        <div class="alert-filter">
+          <select>
+            <option>全部警报</option>
+            <option>严重警报</option>
+            <option>警告</option>
+            <option>通知</option>
+          </select>
+        </div>
+      </div>
+
       <div class="alert-list">
       <div class="alert-list">
         <div class="alert-item critical">
         <div class="alert-item critical">
           <i class="fa fa-exclamation-circle"></i>
           <i class="fa fa-exclamation-circle"></i>
           <div class="alert-content">
           <div class="alert-content">
             <strong>设备 #A23 温度过高</strong>
             <strong>设备 #A23 温度过高</strong>
             <span>车间B - 产线2 | 15:23:45</span>
             <span>车间B - 产线2 | 15:23:45</span>
-            <comp-star-rating
-              [star]="rating"
-              (onStarChange)="ratingChange($event)"
-            ></comp-star-rating>
-            <p>当前评分: {{rating}}</p>
           </div>
           </div>
+          <div class="alert-status">未处理</div>
         </div>
         </div>
         <div class="alert-item warning">
         <div class="alert-item warning">
           <i class="fa fa-exclamation-triangle"></i>
           <i class="fa fa-exclamation-triangle"></i>
           <div class="alert-content">
           <div class="alert-content">
             <strong>设备 #B07 振动异常</strong>
             <strong>设备 #B07 振动异常</strong>
             <span>车间A - 产线4 | 15:20:12</span>
             <span>车间A - 产线4 | 15:20:12</span>
-            <p>{{ 125006 | tok}}</p>
-            <p>{{ 100 | tok}}</p>
-            <p>{{ 99987565 | tok}}</p>
           </div>
           </div>
+          <div class="alert-status">处理中</div>
         </div>
         </div>
         <div class="alert-item info">
         <div class="alert-item info">
           <i class="fa fa-info-circle"></i>
           <i class="fa fa-info-circle"></i>
-            <div class="alert-content">
+          <div class="alert-content">
             <strong>设备 #C15 转速过低</strong>
             <strong>设备 #C15 转速过低</strong>
             <span>车间C - 产线1 | 14:58:33</span>
             <span>车间C - 产线1 | 14:58:33</span>
           </div>
           </div>
+          <div class="alert-status">已处理</div>
         </div>
         </div>
+        <div class="alert-item critical">
+          <i class="fa fa-exclamation-circle"></i>
+          <div class="alert-content">
+            <strong>设备 #D42 电压异常</strong>
+            <span>车间A - 产线3 | 14:45:21</span>
+          </div>
+          <div class="alert-status">未处理</div>
+        </div>
+      </div>
+      <div class="alert-footer">
+        <button class="view-all-btn">
+          <i class="fa fa-list"></i> 查看所有警报
+        </button>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
 
 
   <div class="trend-card">
   <div class="trend-card">
-  <h3><i class="fa fa-chart-line"></i> 健康指数趋势 (24小时)</h3>
+    <div class="trend-header">
+      <h3><i class="fa fa-chart-line"></i> 健康指数趋势</h3>
 
 
-  <div class="trend-description">
-    过去24小时内设备健康指数变化趋势,当前平均健康指数为82,较昨日上升5.2%。
-  </div>
+      <div class="time-range-selector">
+        <button class="time-btn active">24小时</button>
+        <button class="time-btn">7天</button>
+        <button class="time-btn">30天</button>
+        <button class="time-btn">自定义</button>
+      </div>
 
 
-  <div class="trend-graph">
-    <div class="graph-bar" style="--height: 60;" data-value="60"></div>
-    <div class="graph-bar" style="--height: 65;" data-value="65"></div>
-    <div class="graph-bar" style="--height: 70;" data-value="70"></div>
-    <div class="graph-bar" style="--height: 82;" data-value="82"></div>
-    <div class="graph-bar" style="--height: 88;" data-value="88"></div>
-    <div class="graph-bar" style="--height: 92;" data-value="92"></div>
-    <div class="graph-bar" style="--height: 90;" data-value="90"></div>
-  </div>
+    </div>
 
 
-  <div class="time-labels">
-    <span>00:00</span>
-    <span>04:00</span>
-    <span>08:00</span>
-    <span>12:00</span>
-    <span>16:00</span>
-    <span>20:00</span>
-    <span>24:00</span>
-  </div>
 
 
-  <div class="trend-footer">
-    <div class="trend-summary">
-      数据更新时间: {{currentTime | date:'yyyy-MM-dd HH:mm:ss'}}
-    </div>
-    <div class="trend-change positive">
-      <i class="fa fa-arrow-up"></i> 5.2%
+
+    <div class="trend-graph">
+      <div class="graph-labels">
+        <span>04:00</span>
+        <span>08:00</span>
+        <span>12:00</span>
+        <span>16:00</span>
+        <span>20:00</span>
+        <span>00:00</span>
+        <span>当前</span>
+      </div>
+      <div class="graph-bars">
+        <div class="graph-bar" [style.height.%]="60"></div>
+        <div class="graph-bar" [style.height.%]="65"></div>
+        <div class="graph-bar" [style.height.%]="70"></div>
+        <div class="graph-bar" [style.height.%]="82"></div>
+        <div class="graph-bar" [style.height.%]="88"></div>
+        <div class="graph-bar" [style.height.%]="92"></div>
+        <div class="graph-bar" [style.height.%]="90"></div>
+      </div>
     </div>
     </div>
   </div>
   </div>
 </div>
 </div>
-</div>

+ 15 - 46
industry-monitor-web/src/app/pages/factory-overview/factory-overview.component.ts

@@ -1,8 +1,6 @@
-
+// factory-overview.component.ts
 import { DatePipe } from '@angular/common';
 import { DatePipe } from '@angular/common';
 import { Component, ViewEncapsulation } from '@angular/core';
 import { Component, ViewEncapsulation } from '@angular/core';
-import { CompStarRatingComponent } from '../../componets/star-rating/comp-star-rating.component';
-import { TokPipe } from '../../pipes/tok-pipe/tok.pipe';
 
 
 @Component({
 @Component({
   standalone: true,
   standalone: true,
@@ -10,57 +8,28 @@ import { TokPipe } from '../../pipes/tok-pipe/tok.pipe';
   styleUrls: ['./factory-overview.css'],
   styleUrls: ['./factory-overview.css'],
   templateUrl: './factory-overview.component.html',
   templateUrl: './factory-overview.component.html',
   encapsulation: ViewEncapsulation.None,
   encapsulation: ViewEncapsulation.None,
-  imports: [
-    DatePipe,TokPipe,
-    CompStarRatingComponent
-  ]
-
+  imports: [DatePipe]
 })
 })
 export class FactoryOverviewComponent {
 export class FactoryOverviewComponent {
-  // 在组件类中添加以下属性
-
-  // 设备状态数据
-  deviceStatus = {
-    total: 24,
-    normal: { count: 19, percentage: 80 },
-    warning: { count: 4, percentage: 15 },
-    danger: { count: 1, percentage: 5 }
-  };
-
-  // 饼图角度计算
-  get pieChartStyle() {
-    return {
-      'background': `conic-gradient(
-        #27ae60 0% ${this.deviceStatus.normal.percentage}%,
-        #f39c12 ${this.deviceStatus.normal.percentage}% ${this.deviceStatus.normal.percentage + this.deviceStatus.warning.percentage}%,
-        #e74c3c ${this.deviceStatus.normal.percentage + this.deviceStatus.warning.percentage}% 100%
-      )`
-    };
-
-}
-  rating:number = 0
-  ratingChange(rating: number) {
-    this.rating = rating;
-  }
   currentTime: Date = new Date();
   currentTime: Date = new Date();
-   ngOnInit(): void {
+  hoverIndex: number = -1;
+
+  constructor() {
     // 更新时间,每秒更新一次
     // 更新时间,每秒更新一次
     setInterval(() => {
     setInterval(() => {
       this.currentTime = new Date();
       this.currentTime = new Date();
     }, 1000);
     }, 1000);
+  }
 
 
+  // 修复:添加 cardHover 方法
+  cardHover(index: number) {
+    this.hoverIndex = index;
   }
   }
 
 
-    tok(value:number){
-      if(value<=1000){
-        return value
-      }
-      if(value<=999999){
-        return (value/1000).toFixed(0) + 'k'
-      }
-      if(value<=999999999){
-        return (value/10000).toFixed(0) + '万'
-      }
-      return value
-    }
+  // 添加刷新数据方法
+  refreshData() {
+    // 这里可以添加实际的数据刷新逻辑
+    console.log('刷新数据...');
+    this.currentTime = new Date();
+  }
 }
 }

+ 330 - 127
industry-monitor-web/src/app/pages/factory-overview/factory-overview.css

@@ -1,8 +1,9 @@
-/* 组件容器样式 */
+/* factory-overview.css */
 :host {
 :host {
   display: block;
   display: block;
   width: 100%;
   width: 100%;
   padding: 15px;
   padding: 15px;
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 }
 
 
 .dashboard {
 .dashboard {
@@ -24,12 +25,53 @@
   border-bottom: 1px solid #eee;
   border-bottom: 1px solid #eee;
 }
 }
 
 
+.header-left {
+  display: flex;
+  align-items: center;
+  gap: 30px;
+}
+
 .dashboard-header h2 {
 .dashboard-header h2 {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 10px;
   gap: 10px;
   font-size: 24px;
   font-size: 24px;
   color: #2c3e50;
   color: #2c3e50;
+  margin: 0;
+}
+
+.quick-nav {
+  display: flex;
+  gap: 10px;
+}
+
+.nav-btn {
+  padding: 8px 16px;
+  background: #f1f2f6;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  transition: all 0.3s ease;
+}
+
+.nav-btn.active, .nav-btn:hover {
+  background: #2c3e50;
+  color: white;
+}
+
+.header-right {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+}
+
+.user-info {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 14px;
+  color: #2c3e50;
 }
 }
 
 
 .time-display {
 .time-display {
@@ -43,6 +85,24 @@
   gap: 8px;
   gap: 8px;
 }
 }
 
 
+.refresh-btn {
+  background: #27ae60;
+  color: white;
+  border: none;
+  padding: 8px 15px;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  transition: background 0.3s ease;
+}
+
+.refresh-btn:hover {
+  background: #219653;
+}
+
 /* 指标网格样式 */
 /* 指标网格样式 */
 .metric-grid {
 .metric-grid {
   display: grid;
   display: grid;
@@ -59,6 +119,15 @@
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 15px;
   gap: 15px;
+  position: relative;
+  overflow: hidden;
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.metric-card:hover {
+  transform: translateY(-5px);
+  box-shadow: 0 12px 20px rgba(0,0,0,0.15);
 }
 }
 
 
 .metric-icon {
 .metric-icon {
@@ -77,6 +146,10 @@
 .metric-icon.orange { background: #f39c12; }
 .metric-icon.orange { background: #f39c12; }
 .metric-icon.purple { background: #9b59b6; }
 .metric-icon.purple { background: #9b59b6; }
 
 
+.metric-data {
+  flex: 1;
+}
+
 .metric-data h3 {
 .metric-data h3 {
   font-size: 16px;
   font-size: 16px;
   font-weight: 600;
   font-weight: 600;
@@ -88,19 +161,115 @@
   font-size: 24px;
   font-size: 24px;
   font-weight: 700;
   font-weight: 700;
   color: #2c3e50;
   color: #2c3e50;
+  margin: 5px 0;
 }
 }
 
 
 .metric-label {
 .metric-label {
   font-size: 14px;
   font-size: 14px;
   color: #95a5a6;
   color: #95a5a6;
+  margin: 0;
+}
+
+/* 进度条样式 */
+.metric-progress {
+  height: 6px;
+  background: #e0e0e0;
+  border-radius: 3px;
+  margin-top: 10px;
+  overflow: hidden;
+}
+
+.progress-bar {
+  height: 100%;
+  border-radius: 3px;
+  transition: width 0.5s ease;
+}
+
+.metric-card:nth-child(1) .progress-bar { background: #3498db; }
+.metric-card:nth-child(2) .progress-bar { background: #f39c12; }
+.metric-card:nth-child(3) .progress-bar { background: #27ae60; }
+.metric-card:nth-child(4) .progress-bar { background: #9b59b6; }
+
+/* 悬停效果 */
+.metric-hover {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: rgba(0,0,0,0.8);
+  color: white;
+  padding: 10px;
+  text-align: center;
+  opacity: 0;
+  transform: translateY(100%);
+  transition: all 0.3s ease;
+}
+
+.metric-card.hover .metric-hover {
+  opacity: 1;
+  transform: translateY(0);
+}
+
+/* 仪表板行布局 */
+.dashboard-row {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+}
+
+.chart-card, .alert-card {
+  flex: 1;
+  background: white;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+}
+
+.trend-card {
+  background: white;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 }
 }
 
 
 /* 饼图样式 */
 /* 饼图样式 */
+.chart-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.chart-tabs {
+  display: flex;
+  gap: 8px;
+}
+
+.tab-btn {
+  padding: 6px 12px;
+  border: none;
+  border-radius: 15px;
+  background: #f1f1f1;
+  font-size: 12px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.tab-btn.active, .tab-btn:hover {
+  background: #2c3e50;
+  color: white;
+}
+
+.chart-container-wrapper {
+  display: flex;
+  gap: 30px;
+}
+
 .pie-chart {
 .pie-chart {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 30px;
   gap: 30px;
-  padding: 20px 0;
+  padding: 10px 0;
 }
 }
 
 
 .chart-container {
 .chart-container {
@@ -124,6 +293,15 @@
   top: 50%;
   top: 50%;
   left: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   transform: translate(-50%, -50%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.chart-center-text {
+  font-size: 20px;
+  font-weight: bold;
+  color: #2c3e50;
 }
 }
 
 
 .chart-legend div {
 .chart-legend div {
@@ -145,9 +323,58 @@
 .dot.warning { background: #f39c12; }
 .dot.warning { background: #f39c12; }
 .dot.danger { background: #e74c3c; }
 .dot.danger { background: #e74c3c; }
 
 
+/* 图表详情 */
+.chart-details {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 15px;
+  flex: 1;
+}
+
+.detail-item {
+  background: #f8fafc;
+  border-radius: 6px;
+  padding: 12px;
+  transition: transform 0.3s ease;
+}
+
+.detail-item:hover {
+  transform: translateY(-3px);
+  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
+}
+
+.detail-label {
+  font-size: 13px;
+  color: #7f8c8d;
+  margin-bottom: 5px;
+}
+
+.detail-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #2c3e50;
+}
+
 /* 警报样式 */
 /* 警报样式 */
+.alert-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.alert-filter select {
+  padding: 6px 12px;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  background: white;
+  font-size: 14px;
+}
+
 .alert-list {
 .alert-list {
   margin-top: 15px;
   margin-top: 15px;
+  max-height: 300px;
+  overflow-y: auto;
 }
 }
 
 
 .alert-item {
 .alert-item {
@@ -159,6 +386,12 @@
   margin-bottom: 10px;
   margin-bottom: 10px;
   background: #f9f9f9;
   background: #f9f9f9;
   border-left: 4px solid;
   border-left: 4px solid;
+  transition: all 0.3s ease;
+}
+
+.alert-item:hover {
+  transform: translateX(5px);
+  box-shadow: 0 3px 8px rgba(0,0,0,0.1);
 }
 }
 
 
 .alert-item.critical {
 .alert-item.critical {
@@ -199,126 +432,126 @@
   color: #95a5a6;
   color: #95a5a6;
 }
 }
 
 
-/* 趋势图样式 */
-.trend-graph {
-  display: flex;
-  align-items: flex-end;
-  gap: 10px;
-  height: 200px;
-  padding: 20px;
-  background: #f8fafc;
-  border-radius: 6px;
-  margin-top: 15px;
+.alert-status {
+  padding: 4px 10px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: bold;
 }
 }
 
 
-.graph-bar {
-  flex: 1;
-  background: #3498db;
-  height: calc(var(--height) * 2px);
-  border-radius: 4px 4px 0 0;
-  position: relative;
+.alert-item.critical .alert-status {
+  background: #e74c3c;
+  color: white;
 }
 }
 
 
-/* 仪表板行布局 */
-.dashboard-row {
-  display: flex;
-  gap: 20px;
-  margin-bottom: 20px;
+.alert-item.warning .alert-status {
+  background: #f39c12;
+  color: white;
 }
 }
 
 
-.chart-card, .alert-card {
-  flex: 1;
-  background: white;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+.alert-item.info .alert-status {
+  background: #3498db;
+  color: white;
 }
 }
 
 
-.trend-card {
-  background: white;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+.alert-footer {
+  margin-top: 15px;
+  text-align: center;
 }
 }
-/* 健康指数趋势卡片样式 */
-.trend-card {
-  background: white;
-  border-radius: 12px;
-  padding: 20px;
-  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
-  transition: all 0.3s ease;
-  border: 1px solid #eaeef2;
-  position: relative;
-  overflow: hidden;
+
+.view-all-btn {
+  background: #3498db;
+  color: white;
+  border: none;
+  padding: 8px 15px;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+  transition: background 0.3s ease;
 }
 }
 
 
-.trend-card:hover {
-  transform: translateY(-5px);
-  box-shadow: 0 8px 20px rgba(0,0,0,0.12);
-  border-color: #3498db;
+.view-all-btn:hover {
+  background: #2980b9;
 }
 }
 
 
-.trend-card h3 {
-  margin: 0 0 15px 0;
-  font-size: 18px;
-  color: #2c3e50;
+/* 趋势图样式 */
+.trend-header {
   display: flex;
   display: flex;
+  justify-content: space-between;
   align-items: center;
   align-items: center;
-  gap: 10px;
+  margin-bottom: 15px;
 }
 }
 
 
-.trend-card h3 i {
-  color: #3498db;
-  font-size: 20px;
+.time-range-selector {
+  display: flex;
+  gap: 8px;
 }
 }
 
 
-.trend-description {
-  font-size: 14px;
-  color: #718096;
-  margin-bottom: 20px;
-  line-height: 1.5;
+.time-btn {
+  padding: 6px 12px;
+  border: 1px solid #ddd;
+  border-radius: 15px;
+  background: white;
+  font-size: 12px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.time-btn.active, .time-btn:hover {
+  border-color: #3498db;
+  background: #3498db;
+  color: white;
 }
 }
 
 
 .trend-graph {
 .trend-graph {
   display: flex;
   display: flex;
-  align-items: flex-end;
-  gap: 12px;
+  flex-direction: column;
   height: 200px;
   height: 200px;
   padding: 20px;
   padding: 20px;
   background: #f8fafc;
   background: #f8fafc;
-  border-radius: 8px;
+  border-radius: 6px;
   margin-top: 15px;
   margin-top: 15px;
   position: relative;
   position: relative;
 }
 }
 
 
+.graph-labels {
+  display: flex;
+  justify-content: space-between;
+  margin-top: auto;
+  color: #7f8c8d;
+  font-size: 12px;
+}
+
+.graph-bars {
+  display: flex;
+  align-items: flex-end;
+  gap: 10px;
+  height: 100%;
+  width: 100%;
+}
+
 .graph-bar {
 .graph-bar {
   flex: 1;
   flex: 1;
-  background: linear-gradient(to top, #3498db, #67b7f5);
-  height: calc(var(--height) * 1.8px);
-  border-radius: 6px 6px 0 0;
+  background: #3498db;
+  border-radius: 4px 4px 0 0;
   position: relative;
   position: relative;
-  transition: all 0.4s ease;
-  cursor: pointer;
-  min-width: 30px;
-}
-
-.graph-bar:hover {
-  transform: scaleY(1.05);
-  box-shadow: 0 -4px 8px rgba(52, 152, 219, 0.3);
+  transition: height 0.5s ease;
 }
 }
 
 
 .graph-bar::after {
 .graph-bar::after {
-  content: attr(data-value);
+  content: attr(style);
   position: absolute;
   position: absolute;
   top: -25px;
   top: -25px;
   left: 50%;
   left: 50%;
   transform: translateX(-50%);
   transform: translateX(-50%);
-  background: #2c3e50;
+  background: rgba(0,0,0,0.7);
   color: white;
   color: white;
   padding: 3px 8px;
   padding: 3px 8px;
-  border-radius: 12px;
+  border-radius: 4px;
   font-size: 12px;
   font-size: 12px;
-  font-weight: 600;
   opacity: 0;
   opacity: 0;
   transition: opacity 0.3s ease;
   transition: opacity 0.3s ease;
 }
 }
@@ -327,60 +560,30 @@
   opacity: 1;
   opacity: 1;
 }
 }
 
 
-.time-labels {
-  display: flex;
-  justify-content: space-between;
-  margin-top: 8px;
-  font-size: 12px;
-  color: #95a5a6;
-  padding: 0 10px;
-}
-
-.trend-footer {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-top: 20px;
-  padding-top: 15px;
-  border-top: 1px solid #eaeef2;
-}
-
-.trend-summary {
-  font-size: 14px;
-  color: #718096;
-}
-
-.trend-change {
-  display: flex;
-  align-items: center;
-  gap: 5px;
-  font-weight: 600;
-  font-size: 14px;
-}
-
-.trend-change.positive {
-  color: #27ae60;
-}
-
-.trend-change.negative {
-  color: #e74c3c;
+/* 响应式调整 */
+@media (max-width: 1200px) {
+  .dashboard-row {
+    flex-direction: column;
+  }
 }
 }
 
 
-/* 响应式设计 */
 @media (max-width: 768px) {
 @media (max-width: 768px) {
-  .trend-card {
-    padding: 15px;
+  .dashboard-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 15px;
   }
   }
 
 
-  .trend-graph {
-    height: 160px;
-    padding: 15px;
-    gap: 8px;
+  .header-left, .header-right {
+    width: 100%;
   }
   }
 
 
-  .graph-bar {
-    min-width: 20px;
+  .quick-nav {
+    overflow-x: auto;
+    padding-bottom: 10px;
   }
   }
-}
-
 
 
+  .chart-container-wrapper {
+    flex-direction: column;
+  }
+}

+ 258 - 124
industry-monitor-web/src/app/pages/historical-data/historical-data.component.html

@@ -1,37 +1,61 @@
-
 <!-- historical-data.component.html -->
 <!-- historical-data.component.html -->
 <div class="history-container">
 <div class="history-container">
   <div class="history-header">
   <div class="history-header">
-    <h2><i class="fa fa-chart-bar"></i> 历史数据分析</h2>
+    <div class="header-content">
+      <h2><i class="fas fa-chart-line"></i> 历史数据分析</h2>
+      <p class="subtitle">深入洞察设备运行状况与性能趋势</p>
+    </div>
+    <div class="header-actions">
+      <button class="btn btn-icon"><i class="fas fa-question-circle"></i></button>
+      <button class="btn btn-icon"><i class="fas fa-cog"></i></button>
+    </div>
   </div>
   </div>
 
 
   <div class="filter-row">
   <div class="filter-row">
     <div class="filter-card">
     <div class="filter-card">
-      <h3><i class="fa fa-calendar-alt"></i> 时间范围</h3>
+      <div class="card-header">
+        <i class="fas fa-calendar-alt"></i>
+        <h3>时间范围</h3>
+      </div>
       <div class="date-controls">
       <div class="date-controls">
         <div class="date-input">
         <div class="date-input">
-          <label>开始日期:</label>
-          <input type="date" value="2023-07-01">
+          <label>开始日期</label>
+          <div class="input-with-icon">
+            <input type="date" value="2023-07-01">
+            <i class="fas fa-calendar-day"></i>
+          </div>
         </div>
         </div>
         <div class="date-input">
         <div class="date-input">
-          <label>结束日期:</label>
-          <input type="date" value="2023-07-15">
+          <label>结束日期</label>
+          <div class="input-with-icon">
+            <input type="date" value="2023-07-15">
+            <i class="fas fa-calendar-day"></i>
+          </div>
         </div>
         </div>
-        <button class="btn"><i class="fa fa-sync"></i> 应用</button>
+        <button class="btn btn-primary">
+          <i class="fas fa-sync-alt"></i> 应用筛选
+        </button>
       </div>
       </div>
     </div>
     </div>
 
 
-    <div class="device-selector">
-      <h3><i class="fa fa-microchip"></i> 设备选择</h3>
+    <div class="filter-card">
+      <div class="card-header">
+        <i class="fas fa-microchip"></i>
+        <h3>设备选择</h3>
+      </div>
       <div class="device-controls">
       <div class="device-controls">
-        <select>
-          <option>CNC 铣床 #01</option>
-          <option>注塑机 #05</option>
-          <option>装配机器人 #03</option>
-        </select>
-        <label class="checkbox-container">多设备对比
-          <input type="checkbox">
+        <div class="select-wrapper">
+          <select class="styled-select">
+            <option>CNC 铣床 #01</option>
+            <option>注塑机 #05</option>
+            <option>装配机器人 #03</option>
+          </select>
+          <i class="fas fa-chevron-down"></i>
+        </div>
+        <label class="checkbox-container">
+          <input type="checkbox" id="compare-devices">
           <span class="checkmark"></span>
           <span class="checkmark"></span>
+          <span class="checkbox-label">多设备对比</span>
         </label>
         </label>
       </div>
       </div>
     </div>
     </div>
@@ -40,126 +64,236 @@
   <div class="chart-container">
   <div class="chart-container">
     <div class="chart-card">
     <div class="chart-card">
       <div class="chart-header">
       <div class="chart-header">
-        <h3><i class="fa fa-wave-square"></i> 振动数据趋势 (2023-07-01 - 2023-07-15)</h3>
-        <div class="chart-legend">
-          <div><span class="color-dot primary"></span> CNC 铣床 #01</div>
-          <div><span class="color-dot secondary"></span> 注塑机 #05</div>
+        <h3><i class="fas fa-wave-square"></i> 振动数据趋势</h3>
+        <div class="chart-toolbar">
+          <div class="chart-legend">
+            <div class="legend-item">
+              <span class="color-dot primary"></span>
+              <span>CNC 铣床 #01</span>
+            </div>
+            <div class="legend-item">
+              <span class="color-dot secondary"></span>
+              <span>注塑机 #05</span>
+            </div>
+          </div>
+          <div class="chart-actions">
+            <button class="btn btn-icon"><i class="fas fa-expand"></i></button>
+            <button class="btn btn-icon"><i class="fas fa-download"></i></button>
+          </div>
         </div>
         </div>
       </div>
       </div>
       <div class="chart-content">
       <div class="chart-content">
-        <div class="trend-chart">
-          <div class="grid-lines">
-            <div class="grid-line"></div>
-            <div class="grid-line"></div>
-            <div class="grid-line"></div>
-            <div class="grid-line"></div>
-            <div class="grid-line"></div>
-          </div>
-          <div class="data-line primary"></div>
-          <div class="data-line secondary"></div>
-          <div class="x-axis">
-            <span>1</span><span>3</span><span>5</span><span>7</span><span>9</span><span>11</span><span>13</span><span>15</span>
-          </div>
-          <div class="y-axis">
-            <span>1.5</span><span>1.0</span><span>0.5</span><span>0</span>
+        <div class="chart-placeholder">
+          <!-- 这里实际应用中会替换为真实的图表库如Chart.js或ECharts -->
+          <div class="chart-mockup">
+            <div class="y-axis">
+              <span>1.5</span>
+              <span>1.0</span>
+              <span>0.5</span>
+              <span>0</span>
+            </div>
+            <div class="grid-lines">
+              <div class="grid-line"></div>
+              <div class="grid-line"></div>
+              <div class="grid-line"></div>
+              <div class="grid-line"></div>
+            </div>
+            <div class="data-line primary animated-line"></div>
+            <div class="data-line secondary animated-line"></div>
+            <div class="x-axis">
+              <span>1日</span>
+              <span>3日</span>
+              <span>5日</span>
+              <span>7日</span>
+              <span>9日</span>
+              <span>11日</span>
+              <span>13日</span>
+              <span>15日</span>
+            </div>
           </div>
           </div>
+          <div class="chart-hover-info">将鼠标悬停在图表上查看详细数据</div>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
 
 
-  <div class="data-table-card">
-    <h3><i class="fa fa-table"></i> 详细数据记录</h3>
-    <table class="data-table">
-      <thead>
-        <tr>
-          <th>日期</th>
-          <th>设备名称</th>
-          <th>振幅(mm/s)</th>
-          <th>温度(°C)</th>
-          <th>转速(RPM)</th>
-          <th>健康指数</th>
-          <th>状态</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td>{{currentDate}}</td>
-          <td>CNC 铣床 #01</td>
-          <td>0.58</td>
-          <td>68</td>
-          <td>1420</td>
-          <td>89%</td>
-          <td><span class="status-badge normal">正常</span></td>
-        </tr>
-        <tr>
-         <td>{{currentDate}}</td>
-          <td>注塑机 #05</td>
-          <td>0.72</td>
-          <td>71</td>
-          <td>920</td>
-          <td>76%</td>
-          <td><span class="status-badge warning">警告</span></td>
-        </tr>
-        <tr>
-        <td>{{currentDate}}</td>
-          <td>CNC 铣床 #01</td>
-          <td>0.62</td>
-          <td>70</td>
-          <td>1405</td>
-          <td>85%</td>
-          <td><span class="status-badge normal">正常</span></td>
-        </tr>
-        <tr>
-         <td>{{currentDate}}</td>
-          <td>装配机器人 #03</td>
-          <td>0.48</td>
-          <td>65</td>
-          <td>1850</td>
-          <td>65%</td>
-          <td><span class="status-badge critical">严重</span></td>
-        </tr>
-        <tr>
-          <td>{{currentDate}}</td>
-          <td>CNC 铣床 #01</td>
-          <td>0.92</td>
-          <td>75</td>
-          <td>1380</td>
-          <td>82%</td>
-          <td><span class="status-badge warning">警告</span></td>
-        </tr>
-      </tbody>
-    </table>
+  <div class="metrics-grid">
+    <div class="metric-card">
+      <div class="metric-header">
+        <i class="fas fa-vibration"></i>
+        <h4>平均振幅</h4>
+      </div>
+      <div class="metric-value">0.68<span class="unit">mm/s</span></div>
+      <div class="metric-change positive">
+        <i class="fas fa-arrow-up"></i> 5.2% 较上周
+      </div>
+    </div>
+    <div class="metric-card">
+      <div class="metric-header">
+        <i class="fas fa-temperature-high"></i>
+        <h4>平均温度</h4>
+      </div>
+      <div class="metric-value">71.2<span class="unit">°C</span></div>
+      <div class="metric-change negative">
+        <i class="fas fa-arrow-down"></i> 2.1% 较上周
+      </div>
+    </div>
+    <div class="metric-card">
+      <div class="metric-header">
+        <i class="fas fa-tachometer-alt"></i>
+        <h4>平均转速</h4>
+      </div>
+      <div class="metric-value">1,420<span class="unit">RPM</span></div>
+      <div class="metric-change neutral">
+        <i class="fas fa-minus"></i> 0.3% 较上周
+      </div>
+    </div>
+    <div class="metric-card">
+      <div class="metric-header">
+        <i class="fas fa-heartbeat"></i>
+        <h4>平均健康指数</h4>
+      </div>
+      <div class="metric-value">82<span class="unit">%</span></div>
+      <div class="metric-change negative">
+        <i class="fas fa-arrow-down"></i> 3.7% 较上周
+      </div>
+    </div>
   </div>
   </div>
 
 
-<script>
-  // 获取当前日期并格式化为YYYY-MM-DD
-  function getCurrentDate() {
-    const now = new Date();
-    const year = now.getFullYear();
-    const month = String(now.getMonth() + 1).padStart(2, '0');
-    const day = String(now.getDate()).padStart(2, '0');
-    return `${year}-${month}-${day}`;
-  }
-
-  // 更新表格中的日期
-  document.addEventListener('DOMContentLoaded', function() {
-    const currentDate = getCurrentDate();
-    for (let i = 1; i <= 5; i++) {
-      const element = document.getElementById(`currentDate${i}`);
-      if (element) {
-        element.textContent = currentDate;
-      }
-    }
-  });
-</script>
+  <div class="data-table-card">
+    <div class="table-header">
+      <h3><i class="fas fa-table"></i> 详细数据记录</h3>
+      <div class="table-actions">
+        <div class="search-box">
+          <i class="fas fa-search"></i>
+          <input type="text" placeholder="搜索设备或日期...">
+        </div>
+        <button class="btn btn-icon"><i class="fas fa-filter"></i></button>
+      </div>
+    </div>
+    <div class="table-responsive">
+      <table class="data-table">
+        <thead>
+          <tr>
+            <th>日期 <i class="fas fa-sort"></i></th>
+            <th>设备名称 <i class="fas fa-sort"></i></th>
+            <th>振幅(mm/s) <i class="fas fa-sort"></i></th>
+            <th>温度(°C) <i class="fas fa-sort"></i></th>
+            <th>转速(RPM) <i class="fas fa-sort"></i></th>
+            <th>健康指数 <i class="fas fa-sort"></i></th>
+            <th>状态</th>
+            <th>操作</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td>2023-07-15</td>
+            <td>CNC 铣床 #01</td>
+            <td>0.58</td>
+            <td>68</td>
+            <td>1,420</td>
+            <td>
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 89%; background: #4CAF50;"></div>
+                <span>89%</span>
+              </div>
+            </td>
+            <td><span class="status-badge normal"><i class="fas fa-check-circle"></i> 正常</span></td>
+            <td><button class="btn btn-icon btn-sm"><i class="fas fa-ellipsis-v"></i></button></td>
+          </tr>
+          <tr>
+            <td>2023-07-15</td>
+            <td>注塑机 #05</td>
+            <td>0.72</td>
+            <td>71</td>
+            <td>920</td>
+            <td>
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 76%; background: #FFC107;"></div>
+                <span>76%</span>
+              </div>
+            </td>
+            <td><span class="status-badge warning"><i class="fas fa-exclamation-triangle"></i> 警告</span></td>
+            <td><button class="btn btn-icon btn-sm"><i class="fas fa-ellipsis-v"></i></button></td>
+          </tr>
+          <tr>
+            <td>2023-07-14</td>
+            <td>CNC 铣床 #01</td>
+            <td>0.62</td>
+            <td>70</td>
+            <td>1,405</td>
+            <td>
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 85%; background: #4CAF50;"></div>
+                <span>85%</span>
+              </div>
+            </td>
+            <td><span class="status-badge normal"><i class="fas fa-check-circle"></i> 正常</span></td>
+            <td><button class="btn btn-icon btn-sm"><i class="fas fa-ellipsis-v"></i></button></td>
+          </tr>
+          <tr>
+            <td>2023-07-14</td>
+            <td>装配机器人 #03</td>
+            <td>0.48</td>
+            <td>65</td>
+            <td>1,850</td>
+            <td>
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 65%; background: #F44336;"></div>
+                <span>65%</span>
+              </div>
+            </td>
+            <td><span class="status-badge critical"><i class="fas fa-times-circle"></i> 严重</span></td>
+            <td><button class="btn btn-icon btn-sm"><i class="fas fa-ellipsis-v"></i></button></td>
+          </tr>
+          <tr>
+            <td>2023-07-13</td>
+            <td>CNC 铣床 #01</td>
+            <td>0.92</td>
+            <td>75</td>
+            <td>1,380</td>
+            <td>
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 82%; background: #FFC107;"></div>
+                <span>82%</span>
+              </div>
+            </td>
+            <td><span class="status-badge warning"><i class="fas fa-exclamation-triangle"></i> 警告</span></td>
+            <td><button class="btn btn-icon btn-sm"><i class="fas fa-ellipsis-v"></i></button></td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+    <div class="table-footer">
+      <div class="pagination-info">
+        显示 1-5 条,共 23 条记录
+      </div>
+      <div class="pagination-controls">
+        <button class="btn btn-icon"><i class="fas fa-chevron-left"></i></button>
+        <button class="btn active">1</button>
+        <button class="btn">2</button>
+        <button class="btn">3</button>
+        <button class="btn">4</button>
+        <button class="btn btn-icon"><i class="fas fa-chevron-right"></i></button>
+      </div>
+    </div>
+  </div>
 
 
   <div class="report-section">
   <div class="report-section">
-    <h3><i class="fa fa-file-alt"></i> 报表生成</h3>
+    <div class="section-header">
+      <h3><i class="fas fa-file-alt"></i> 报表生成</h3>
+      <p>导出数据用于进一步分析或分享</p>
+    </div>
     <div class="report-options">
     <div class="report-options">
-      <button class="btn"><i class="fa fa-file-csv"></i> 导出CSV</button>
-      <button class="btn"><i class="fa fa-file-pdf"></i> 导出PDF</button>
-      <button class="btn primary"><i class="fa fa-stethoscope"></i> 生成健康诊断报告</button>
+      <button class="btn btn-outline">
+        <i class="fas fa-file-csv"></i> 导出CSV
+      </button>
+      <button class="btn btn-outline">
+        <i class="fas fa-file-pdf"></i> 导出PDF
+      </button>
+      <button class="btn btn-primary">
+        <i class="fas fa-stethoscope"></i> 生成健康诊断报告
+      </button>
     </div>
     </div>
   </div>
   </div>
-</div>
+</div>

+ 0 - 9
industry-monitor-web/src/app/pages/historical-data/historical-data.component.ts

@@ -11,14 +11,6 @@ import { DatePipe } from '@angular/common';
   encapsulation: ViewEncapsulation.None
   encapsulation: ViewEncapsulation.None
 })
 })
 export class HistoricalDataComponent {
 export class HistoricalDataComponent {
-  // 在组件类中
-currentDate: string;
-
-constructor() {
-  const now = new Date();
-  this.currentDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
-}
-
 currentTime: Date = new Date();
 currentTime: Date = new Date();
    ngOnInit(): void {
    ngOnInit(): void {
     // 更新时间,每秒更新一次
     // 更新时间,每秒更新一次
@@ -28,4 +20,3 @@ currentTime: Date = new Date();
 
 
    }
    }
 }
 }
-

+ 526 - 280
industry-monitor-web/src/app/pages/historical-data/historical-data.css

@@ -5,78 +5,173 @@
   padding: 20px;
   padding: 20px;
   background-color: #f5f7fa;
   background-color: #f5f7fa;
   min-height: 100vh;
   min-height: 100vh;
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 }
 
 
 .history-container {
 .history-container {
   max-width: 1400px;
   max-width: 1400px;
   margin: 0 auto;
   margin: 0 auto;
-  padding: 25px;
   background: white;
   background: white;
-  border-radius: 10px;
-  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.05);
+  border-radius: 12px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
+  overflow: hidden;
 }
 }
 
 
 .history-header {
 .history-header {
-  margin-bottom: 30px;
-  padding-bottom: 20px;
-  border-bottom: 1px solid #eaeef2;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 24px 30px;
+  background: linear-gradient(135deg, #3498db, #2c3e50);
+  color: white;
 }
 }
 
 
-.history-header h2 {
+.header-content h2 {
+  margin: 0;
+  font-size: 26px;
+  font-weight: 600;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 12px;
   gap: 12px;
-  font-size: 26px;
-  color: #2c3e50;
-  font-weight: 600;
-  margin: 0;
 }
 }
 
 
-.history-header h2 i {
-  color: #3498db;
+.header-content .subtitle {
+  margin: 6px 0 0;
+  font-size: 14px;
+  opacity: 0.9;
+  font-weight: 400;
+}
+
+.header-actions {
+  display: flex;
+  gap: 12px;
+}
+
+.btn {
+  padding: 8px 16px;
+  border-radius: 6px;
+  border: none;
+  background: none;
+  cursor: pointer;
+  font-size: 14px;
+  font-weight: 500;
+  transition: all 0.2s ease;
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.btn-icon {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  justify-content: center;
+  background: rgba(255, 255, 255, 0.1);
+  color: white;
+}
+
+.btn-icon:hover {
+  background: rgba(255, 255, 255, 0.2);
+}
+
+.btn-primary {
+  background-color: #3498db;
+  color: white;
+}
+
+.btn-primary:hover {
+  background-color: #2980b9;
+}
+
+.btn-outline {
+  border: 1px solid #ddd;
+  background: white;
+  color: #555;
+}
+
+.btn-outline:hover {
+  background: #f5f5f5;
+}
+
+.btn-sm {
+  padding: 4px 8px;
+  font-size: 12px;
 }
 }
 
 
 .filter-row {
 .filter-row {
   display: flex;
   display: flex;
   gap: 20px;
   gap: 20px;
-  margin-bottom: 25px;
+  padding: 20px;
+  background: white;
+  border-bottom: 1px solid #eee;
 }
 }
 
 
-.filter-card,
-.device-selector {
+.filter-card {
   flex: 1;
   flex: 1;
   background: white;
   background: white;
   border-radius: 8px;
   border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 3px 10px rgba(0,0,0,0.08);
-  border: 1px solid #eaeef2;
+  padding: 16px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  margin-bottom: 16px;
+}
+
+.card-header i {
+  color: #3498db;
+  font-size: 18px;
+}
+
+.card-header h3 {
+  margin: 0;
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
 }
 }
 
 
 .date-controls {
 .date-controls {
   display: grid;
   display: grid;
   grid-template-columns: 1fr 1fr auto;
   grid-template-columns: 1fr 1fr auto;
-  gap: 15px;
+  gap: 12px;
   align-items: flex-end;
   align-items: flex-end;
 }
 }
 
 
 .date-input label {
 .date-input label {
   display: block;
   display: block;
-  margin-bottom: 8px;
-  font-size: 14px;
-  color: #4a5568;
+  margin-bottom: 6px;
+  font-size: 13px;
+  color: #666;
   font-weight: 500;
   font-weight: 500;
 }
 }
 
 
-.date-input input {
+.input-with-icon {
+  position: relative;
+}
+
+.input-with-icon i {
+  position: absolute;
+  right: 12px;
+  top: 50%;
+  transform: translateY(-50%);
+  color: #999;
+  pointer-events: none;
+}
+
+.input-with-icon input {
   width: 100%;
   width: 100%;
   padding: 10px 12px;
   padding: 10px 12px;
   border-radius: 6px;
   border-radius: 6px;
-  border: 1px solid #e2e8f0;
+  border: 1px solid #ddd;
   font-size: 14px;
   font-size: 14px;
-  transition: border-color 0.3s;
+  transition: border 0.2s;
+  padding-right: 36px;
 }
 }
 
 
-.date-input input:focus {
+.input-with-icon input:focus {
   outline: none;
   outline: none;
   border-color: #3498db;
   border-color: #3498db;
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
@@ -84,21 +179,37 @@
 
 
 .device-controls {
 .device-controls {
   display: flex;
   display: flex;
-  gap: 15px;
+  gap: 16px;
   align-items: center;
   align-items: center;
 }
 }
 
 
-.device-controls select {
+.select-wrapper {
+  position: relative;
   flex: 1;
   flex: 1;
-  padding: 10px 12px;
+}
+
+.select-wrapper i {
+  position: absolute;
+  right: 12px;
+  top: 50%;
+  transform: translateY(-50%);
+  color: #999;
+  pointer-events: none;
+}
+
+.styled-select {
+  width: 100%;
+  padding: 10px 36px 10px 12px;
   border-radius: 6px;
   border-radius: 6px;
-  border: 1px solid #e2e8f0;
+  border: 1px solid #ddd;
   font-size: 14px;
   font-size: 14px;
-  background-color: white;
-  transition: border-color 0.3s;
+  appearance: none;
+  background: white;
+  cursor: pointer;
+  transition: border 0.2s;
 }
 }
 
 
-.device-controls select:focus {
+.styled-select:focus {
   outline: none;
   outline: none;
   border-color: #3498db;
   border-color: #3498db;
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
@@ -110,7 +221,7 @@
   cursor: pointer;
   cursor: pointer;
   font-size: 14px;
   font-size: 14px;
   user-select: none;
   user-select: none;
-  color: #4a5568;
+  gap: 8px;
 }
 }
 
 
 .checkbox-container input {
 .checkbox-container input {
@@ -120,406 +231,541 @@
 }
 }
 
 
 .checkmark {
 .checkmark {
-  height: 20px;
-  width: 20px;
-  background-color: #edf2f7;
+  width: 18px;
+  height: 18px;
+  background-color: white;
+  border: 1px solid #ddd;
   border-radius: 4px;
   border-radius: 4px;
-  margin-left: 10px;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   justify-content: center;
   justify-content: center;
-  transition: background-color 0.2s;
+  transition: all 0.2s;
 }
 }
 
 
 .checkbox-container:hover .checkmark {
 .checkbox-container:hover .checkmark {
-  background-color: #e2e8f0;
+  border-color: #3498db;
 }
 }
 
 
 .checkbox-container input:checked ~ .checkmark {
 .checkbox-container input:checked ~ .checkmark {
   background-color: #3498db;
   background-color: #3498db;
+  border-color: #3498db;
 }
 }
 
 
 .checkmark:after {
 .checkmark:after {
   content: "";
   content: "";
   display: none;
   display: none;
-  width: 5px;
-  height: 10px;
+  width: 4px;
+  height: 8px;
   border: solid white;
   border: solid white;
   border-width: 0 2px 2px 0;
   border-width: 0 2px 2px 0;
   transform: rotate(45deg);
   transform: rotate(45deg);
+  margin-top: -2px;
 }
 }
 
 
 .checkbox-container input:checked ~ .checkmark:after {
 .checkbox-container input:checked ~ .checkmark:after {
   display: block;
   display: block;
 }
 }
 
 
-.data-table-card {
-  margin-top: 30px;
+.checkbox-label {
+  color: #555;
+}
+
+.chart-container {
+  padding: 0 20px;
+}
+
+.chart-card {
   background: white;
   background: white;
   border-radius: 8px;
   border-radius: 8px;
-  box-shadow: 0 3px 10px rgba(0,0,0,0.08);
-  border: 1px solid #eaeef2;
-  overflow: hidden;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+  margin-bottom: 20px;
+}
+
+.chart-header {
+  padding: 16px 20px;
+  border-bottom: 1px solid #eee;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
 }
 }
 
 
-.data-table-card h3 {
-  padding: 18px 20px;
+.chart-header h3 {
   margin: 0;
   margin: 0;
-  font-size: 18px;
-  color: #2c3e50;
-  background-color: #f8fafc;
-  border-bottom: 1px solid #eaeef2;
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 10px;
   gap: 10px;
 }
 }
 
 
-.data-table-card h3 i {
-  color: #718096;
+.chart-header i {
+  color: #3498db;
+}
+
+.chart-toolbar {
+  display: flex;
+  align-items: center;
+  gap: 20px;
 }
 }
 
 
-.data-table {
-  width: 100%;
-  border-collapse: collapse;
-  font-size: 14px;
+.chart-legend {
+  display: flex;
+  gap: 16px;
 }
 }
 
 
-.data-table th {
-  background-color: #f8fafc;
-  color: #4a5568;
-  font-weight: 600;
-  padding: 12px 15px;
-  text-align: left;
-  border-bottom: 1px solid #eaeef2;
+.legend-item {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  font-size: 13px;
+  color: #666;
 }
 }
 
 
-.data-table td {
-  padding: 12px 15px;
-  border-bottom: 1px solid #eaeef2;
-  color: #4a5568;
+.color-dot {
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  display: inline-block;
 }
 }
 
 
-.data-table tr:last-child td {
-  border-bottom: none;
+.color-dot.primary { background: #3498db; }
+.color-dot.secondary { background: #9b59b6; }
+
+.chart-actions {
+  display: flex;
+  gap: 8px;
 }
 }
 
 
-.data-table tr:hover td {
-  background-color: #f8fafc;
+.chart-content {
+  padding: 20px;
 }
 }
 
 
-.status-badge {
-  display: inline-block;
-  padding: 4px 10px;
-  border-radius: 12px;
-  font-size: 12px;
-  font-weight: 500;
+.chart-placeholder {
+  height: 400px;
+  background: #f8fafc;
+  border-radius: 6px;
+  position: relative;
+  overflow: hidden;
 }
 }
 
 
-.status-badge.normal {
-  background-color: #e6fffa;
-  color: #38b2ac;
+.chart-mockup {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  padding: 30px 40px;
 }
 }
 
 
-.status-badge.warning {
-  background-color: #fffaf0;
-  color: #dd6b20;
+.grid-lines {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
 }
 
 
-.status-badge.critical {
-  background-color: #fff5f5;
-  color: #e53e3e;
+.grid-line {
+  position: absolute;
+  width: 100%;
+  height: 1px;
+  background: rgba(0, 0, 0, 0.05);
 }
 }
 
 
-.chart-container {
-  margin-bottom: 25px;
+.grid-line:nth-child(1) { top: 25%; }
+.grid-line:nth-child(2) { top: 50%; }
+.grid-line:nth-child(3) { top: 75%; }
+.grid-line:nth-child(4) { bottom: 0; }
+
+.data-line {
+  position: absolute;
+  height: 3px;
+  border-radius: 3px;
+  bottom: 30px;
+  left: 40px;
+  right: 40px;
+  transform-origin: left;
 }
 }
 
 
-.chart-card {
-  background: white;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 3px 10px rgba(0,0,0,0.08);
-  border: 1px solid #eaeef2;
+.data-line.primary {
+  background: #3498db;
+  animation: drawLine 1.5s ease-out forwards;
 }
 }
 
 
-.chart-header {
+.data-line.secondary {
+  background: #9b59b6;
+  animation: drawLine 1.5s ease-out 0.3s forwards;
+  opacity: 0;
+}
+
+@keyframes drawLine {
+  0% {
+    transform: scaleX(0);
+    opacity: 0;
+  }
+  100% {
+    transform: scaleX(1);
+    opacity: 1;
+  }
+}
+
+.x-axis {
+  position: absolute;
+  bottom: 10px;
+  left: 40px;
+  right: 40px;
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
-  align-items: center;
+  font-size: 12px;
+  color: #666;
+}
+
+.y-axis {
+  position: absolute;
+  left: 20px;
+  top: 30px;
+  bottom: 30px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  font-size: 12px;
+  color: #666;
+}
+
+.chart-hover-info {
+  position: absolute;
+  bottom: 10px;
+  left: 0;
+  right: 0;
+  text-align: center;
+  font-size: 12px;
+  color: #999;
+  padding: 4px;
+  background: rgba(255, 255, 255, 0.7);
+}
+
+.metrics-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 20px;
+  padding: 0 20px;
   margin-bottom: 20px;
   margin-bottom: 20px;
 }
 }
 
 
-.chart-header h4 {
-  margin: 0;
-  font-size: 16px;
-  color: #2c3e50;
-  font-weight: 600;
+.metric-card {
+  background: white;
+  border-radius: 8px;
+  padding: 16px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
 }
 }
 
 
-.chart-legend {
+.metric-header {
   display: flex;
   display: flex;
-  gap: 20px;
-  font-size: 14px;
-  color: #4a5568;
+  align-items: center;
+  gap: 10px;
+  margin-bottom: 12px;
 }
 }
 
 
-.color-dot {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
+.metric-header i {
+  font-size: 20px;
+  color: #3498db;
+  width: 36px;
+  height: 36px;
+  background: rgba(52, 152, 219, 0.1);
   border-radius: 50%;
   border-radius: 50%;
-  margin-right: 8px;
-  vertical-align: middle;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 }
 
 
-.color-dot.primary { background: #3498db; }
-.color-dot.secondary { background: #9b59b6; }
+.metric-header h4 {
+  margin: 0;
+  font-size: 14px;
+  font-weight: 500;
+  color: #666;
+}
 
 
-.chart-content {
-  height: 400px;
-  background: #f8fafc;
-  border-radius: 6px;
-  position: relative;
-  padding: 30px 40px;
-  border: 1px solid #eaeef2;
+.metric-value {
+  font-size: 24px;
+  font-weight: 600;
+  color: #2c3e50;
+  margin-bottom: 8px;
 }
 }
 
 
-/* 响应式设计 */
-@media (max-width: 768px) {
-  .filter-row {
-    flex-direction: column;
-    gap: 15px;
-  }
+.metric-value .unit {
+  font-size: 14px;
+  color: #999;
+  margin-left: 4px;
+  font-weight: 400;
+}
 
 
-  .date-controls {
-    grid-template-columns: 1fr;
-  }
+.metric-change {
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
 
 
-  .device-controls {
-    flex-direction: column;
-    align-items: flex-start;
-  }
+.metric-change.positive {
+  color: #27ae60;
+}
 
 
-  .data-table {
-    display: block;
-    overflow-x: auto;
-  }
+.metric-change.negative {
+  color: #e74c3c;
 }
 }
-.chart-container {
-  margin-bottom: 25px;
+
+.metric-change.neutral {
+  color: #7f8c8d;
 }
 }
 
 
-.chart-card {
-  background: white;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 3px 10px rgba(0,0,0,0.08);
-  border: 1px solid #eaeef2;
+.data-table-card {
+  padding: 0 20px;
+  margin-bottom: 20px;
 }
 }
 
 
-.chart-header {
+.table-header {
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
   align-items: center;
   align-items: center;
-  margin-bottom: 20px;
+  margin-bottom: 16px;
 }
 }
 
 
-.chart-header h3 {
+.table-header h3 {
   margin: 0;
   margin: 0;
   font-size: 16px;
   font-size: 16px;
-  color: #2c3e50;
   font-weight: 600;
   font-weight: 600;
+  color: #333;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 10px;
   gap: 10px;
 }
 }
 
 
-.chart-header h3 i {
+.table-header i {
   color: #3498db;
   color: #3498db;
 }
 }
 
 
-.chart-legend {
+.table-actions {
   display: flex;
   display: flex;
-  gap: 20px;
-  font-size: 14px;
-  color: #4a5568;
+  align-items: center;
+  gap: 12px;
 }
 }
 
 
-.color-dot {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-  margin-right: 8px;
-  vertical-align: middle;
+.search-box {
+  position: relative;
 }
 }
 
 
-.color-dot.primary { background: #3498db; }
-.color-dot.secondary { background: #9b59b6; }
+.search-box i {
+  position: absolute;
+  left: 12px;
+  top: 50%;
+  transform: translateY(-50%);
+  color: #999;
+}
 
 
-#vibrationChart {
-  width: 100%;
+.search-box input {
+  padding: 8px 12px 8px 36px;
   border-radius: 6px;
   border-radius: 6px;
-  background: #f8fafc;
-  border: 1px solid #eaeef2;
+  border: 1px solid #ddd;
+  font-size: 14px;
+  width: 200px;
+  transition: all 0.2s;
 }
 }
-/* 振动图表专用样式 */
-.chart-container {
-  margin-bottom: 25px;
+
+.search-box input:focus {
+  outline: none;
+  border-color: #3498db;
+  box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
 }
 }
 
 
-.chart-card {
-  background: white;
-  border-radius: 8px;
-  padding: 20px;
-  box-shadow: 0 3px 10px rgba(0,0,0,0.08);
-  border: 1px solid #eaeef2;
+.table-responsive {
+  overflow-x: auto;
 }
 }
 
 
-.chart-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 20px;
+.data-table {
+  width: 100%;
+  border-collapse: collapse;
+  font-size: 14px;
 }
 }
 
 
-.chart-header h3 {
-  margin: 0;
-  font-size: 16px;
-  color: #2c3e50;
+.data-table th {
+  background: #f5f7fa;
+  padding: 12px 16px;
+  text-align: left;
   font-weight: 600;
   font-weight: 600;
-  display: flex;
-  align-items: center;
-  gap: 10px;
+  color: #2c3e50;
+  position: relative;
+  white-space: nowrap;
 }
 }
 
 
-.chart-header h3 i {
-  color: #3498db;
+.data-table th i {
+  margin-left: 6px;
+  color: #999;
+  font-size: 12px;
 }
 }
 
 
-.chart-legend {
-  display: flex;
-  gap: 20px;
-  font-size: 14px;
-  color: #4a5568;
+.data-table td {
+  padding: 12px 16px;
+  border-bottom: 1px solid #eee;
+  color: #555;
 }
 }
 
 
-.color-dot {
-  display: inline-block;
-  width: 12px;
-  height: 12px;
-  border-radius: 50%;
-  margin-right: 8px;
-  vertical-align: middle;
+.data-table tr:hover td {
+  background: #f8fafc;
 }
 }
 
 
-.color-dot.primary { background: #3498db; }
-.color-dot.secondary { background: #9b59b6; }
-
-.chart-content {
-  height: 400px;
-  background: #f8fafc;
-  border-radius: 6px;
+.progress-bar {
+  height: 24px;
+  background: #f0f0f0;
+  border-radius: 12px;
   position: relative;
   position: relative;
-  border: 1px solid #eaeef2;
   overflow: hidden;
   overflow: hidden;
 }
 }
 
 
-.trend-chart {
-  width: 100%;
+.progress-fill {
   height: 100%;
   height: 100%;
-  position: relative;
-  padding: 20px 30px 40px 40px;
+  border-radius: 12px;
+  position: absolute;
+  top: 0;
+  left: 0;
 }
 }
 
 
-.grid-lines {
+.progress-bar span {
   position: absolute;
   position: absolute;
-  top: 0;
   left: 0;
   left: 0;
-  width: 100%;
-  height: calc(100% - 30px);
+  right: 0;
+  text-align: center;
+  line-height: 24px;
+  font-size: 12px;
+  color: white;
+  z-index: 1;
+}
+
+.status-badge {
+  display: inline-flex;
+  align-items: center;
+  gap: 6px;
+  padding: 4px 8px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.status-badge i {
+  font-size: 10px;
+}
+
+.status-badge.normal {
+  background: rgba(46, 204, 113, 0.1);
+  color: #2ecc71;
+}
+
+.status-badge.warning {
+  background: rgba(241, 196, 15, 0.1);
+  color: #f1c40f;
+}
+
+.status-badge.critical {
+  background: rgba(231, 76, 60, 0.1);
+  color: #e74c3c;
+}
+
+.table-footer {
   display: flex;
   display: flex;
-  flex-direction: column;
   justify-content: space-between;
   justify-content: space-between;
-  padding: 20px 30px 0 40px;
+  align-items: center;
+  padding: 16px 0;
+  font-size: 14px;
+  color: #666;
 }
 }
 
 
-.grid-line {
-  height: 1px;
-  background-color: #eaeef2;
-  width: 100%;
+.pagination-controls {
+  display: flex;
+  gap: 8px;
 }
 }
 
 
-.data-line {
-  position: absolute;
-  height: 2px;
-  border-radius: 2px;
-  left: 40px;
-  right: 30px;
+.pagination-controls .btn {
+  width: 36px;
+  height: 36px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 6px;
+  border: 1px solid #ddd;
+  background: white;
 }
 }
 
 
-.data-line.primary {
-  background-color: #3498db;
-  top: 30%;
+.pagination-controls .btn.active {
+  background: #3498db;
+  color: white;
+  border-color: #3498db;
 }
 }
 
 
-.data-line.secondary {
-  background-color: #9b59b6;
-  top: 60%;
+.report-section {
+  padding: 20px;
+  background: white;
+  border-radius: 8px;
+  margin: 0 20px 20px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
 }
 }
 
 
-.x-axis {
-  position: absolute;
-  bottom: 10px;
-  left: 40px;
-  right: 30px;
+.section-header h3 {
+  margin: 0 0 4px;
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
   display: flex;
   display: flex;
-  justify-content: space-between;
-  font-size: 12px;
-  color: #718096;
+  align-items: center;
+  gap: 10px;
 }
 }
 
 
-.y-axis {
-  position: absolute;
-  left: 10px;
-  top: 20px;
-  bottom: 40px;
+.section-header i {
+  color: #3498db;
+}
+
+.section-header p {
+  margin: 0;
+  font-size: 13px;
+  color: #666;
+}
+
+.report-options {
   display: flex;
   display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  font-size: 12px;
-  color: #718096;
+  gap: 12px;
+  margin-top: 16px;
 }
 }
 
 
 /* 响应式设计 */
 /* 响应式设计 */
+@media (max-width: 1200px) {
+  .metrics-grid {
+    grid-template-columns: repeat(2, 1fr);
+  }
+}
+
 @media (max-width: 768px) {
 @media (max-width: 768px) {
-  .chart-header {
+  .filter-row {
     flex-direction: column;
     flex-direction: column;
-    align-items: flex-start;
-    gap: 10px;
   }
   }
-
-  .chart-legend {
-    width: 100%;
-    justify-content: space-between;
-    gap: 10px;
+  
+  .date-controls {
+    grid-template-columns: 1fr;
   }
   }
-
-  .trend-chart {
-    padding: 15px 20px 30px 30px;
+  
+  .metrics-grid {
+    grid-template-columns: 1fr;
   }
   }
-
-  .grid-lines {
-    padding: 15px 20px 0 30px;
+  
+  .table-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
   }
   }
-
-  .data-line {
-    left: 30px;
-    right: 20px;
+  
+  .search-box input {
+    width: 100%;
   }
   }
-
-  .x-axis {
-    left: 30px;
-    right: 20px;
+  
+  .table-footer {
+    flex-direction: column;
+    gap: 12px;
+    align-items: flex-start;
   }
   }
-}
+}

+ 0 - 1
industry-monitor-web/src/app/pages/historical-data/historical-data.spec.ts

@@ -21,4 +21,3 @@ describe('HistoricalData', () => {
     expect(component).toBeTruthy();
     expect(component).toBeTruthy();
   });
   });
 });
 });
-

+ 68 - 64
industry-monitor-web/src/app/pages/system-settings/system-settings.component.html

@@ -14,37 +14,41 @@
             </button>
             </button>
         </div>
         </div>
     </div>
     </div>
-    
+
+     <!-- 顶部导航标签 -->
+  <div class="settings-tabs-container">
+    <div class="settings-tabs">
+      <div class="settings-tab active" (click)="setActiveTab('users')" [class.active]="activeTab === 'users'">
+        <i class="fas fa-users"></i> 用户管理
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('alerts')" [class.active]="activeTab === 'alerts'">
+        <i class="fas fa-bell"></i> 警报设置
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('templates')" [class.active]="activeTab === 'templates'">
+        <i class="fas fa-cubes"></i> 设备模板
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('system')" [class.active]="activeTab === 'system'">
+        <i class="fas fa-server"></i> 系统参数
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('roles')" [class.active]="activeTab === 'roles'">
+        <i class="fas fa-key"></i> 权限管理
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('logs')" [class.active]="activeTab === 'logs'">
+        <i class="fas fa-clipboard-list"></i> 系统日志
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('license')" [class.active]="activeTab === 'license'">
+        <i class="fas fa-id-card"></i> 许可证信息
+      </div>
+      <div class="settings-tab" (click)="setActiveTab('backup')" [class.active]="activeTab === 'backup'">
+        <i class="fas fa-cloud-download-alt"></i> 备份与恢复
+      </div>
+    </div>
+  </div>
+
     <!-- 主体内容区域 -->
     <!-- 主体内容区域 -->
     <div class="settings-body">
     <div class="settings-body">
-        <!-- 左侧导航菜单 -->
-        <div class="settings-sidebar">
-            <div class="settings-tab active" data-tab="users">
-                <i class="fas fa-users"></i> 用户管理
-            </div>
-            <div class="settings-tab" data-tab="alerts">
-                <i class="fas fa-bell"></i> 警报设置
-            </div>
-            <div class="settings-tab" data-tab="templates">
-                <i class="fas fa-cubes"></i> 设备模板
-            </div>
-            <div class="settings-tab" data-tab="system">
-                <i class="fas fa-server"></i> 系统参数
-            </div>
-            <div class="settings-tab" data-tab="roles">
-                <i class="fas fa-key"></i> 权限管理
-            </div>
-            <div class="settings-tab" data-tab="logs">
-                <i class="fas fa-clipboard-list"></i> 系统日志
-            </div>
-            <div class="settings-tab" data-tab="license">
-                <i class="fas fa-id-card"></i> 许可证信息
-            </div>
-            <div class="settings-tab" data-tab="backup">
-                <i class="fas fa-cloud-download-alt"></i> 备份与恢复
-            </div>
-        </div>
-        
+
+
         <!-- 右侧设置内容 -->
         <!-- 右侧设置内容 -->
         <div class="settings-content">
         <div class="settings-content">
             <!-- 用户管理 -->
             <!-- 用户管理 -->
@@ -55,7 +59,7 @@
                         <i class="fas fa-user-plus"></i> 添加新用户
                         <i class="fas fa-user-plus"></i> 添加新用户
                     </button>
                     </button>
                 </div>
                 </div>
-                
+
                 <div class="users-grid">
                 <div class="users-grid">
                     <!-- 管理员用户 -->
                     <!-- 管理员用户 -->
                     <div class="user-card">
                     <div class="user-card">
@@ -71,7 +75,7 @@
                                 <strong>用户名:</strong> admin&#64;factory.com
                                 <strong>用户名:</strong> admin&#64;factory.com
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
-                                <strong>角色:</strong> 
+                                <strong>角色:</strong>
                                 <span class="role-badge badge-admin">管理员</span>
                                 <span class="role-badge badge-admin">管理员</span>
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
@@ -90,7 +94,7 @@
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <!-- 工程师用户 -->
                     <!-- 工程师用户 -->
                     <div class="user-card">
                     <div class="user-card">
                         <div class="user-header">
                         <div class="user-header">
@@ -105,7 +109,7 @@
                                 <strong>用户名:</strong> liqiang&#64;factory.com
                                 <strong>用户名:</strong> liqiang&#64;factory.com
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
-                                <strong>角色:</strong> 
+                                <strong>角色:</strong>
                                 <span class="role-badge badge-engineer">工程师</span>
                                 <span class="role-badge badge-engineer">工程师</span>
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
@@ -124,7 +128,7 @@
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <!-- 操作员用户 -->
                     <!-- 操作员用户 -->
                     <div class="user-card">
                     <div class="user-card">
                         <div class="user-header">
                         <div class="user-header">
@@ -139,7 +143,7 @@
                                 <strong>用户名:</strong> wangfang&#64;factory.com
                                 <strong>用户名:</strong> wangfang&#64;factory.com
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
-                                <strong>角色:</strong> 
+                                <strong>角色:</strong>
                                 <span class="role-badge badge-operator">操作员</span>
                                 <span class="role-badge badge-operator">操作员</span>
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
@@ -158,7 +162,7 @@
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <!-- 只读用户 -->
                     <!-- 只读用户 -->
                     <div class="user-card">
                     <div class="user-card">
                         <div class="user-header">
                         <div class="user-header">
@@ -173,7 +177,7 @@
                                 <strong>用户名:</strong> zhaoyu&#64;factory.com
                                 <strong>用户名:</strong> zhaoyu&#64;factory.com
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
-                                <strong>角色:</strong> 
+                                <strong>角色:</strong>
                                 <span class="role-badge badge-viewer">主管</span>
                                 <span class="role-badge badge-viewer">主管</span>
                             </div>
                             </div>
                             <div class="user-detail">
                             <div class="user-detail">
@@ -194,14 +198,14 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            
+
             <!-- 警报设置 -->
             <!-- 警报设置 -->
             <div id="alerts" class="tab-content">
             <div id="alerts" class="tab-content">
                 <div class="section-header">
                 <div class="section-header">
                     <h2><i class="fas fa-bell"></i> 警报设置</h2>
                     <h2><i class="fas fa-bell"></i> 警报设置</h2>
                     <p>自定义系统警报阈值和通知方式</p>
                     <p>自定义系统警报阈值和通知方式</p>
                 </div>
                 </div>
-                
+
                 <div class="settings-card">
                 <div class="settings-card">
                     <div class="form-group">
                     <div class="form-group">
                         <label>振动警报阈值 (mm/s)</label>
                         <label>振动警报阈值 (mm/s)</label>
@@ -210,7 +214,7 @@
                             <div class="slider-value">0.8 mm/s</div>
                             <div class="slider-value">0.8 mm/s</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-group">
                     <div class="form-group">
                         <label>温度警报阈值 (°C)</label>
                         <label>温度警报阈值 (°C)</label>
                         <div class="slider-container">
                         <div class="slider-container">
@@ -218,7 +222,7 @@
                             <div class="slider-value">75°C</div>
                             <div class="slider-value">75°C</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-group">
                     <div class="form-group">
                         <label>转速偏差阈值 (%)</label>
                         <label>转速偏差阈值 (%)</label>
                         <div class="slider-container">
                         <div class="slider-container">
@@ -226,11 +230,11 @@
                             <div class="slider-value">15%</div>
                             <div class="slider-value">15%</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <h3 class="section-subheader">
                     <h3 class="section-subheader">
                         <i class="fas fa-envelope"></i> 通知设置
                         <i class="fas fa-envelope"></i> 通知设置
                     </h3>
                     </h3>
-                    
+
                     <div class="notification-item">
                     <div class="notification-item">
                         <div class="notification-icon">
                         <div class="notification-icon">
                             <i class="fas fa-envelope"></i>
                             <i class="fas fa-envelope"></i>
@@ -244,7 +248,7 @@
                             <span class="slider"></span>
                             <span class="slider"></span>
                         </label>
                         </label>
                     </div>
                     </div>
-                    
+
                     <div class="notification-item">
                     <div class="notification-item">
                         <div class="notification-icon">
                         <div class="notification-icon">
                             <i class="fas fa-mobile-alt"></i>
                             <i class="fas fa-mobile-alt"></i>
@@ -258,7 +262,7 @@
                             <span class="slider"></span>
                             <span class="slider"></span>
                         </label>
                         </label>
                     </div>
                     </div>
-                    
+
                     <div class="notification-item">
                     <div class="notification-item">
                         <div class="notification-icon">
                         <div class="notification-icon">
                             <i class="fas fa-bell"></i>
                             <i class="fas fa-bell"></i>
@@ -272,21 +276,21 @@
                             <span class="slider"></span>
                             <span class="slider"></span>
                         </label>
                         </label>
                     </div>
                     </div>
-                    
+
                     <div class="form-footer">
                     <div class="form-footer">
                         <button class="btn btn-outline">取消</button>
                         <button class="btn btn-outline">取消</button>
                         <button class="btn btn-primary">保存设置</button>
                         <button class="btn btn-primary">保存设置</button>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            
+
             <!-- 系统参数 -->
             <!-- 系统参数 -->
             <div id="system" class="tab-content">
             <div id="system" class="tab-content">
                 <div class="section-header">
                 <div class="section-header">
                     <h2><i class="fas fa-server"></i> 系统参数配置</h2>
                     <h2><i class="fas fa-server"></i> 系统参数配置</h2>
                     <p>调整系统核心参数和配置选项</p>
                     <p>调整系统核心参数和配置选项</p>
                 </div>
                 </div>
-                
+
                 <div class="system-status">
                 <div class="system-status">
                     <div class="status-card">
                     <div class="status-card">
                         <div class="status-icon system">
                         <div class="status-icon system">
@@ -298,7 +302,7 @@
                             <div class="status-value">98.7%</div>
                             <div class="status-value">98.7%</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="status-card">
                     <div class="status-card">
                         <div class="status-icon database">
                         <div class="status-icon database">
                             <i class="fas fa-database"></i>
                             <i class="fas fa-database"></i>
@@ -309,7 +313,7 @@
                             <div class="status-value">64%</div>
                             <div class="status-value">64%</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="status-card">
                     <div class="status-card">
                         <div class="status-icon security">
                         <div class="status-icon security">
                             <i class="fas fa-shield-alt"></i>
                             <i class="fas fa-shield-alt"></i>
@@ -320,7 +324,7 @@
                             <div class="status-value">无威胁</div>
                             <div class="status-value">无威胁</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="status-card">
                     <div class="status-card">
                         <div class="status-icon analytics">
                         <div class="status-icon analytics">
                             <i class="fas fa-chart-line"></i>
                             <i class="fas fa-chart-line"></i>
@@ -332,12 +336,12 @@
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
-                
+
                 <div class="settings-card">
                 <div class="settings-card">
                     <h3 class="section-subheader">
                     <h3 class="section-subheader">
                         <i class="fas fa-cogs"></i> 高级配置
                         <i class="fas fa-cogs"></i> 高级配置
                     </h3>
                     </h3>
-                    
+
                     <div class="form-row">
                     <div class="form-row">
                         <div class="form-group">
                         <div class="form-group">
                             <label>数据采集频率</label>
                             <label>数据采集频率</label>
@@ -348,7 +352,7 @@
                                 <option>每分钟</option>
                                 <option>每分钟</option>
                             </select>
                             </select>
                         </div>
                         </div>
-                        
+
                         <div class="form-group">
                         <div class="form-group">
                             <label>数据保留策略</label>
                             <label>数据保留策略</label>
                             <select class="form-control">
                             <select class="form-control">
@@ -359,7 +363,7 @@
                             </select>
                             </select>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-group">
                     <div class="form-group">
                         <label>系统API密钥</label>
                         <label>系统API密钥</label>
                         <div class="api-key-container">
                         <div class="api-key-container">
@@ -372,7 +376,7 @@
                             </button>
                             </button>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-group">
                     <div class="form-group">
                         <label>系统维护模式</label>
                         <label>系统维护模式</label>
                         <div class="toggle-container">
                         <div class="toggle-container">
@@ -385,26 +389,26 @@
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-footer">
                     <div class="form-footer">
                         <button class="btn btn-outline">取消</button>
                         <button class="btn btn-outline">取消</button>
                         <button class="btn btn-primary">保存配置</button>
                         <button class="btn btn-primary">保存配置</button>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            
+
             <!-- 备份与恢复 -->
             <!-- 备份与恢复 -->
             <div id="backup" class="tab-content">
             <div id="backup" class="tab-content">
                 <div class="section-header">
                 <div class="section-header">
                     <h2><i class="fas fa-cloud-download-alt"></i> 备份与恢复</h2>
                     <h2><i class="fas fa-cloud-download-alt"></i> 备份与恢复</h2>
                     <p>管理您的系统备份和数据恢复</p>
                     <p>管理您的系统备份和数据恢复</p>
                 </div>
                 </div>
-                
+
                 <div class="settings-card">
                 <div class="settings-card">
                     <h3 class="section-subheader">
                     <h3 class="section-subheader">
                         <i class="fas fa-history"></i> 最近备份
                         <i class="fas fa-history"></i> 最近备份
                     </h3>
                     </h3>
-                    
+
                     <div class="backup-list">
                     <div class="backup-list">
                         <div class="backup-item">
                         <div class="backup-item">
                             <div class="backup-icon">
                             <div class="backup-icon">
@@ -423,7 +427,7 @@
                                 </button>
                                 </button>
                             </div>
                             </div>
                         </div>
                         </div>
-                        
+
                         <div class="backup-item">
                         <div class="backup-item">
                             <div class="backup-icon">
                             <div class="backup-icon">
                                 <i class="fas fa-file-alt"></i>
                                 <i class="fas fa-file-alt"></i>
@@ -441,7 +445,7 @@
                                 </button>
                                 </button>
                             </div>
                             </div>
                         </div>
                         </div>
-                        
+
                         <div class="backup-item">
                         <div class="backup-item">
                             <div class="backup-icon">
                             <div class="backup-icon">
                                 <i class="fas fa-users"></i>
                                 <i class="fas fa-users"></i>
@@ -460,7 +464,7 @@
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="form-footer">
                     <div class="form-footer">
                         <button class="btn btn-primary">
                         <button class="btn btn-primary">
                             <i class="fas fa-plus"></i> 创建新备份
                             <i class="fas fa-plus"></i> 创建新备份
@@ -470,4 +474,4 @@
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
-</div>
+</div>

+ 4 - 0
industry-monitor-web/src/app/pages/system-settings/system-settings.component.ts

@@ -11,6 +11,7 @@ import { DatePipe } from '@angular/common';
 })
 })
 export class SystemSettingsComponent {
 export class SystemSettingsComponent {
 currentTime: Date = new Date();
 currentTime: Date = new Date();
+activeTab: string = 'users';
    ngOnInit(): void {
    ngOnInit(): void {
     // 更新时间,每秒更新一次
     // 更新时间,每秒更新一次
     setInterval(() => {
     setInterval(() => {
@@ -18,4 +19,7 @@ currentTime: Date = new Date();
     }, 1000);
     }, 1000);
 
 
    }
    }
+   setActiveTab(tab: string): void {
+    this.activeTab = tab;
+  }
 }
 }

+ 143 - 386
industry-monitor-web/src/app/pages/system-settings/system-settings.css

@@ -1,6 +1,6 @@
-/* 系统设置中心页面CSS样式 */
+/* 系统设置中心页面CSS样式 - 优化版 */
 
 
-/* 基础变量 - 与整体应用保持一致 */
+/* 基础变量 */
 :root {
 :root {
   --primary: #3498db;
   --primary: #3498db;
   --primary-dark: #2980b9;
   --primary-dark: #2980b9;
@@ -65,114 +65,49 @@
   gap: 10px;
   gap: 10px;
 }
 }
 
 
-/* 按钮样式 */
-.btn {
-  padding: 8px 18px;
-  border-radius: 30px;
-  border: none;
-  font-weight: 600;
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  transition: var(--transition);
-  font-size: 14px;
-}
-
-.btn-sm {
-  padding: 6px 14px;
-  font-size: 13px;
-}
-
-.btn-primary {
-  background: var(--primary);
-  color: white;
-}
-
-.btn-primary:hover {
-  background: var(--primary-dark);
-  transform: translateY(-2px);
-  box-shadow: var(--shadow-hover);
-}
-
-.btn-outline {
-  background: transparent;
-  border: 1px solid var(--primary);
-  color: var(--primary);
-}
-
-.btn-outline:hover {
-  background: rgba(52, 152, 219, 0.1);
-}
-
-.btn-danger {
-  background: rgba(231, 76, 60, 0.1);
-  color: var(--danger);
-  border: 1px solid rgba(231, 76, 60, 0.3);
-}
-
-.btn-danger:hover {
-  background: rgba(231, 76, 60, 0.2);
-}
-
-.btn-edit {
-  background: rgba(243, 156, 18, 0.1);
-  color: var(--warning);
-  border: 1px solid rgba(243, 156, 18, 0.3);
-}
-
-.btn-delete {
-  background: rgba(231, 76, 60, 0.1);
-  color: var(--danger);
-  border: 1px solid rgba(231, 76, 60, 0.3);
+/* 顶部导航标签容器 */
+.settings-tabs-container {
+  background: white;
+  border-bottom: 1px solid var(--light-gray);
+  padding: 0 20px;
+  overflow-x: auto;
 }
 }
 
 
-/* 主体内容区域 */
-.settings-body {
+.settings-tabs {
   display: flex;
   display: flex;
-  min-height: 600px;
-}
-
-/* 左侧导航菜单 */
-.settings-sidebar {
-  width: 240px;
-  background: white;
-  border-right: 1px solid var(--light-gray);
-  padding: 20px 0;
+  min-width: max-content;
 }
 }
 
 
 .settings-tab {
 .settings-tab {
-  padding: 12px 24px;
+  padding: 14px 24px;
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 12px;
   gap: 12px;
   cursor: pointer;
   cursor: pointer;
   transition: var(--transition);
   transition: var(--transition);
-  border-left: 4px solid transparent;
+  border-bottom: 3px solid transparent;
   font-weight: 500;
   font-weight: 500;
   color: var(--dark);
   color: var(--dark);
   font-size: 15px;
   font-size: 15px;
-}
-
-.settings-tab.active {
-  background: rgba(52, 152, 219, 0.1);
-  border-left: 4px solid var(--primary);
-  color: var(--primary);
+  white-space: nowrap;
 }
 }
 
 
 .settings-tab:hover:not(.active) {
 .settings-tab:hover:not(.active) {
   background: rgba(0, 0, 0, 0.03);
   background: rgba(0, 0, 0, 0.03);
 }
 }
 
 
+.settings-tab.active {
+  background: rgba(52, 152, 219, 0.05);
+  border-bottom: 3px solid var(--primary);
+  color: var(--primary);
+}
+
 .settings-tab i {
 .settings-tab i {
-  width: 24px;
-  text-align: center;
-  font-size: 18px;
+  font-size: 16px;
 }
 }
 
 
-/* 右侧设置内容 */
-.settings-content {
-  flex: 1;
+/* 主体内容区域 */
+.settings-body {
   padding: 24px;
   padding: 24px;
   background: #f9fbfd;
   background: #f9fbfd;
   min-height: 600px;
   min-height: 600px;
@@ -192,22 +127,68 @@
   to { opacity: 1; transform: translateY(0); }
   to { opacity: 1; transform: translateY(0); }
 }
 }
 
 
-/* 公共部分样式 */
-.section-header {
+/* 响应式设计 */
+@media (max-width: 992px) {
+  .settings-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 16px;
+  }
+
+  .setting-actions {
+    width: 100%;
+    justify-content: flex-end;
+  }
+}
+
+@media (max-width: 768px) {
+  .settings-tabs {
+    gap: 0;
+  }
+
+  .settings-tab {
+    padding: 12px 16px;
+    font-size: 14px;
+  }
+
+  .settings-tab i {
+    display: none;
+  }
+}
+
+@media (max-width: 480px) {
+  .settings-header h1 {
+    font-size: 18px;
+  }
+
+  .settings-tab {
+    padding: 10px 12px;
+    font-size: 13px;
+  }
+
+  .settings-body {
+    padding: 16px;
+  }
+}
+
+/* 用户管理卡片优化样式 */
+.users-header {
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
   align-items: center;
   align-items: center;
   margin-bottom: 24px;
   margin-bottom: 24px;
+  padding-bottom: 16px;
+  border-bottom: 1px solid var(--light-gray);
 }
 }
 
 
-.section-header h2 {
-  font-size: 20px;
+.users-header h2 {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
   gap: 12px;
   gap: 12px;
+  font-size: 20px;
+  color: var(--dark);
 }
 }
 
 
-/* 用户网格 */
 .users-grid {
 .users-grid {
   display: grid;
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
   grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
@@ -220,23 +201,25 @@
   box-shadow: var(--shadow);
   box-shadow: var(--shadow);
   overflow: hidden;
   overflow: hidden;
   transition: var(--transition);
   transition: var(--transition);
+  border: 1px solid var(--light-gray);
 }
 }
 
 
 .user-card:hover {
 .user-card:hover {
+  transform: translateY(-5px);
   box-shadow: var(--shadow-hover);
   box-shadow: var(--shadow-hover);
-  transform: translateY(-4px);
 }
 }
 
 
 .user-header {
 .user-header {
   display: flex;
   display: flex;
+  align-items: center;
   padding: 20px;
   padding: 20px;
-  gap: 16px;
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e8eb 100%);
   border-bottom: 1px solid var(--light-gray);
   border-bottom: 1px solid var(--light-gray);
 }
 }
 
 
 .user-avatar {
 .user-avatar {
-  width: 56px;
-  height: 56px;
+  width: 60px;
+  height: 60px;
   border-radius: 50%;
   border-radius: 50%;
   background: var(--primary);
   background: var(--primary);
   color: white;
   color: white;
@@ -245,19 +228,18 @@
   justify-content: center;
   justify-content: center;
   font-size: 24px;
   font-size: 24px;
   font-weight: bold;
   font-weight: bold;
+  margin-right: 16px;
+  box-shadow: 0 3px 6px rgba(0,0,0,0.1);
 }
 }
 
 
-.badge-admin .user-avatar { background: #e74c3c; }
-.badge-engineer .user-avatar { background: #3498db; }
-.badge-operator .user-avatar { background: #27ae60; }
-.badge-viewer .user-avatar { background: #f39c12; }
-
 .user-info h3 {
 .user-info h3 {
+  margin: 0;
   font-size: 18px;
   font-size: 18px;
-  margin-bottom: 4px;
+  color: var(--dark);
 }
 }
 
 
 .user-info p {
 .user-info p {
+  margin: 4px 0 0;
   color: var(--gray);
   color: var(--gray);
   font-size: 14px;
   font-size: 14px;
 }
 }
@@ -269,10 +251,13 @@
 .user-detail {
 .user-detail {
   margin-bottom: 12px;
   margin-bottom: 12px;
   font-size: 14px;
   font-size: 14px;
+  display: flex;
 }
 }
 
 
 .user-detail strong {
 .user-detail strong {
-  color: var(--dark);
+  min-width: 80px;
+  color: var(--gray);
+  font-weight: 500;
 }
 }
 
 
 .role-badge {
 .role-badge {
@@ -281,329 +266,101 @@
   border-radius: 20px;
   border-radius: 20px;
   font-size: 12px;
   font-size: 12px;
   font-weight: 600;
   font-weight: 600;
+  text-transform: uppercase;
 }
 }
 
 
-.badge-admin { background: rgba(231, 76, 60, 0.1); color: #e74c3c; }
-.badge-engineer { background: rgba(52, 152, 219, 0.1); color: #3498db; }
-.badge-operator { background: rgba(39, 174, 96, 0.1); color: #27ae60; }
-.badge-viewer { background: rgba(243, 156, 18, 0.1); color: #f39c12; }
-
-.user-actions {
-  display: flex;
-  gap: 10px;
-  margin-top: 16px;
-}
-
-/* 警报设置 */
-.settings-card {
-  background: white;
-  border-radius: var(--border-radius);
-  box-shadow: var(--shadow);
-  padding: 24px;
-  margin-bottom: 24px;
-}
-
-.form-group {
-  margin-bottom: 20px;
-}
-
-.form-group label {
-  display: block;
-  margin-bottom: 8px;
-  font-weight: 600;
-  color: var(--dark);
-}
-
-.slider-container {
-  display: flex;
-  align-items: center;
-  gap: 16px;
-}
-
-.slider-container input[type="range"] {
-  flex: 1;
-  height: 6px;
-  border-radius: 3px;
-  background: var(--light-gray);
-  outline: none;
-  -webkit-appearance: none;
-}
-
-.slider-container input[type="range"]::-webkit-slider-thumb {
-  -webkit-appearance: none;
-  width: 18px;
-  height: 18px;
-  border-radius: 50%;
-  background: var(--primary);
-  cursor: pointer;
-}
-
-.slider-value {
-  min-width: 80px;
-  text-align: right;
-  font-weight: 600;
-  color: var(--primary);
-}
-
-.section-subheader {
-  display: flex;
-  align-items: center;
-  gap: 10px;
-  margin: 24px 0 16px;
-  font-size: 18px;
-  color: var(--secondary);
-}
-
-.notification-item {
-  display: flex;
-  align-items: center;
-  padding: 16px;
-  border-radius: var(--border-radius);
-  background: var(--light);
-  margin-bottom: 12px;
+.badge-admin {
+  background: rgba(231, 76, 60, 0.1);
+  color: #e74c3c;
 }
 }
 
 
-.notification-icon {
-  width: 40px;
-  height: 40px;
-  border-radius: 50%;
+.badge-engineer {
   background: rgba(52, 152, 219, 0.1);
   background: rgba(52, 152, 219, 0.1);
-  display: flex;
-  align-items: center;
-  justify-content: center;
   color: var(--primary);
   color: var(--primary);
-  font-size: 18px;
-}
-
-.notification-info {
-  flex: 1;
-  padding: 0 16px;
-}
-
-.notification-info h4 {
-  margin-bottom: 4px;
-}
-
-.notification-info p {
-  color: var(--gray);
-  font-size: 14px;
-}
-
-.notification-switch {
-  position: relative;
-  display: inline-block;
-  width: 50px;
-  height: 24px;
 }
 }
 
 
-.notification-switch input {
-  opacity: 0;
-  width: 0;
-  height: 0;
+.badge-operator {
+  background: rgba(46, 204, 113, 0.1);
+  color: #2ecc71;
 }
 }
 
 
-.notification-switch .slider {
-  position: absolute;
-  cursor: pointer;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background-color: var(--light-gray);
-  transition: .4s;
-  border-radius: 34px;
-}
-
-.notification-switch .slider:before {
-  position: absolute;
-  content: "";
-  height: 16px;
-  width: 16px;
-  left: 4px;
-  bottom: 4px;
-  background-color: white;
-  transition: .4s;
-  border-radius: 50%;
+.badge-viewer {
+  background: rgba(155, 89, 182, 0.1);
+  color: #9b59b6;
 }
 }
 
 
-.notification-switch input:checked + .slider {
-  background-color: var(--success);
-}
-
-.notification-switch input:checked + .slider:before {
-  transform: translateX(26px);
-}
-
-.form-footer {
+.user-actions {
   display: flex;
   display: flex;
-  justify-content: flex-end;
-  gap: 12px;
-  margin-top: 24px;
+  gap: 8px;
+  margin-top: 16px;
   padding-top: 16px;
   padding-top: 16px;
   border-top: 1px solid var(--light-gray);
   border-top: 1px solid var(--light-gray);
 }
 }
 
 
-/* 系统状态 */
-.system-status {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
-  gap: 20px;
-  margin-bottom: 24px;
-}
-
-.status-card {
-  background: white;
+/* 优化按钮样式 */
+.btn {
+  padding: 8px 16px;
   border-radius: var(--border-radius);
   border-radius: var(--border-radius);
-  box-shadow: var(--shadow);
-  padding: 20px;
-  display: flex;
-  gap: 16px;
-  align-items: center;
-}
-
-.status-icon {
-  width: 60px;
-  height: 60px;
-  border-radius: 50%;
-  display: flex;
+  font-size: 14px;
+  font-weight: 500;
+  cursor: pointer;
+  transition: var(--transition);
+  display: inline-flex;
   align-items: center;
   align-items: center;
-  justify-content: center;
-  font-size: 24px;
-}
-
-.system .status-icon { background: rgba(52, 152, 219, 0.1); color: var(--primary); }
-.database .status-icon { background: rgba(46, 204, 113, 0.1); color: #2ecc71; }
-.security .status-icon { background: rgba(243, 156, 18, 0.1); color: var(--warning); }
-.analytics .status-icon { background: rgba(155, 89, 182, 0.1); color: #9b59b6; }
-
-.status-info h3 {
-  font-size: 17px;
-  margin-bottom: 4px;
-}
-
-.status-info p {
-  color: var(--gray);
-  font-size: 13px;
-  margin-bottom: 4px;
-}
-
-.status-value {
-  font-size: 20px;
-  font-weight: 700;
+  gap: 8px;
+  border: 1px solid transparent;
 }
 }
 
 
-/* 备份列表 */
-.backup-list {
-  margin: 16px 0;
+.btn-primary {
+  background-color: var(--primary);
+  color: white;
+  box-shadow: 0 2px 5px rgba(52, 152, 219, 0.3);
 }
 }
 
 
-.backup-item {
-  display: flex;
-  align-items: center;
-  padding: 16px;
-  border-radius: var(--border-radius);
-  background: var(--light);
-  margin-bottom: 12px;
+.btn-primary:hover {
+  background-color: var(--primary-dark);
+  transform: translateY(-3px);
+  box-shadow: 0 4px 8px rgba(52, 152, 219, 0.4);
 }
 }
 
 
-.backup-icon {
-  width: 40px;
-  height: 40px;
-  border-radius: 50%;
-  background: rgba(52, 152, 219, 0.1);
-  display: flex;
-  align-items: center;
-  justify-content: center;
+.btn-outline {
+  background-color: transparent;
   color: var(--primary);
   color: var(--primary);
-  font-size: 18px;
-}
-
-.backup-info {
-  flex: 1;
-  padding: 0 16px;
+  border: 1px solid var(--primary);
 }
 }
 
 
-.backup-info h4 {
-  margin-bottom: 4px;
+.btn-outline:hover {
+  background-color: rgba(52, 152, 219, 0.1);
+  transform: translateY(-3px);
+  box-shadow: 0 2px 5px rgba(52, 152, 219, 0.2);
 }
 }
 
 
-.backup-info p {
-  color: var(--gray);
-  font-size: 14px;
+/* 添加新用户按钮特殊样式 */
+.users-header .btn-primary {
+  padding: 10px 18px;
+  font-size: 15px;
 }
 }
 
 
-.backup-actions {
-  display: flex;
-  gap: 8px;
+.users-header .btn-primary:hover {
+  transform: translateY(-3px);
 }
 }
 
 
-/* 响应式设计 */
-@media (max-width: 992px) {
-  .settings-sidebar {
-    width: 200px;
-  }
-  
-  .users-grid {
-    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
-  }
+/* 按钮图标样式 */
+.btn i {
+  font-size: 14px;
 }
 }
 
 
+/* 响应式调整 */
 @media (max-width: 768px) {
 @media (max-width: 768px) {
-  .settings-body {
-    flex-direction: column;
-  }
-  
-  .settings-sidebar {
-    width: 100%;
-    display: flex;
-    overflow-x: auto;
-    padding: 10px 0;
-    border-right: none;
-    border-bottom: 1px solid var(--light-gray);
-  }
-  
-  .settings-tab {
-    padding: 10px 16px;
-    white-space: nowrap;
-  }
-  
   .users-grid {
   .users-grid {
     grid-template-columns: 1fr;
     grid-template-columns: 1fr;
   }
   }
-  
-  .system-status {
-    grid-template-columns: 1fr 1fr;
-  }
-  
-  .section-header {
-    flex-direction: column;
-    align-items: flex-start;
-    gap: 16px;
-  }
-}
 
 
-@media (max-width: 480px) {
-  .system-status {
-    grid-template-columns: 1fr;
-  }
-  
-  .settings-header {
-    flex-direction: column;
-    gap: 16px;
-    align-items: flex-start;
+  .user-header {
+    padding: 16px;
   }
   }
-  
-  .setting-actions {
-    width: 100%;
-    flex-wrap: wrap;
-  }
-  
-  .form-footer {
-    flex-direction: column;
-  }
-  
-  .btn {
-    width: 100%;
-    justify-content: center;
+
+  .user-body {
+    padding: 16px;
   }
   }
-}
+}

+ 36 - 0
industry-monitor-web/src/app/shared/directives/echarts.directive.ts

@@ -0,0 +1,36 @@
+// src/app/shared/directives/echarts.directive.ts
+import { Directive, ElementRef, Input, OnChanges, SimpleChanges } from '@angular/core';
+import * as echarts from 'echarts';
+
+@Directive({
+  selector: '[appEchart]',
+  standalone: true
+})
+export class EchartDirective implements OnChanges {
+  @Input() echartOptions: any;
+  private chart: any;
+
+  constructor(private el: ElementRef) {}
+
+  ngOnChanges(changes: SimpleChanges) {
+    if (changes['echartOptions']) {
+      this.renderChart();
+    }
+  }
+
+  private renderChart() {
+    if (!this.chart) {
+      this.chart = echarts.init(this.el.nativeElement);
+    }
+
+    if (this.echartOptions) {
+      this.chart.setOption(this.echartOptions);
+    }
+  }
+
+  ngOnDestroy() {
+    if (this.chart) {
+      this.chart.dispose();
+    }
+  }
+}

+ 1 - 1
industry-monitor-web/src/lib/ncloud.ts

@@ -428,4 +428,4 @@ export class CloudApi {
         let json = await response.json();
         let json = await response.json();
         return json
         return json
     }
     }
-}
+}

+ 0 - 6
package-lock.json

@@ -1,6 +0,0 @@
-{
-  "name": "industry-monitor",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {}
-}