Просмотр исходного кода

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

工业检测 2 дней назад
Родитель
Сommit
057dcef2d2

+ 2 - 6
REDEME.md

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

+ 65 - 39
industry-monitor-web/src/app/pages/device-monitor/device-monitor.component.html

@@ -1,41 +1,37 @@
+
 <!-- device-monitor.component.html -->
 <div class="monitor-container">
   <div class="monitor-header">
     <h2><i class="fa fa-microchip"></i> 单设备监测面板</h2>
-    <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 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>
 
   <div class="monitor-row">
     <div class="waveform-card">
       <h3><i class="fa fa-wave-square"></i> 振动波形图 (40秒周期)</h3>
-      <!-- 修改1: 使用 appEchart 指令和 echartOptions 绑定 -->
-      <div class="waveform-container" 
-           appEchart 
-           [echartOptions]="chartOptions">
+      <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>
       </div>
       <div class="waveform-controls">
         <div class="threshold-control">
-          <label>阈值上限: {{ upperThreshold }} mm/s</label>
-          <!-- 修改2: 更新滑块绑定 -->
-          <input type="range" min="0.1" max="1.5" step="0.05" 
-                 [(ngModel)]="upperThreshold" 
-                 (input)="updateThreshold()">
+          <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">
         </div>
         <div class="threshold-control">
-          <label>阈值下限: {{ lowerThreshold }} mm/s</label>
-          <input type="range" min="0.1" max="1.5" step="0.05" 
-                 [(ngModel)]="lowerThreshold" 
-                 (input)="updateThreshold()">
+          <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">
         </div>
       </div>
     </div>
@@ -43,14 +39,40 @@
     <div class="status-panel">
       <h3><i class="fa fa-heartbeat"></i> 实时状态</h3>
       <div class="status-grid">
-        <!-- 修改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 class="status-card">
+          <div class="status-icon blue">
+            <i class="fa fa-wave-square"></i>
+          </div>
+          <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">{{ status.label }}</div>
-            <div class="status-value">{{ status.value }} {{ status.unit }}</div>
+            <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>
         </div>
       </div>
@@ -80,16 +102,20 @@
     </div>
     
     <div class="alert-history">
-      <!-- 修改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 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>
       </div>
     </div>
   </div>

+ 9 - 152
industry-monitor-web/src/app/pages/device-monitor/device-monitor.component.ts

@@ -1,164 +1,21 @@
-import { Component, ViewEncapsulation, OnInit } from '@angular/core';
+import { Component, ViewEncapsulation } from '@angular/core';
 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({
   standalone: true,
   selector: 'app-device-monitor',
-  templateUrl: './device-monitor.component.html',
   styleUrls: ['./device-monitor.css'],
-  imports: [
-    DatePipe,
-    CommonModule,
-    FormsModule,
-    EchartDirective
-  ],
+  imports: [DatePipe],
+  templateUrl: './device-monitor.component.html',
   encapsulation: ViewEncapsulation.None
 })
-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 {
+export class DeviceMonitorComponent {
+currentTime: Date = new Date();
+   ngOnInit(): void {
+    // 更新时间,每秒更新一次
     setInterval(() => {
       this.currentTime = new Date();
     }, 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();
-  }
-}
+   }
+}

+ 51 - 115
industry-monitor-web/src/app/pages/device-monitor/device-monitor.css

@@ -1,9 +1,8 @@
-device-monitor.component.css
+/* device-monitor.component.css */
 :host {
   display: block;
   width: 100%;
   padding: 15px;
-  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 
 .monitor-container {
@@ -32,12 +31,6 @@ device-monitor.component.css
   color: #2c3e50;
 }
 
-.header-info {
-  display: flex;
-  flex-direction: column;
-  align-items: flex-end;
-}
-
 .device-info {
   display: grid;
   grid-template-columns: repeat(2, 1fr);
@@ -46,15 +39,6 @@ device-monitor.component.css
   background: #f8fafc;
   padding: 15px;
   border-radius: 6px;
-  margin-bottom: 10px;
-}
-
-.current-time {
-  font-size: 14px;
-  background: #f8fafc;
-  padding: 8px 15px;
-  border-radius: 4px;
-  font-weight: 500;
 }
 
 .monitor-row {
@@ -63,20 +47,12 @@ device-monitor.component.css
   margin-bottom: 20px;
 }
 
-@media (max-width: 1200px) {
-  .monitor-row {
-    flex-direction: column;
-  }
-}
-
 .waveform-card {
   flex: 2;
   background: white;
   border-radius: 8px;
   padding: 20px;
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-  display: flex;
-  flex-direction: column;
 }
 
 .status-panel {
@@ -85,24 +61,66 @@ device-monitor.component.css
   border-radius: 8px;
   padding: 20px;
   box-shadow: 0 2px 8px rgba(0,0,0,0.1);
-  display: flex;
-  flex-direction: column;
 }
 
 .waveform-container {
   height: 250px;
-  background: #f8fafc;
+  background: #f1f8ff;
   border-radius: 6px;
-  margin: 15px 0;
+  margin: 20px 0;
   position: relative;
   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 {
   display: flex;
   gap: 20px;
-  margin-top: 15px;
 }
 
 .threshold-control {
@@ -113,26 +131,10 @@ device-monitor.component.css
   display: block;
   margin-bottom: 8px;
   font-size: 14px;
-  font-weight: 500;
 }
 
 .threshold-control input {
   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 {
@@ -148,14 +150,8 @@ device-monitor.component.css
   gap: 15px;
   padding: 15px;
   background: #f8fafc;
-  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);
+  border-radius: 6px;
+  border-left: 3px solid #3498db;
 }
 
 .status-icon {
@@ -167,7 +163,6 @@ device-monitor.component.css
   justify-content: center;
   font-size: 18px;
   color: white;
-  flex-shrink: 0;
 }
 
 .status-icon.blue { background: #3498db; }
@@ -191,10 +186,6 @@ device-monitor.component.css
   color: #2c3e50;
 }
 
-.progress-container {
-  margin-top: auto;
-}
-
 .progress-steps {
   display: flex;
   justify-content: space-between;
@@ -211,23 +202,6 @@ device-monitor.component.css
   justify-content: center;
   font-weight: 700;
   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 {
@@ -235,15 +209,10 @@ device-monitor.component.css
   color: white;
 }
 
-.step.active::after {
-  background: #3498db;
-}
-
 .step.current {
   background: #27ae60;
   color: white;
   transform: scale(1.2);
-  box-shadow: 0 0 0 4px rgba(39, 174, 96, 0.3);
 }
 
 .history-panel {
@@ -260,30 +229,6 @@ device-monitor.component.css
   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 {
   border: 1px solid #eee;
   border-radius: 6px;
@@ -295,11 +240,6 @@ device-monitor.component.css
   align-items: center;
   padding: 12px 15px;
   border-bottom: 1px solid #eee;
-  transition: background 0.2s;
-}
-
-.history-item:hover {
-  background: #f9f9f9;
 }
 
 .history-item:last-child {
@@ -310,7 +250,6 @@ device-monitor.component.css
   width: 90px;
   font-weight: 500;
   color: #2c3e50;
-  flex-shrink: 0;
 }
 
 .alert-desc {
@@ -322,9 +261,6 @@ device-monitor.component.css
   border-radius: 4px;
   font-size: 13px;
   font-weight: 500;
-  width: 60px;
-  text-align: center;
-  flex-shrink: 0;
 }
 
 .alert-level.warning {

+ 39 - 154
industry-monitor-web/src/app/pages/factory-overview/factory-overview.component.html

@@ -1,32 +1,14 @@
-<!-- factory-overview.component.html -->
+
 <div class="dashboard">
   <div class="dashboard-header">
-    <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>
+    <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>
   </div>
 
   <div class="metric-grid">
-    <div class="metric-card" (mouseenter)="cardHover(0)" [class.hover]="hoverIndex === 0">
+    <div class="metric-card">
       <div class="metric-icon blue">
         <i class="fa fa-cogs"></i>
       </div>
@@ -34,16 +16,10 @@
         <h3>设备运行状态</h3>
         <p class="metric-value">45/50</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 class="metric-card" (mouseenter)="cardHover(1)" [class.hover]="hoverIndex === 1">
+    <div class="metric-card">
       <div class="metric-icon orange">
         <i class="fa fa-exclamation-triangle"></i>
       </div>
@@ -51,16 +27,10 @@
         <h3>今日预警</h3>
         <p class="metric-value">12</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 class="metric-card" (mouseenter)="cardHover(2)" [class.hover]="hoverIndex === 2">
+    <div class="metric-card">
       <div class="metric-icon green">
         <i class="fa fa-heartbeat"></i>
       </div>
@@ -68,16 +38,10 @@
         <h3>设备健康指数</h3>
         <p class="metric-value">92%</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 class="metric-card" (mouseenter)="cardHover(3)" [class.hover]="hoverIndex === 3">
+    <div class="metric-card">
       <div class="metric-icon purple">
         <i class="fa fa-tachometer-alt"></i>
       </div>
@@ -85,153 +49,74 @@
         <h3>运行参数</h3>
         <p class="metric-value">65°C / 1450 RPM</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 class="dashboard-row">
-    <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 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>
-      </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 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>
     
-    <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-card">
+      <h3><i class="fa fa-bell"></i> 实时警报</h3>
       <div class="alert-list">
         <div class="alert-item critical">
           <i class="fa fa-exclamation-circle"></i>
           <div class="alert-content">
             <strong>设备 #A23 温度过高</strong>
             <span>车间B - 产线2 | 15:23:45</span>
+            <comp-star-rating 
+              [star]="rating" 
+              (onStarChange)="ratingChange($event)"
+            ></comp-star-rating>
+            <p>当前评分: {{rating}}</p>
           </div>
-          <div class="alert-status">未处理</div>
         </div>
         <div class="alert-item warning">
           <i class="fa fa-exclamation-triangle"></i>
           <div class="alert-content">
             <strong>设备 #B07 振动异常</strong>
             <span>车间A - 产线4 | 15:20:12</span>
+            <p>{{ 125006 | tok}}</p>
+            <p>{{ 100 | tok}}</p>
+            <p>{{ 99987565 | tok}}</p>
           </div>
-          <div class="alert-status">处理中</div>
         </div>
         <div class="alert-item info">
           <i class="fa fa-info-circle"></i>
-          <div class="alert-content">
+            <div class="alert-content">
             <strong>设备 #C15 转速过低</strong>
             <span>车间C - 产线1 | 14:58:33</span>
           </div>
-          <div class="alert-status">已处理</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 class="trend-card">
-    <div class="trend-header">
-      <h3><i class="fa fa-chart-line"></i> 健康指数趋势</h3>
-     
-      <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>
-
-    
-    
+    <h3><i class="fa fa-chart-line"></i> 健康指数趋势 (24小时)</h3>
     <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 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>

+ 26 - 16
industry-monitor-web/src/app/pages/factory-overview/factory-overview.component.ts

@@ -1,6 +1,8 @@
-// factory-overview.component.ts
+
 import { DatePipe } from '@angular/common';
 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({
   standalone: true,
@@ -8,28 +10,36 @@ import { Component, ViewEncapsulation } from '@angular/core';
   styleUrls: ['./factory-overview.css'],
   templateUrl: './factory-overview.component.html',
   encapsulation: ViewEncapsulation.None,
-  imports: [DatePipe]
+  imports: [
+    DatePipe,TokPipe,
+    CompStarRatingComponent
+  ]
+  
 })
 export class FactoryOverviewComponent {
+  rating:number = 0
+  ratingChange(rating: number) {
+    this.rating = rating;
+  }
   currentTime: Date = new Date();
-  hoverIndex: number = -1;
-
-  constructor() {
+   ngOnInit(): void {
     // 更新时间,每秒更新一次
     setInterval(() => {
       this.currentTime = new Date();
     }, 1000);
-  }
 
-  // 修复:添加 cardHover 方法
-  cardHover(index: number) {
-    this.hoverIndex = index;
   }
 
-  // 添加刷新数据方法
-  refreshData() {
-    // 这里可以添加实际的数据刷新逻辑
-    console.log('刷新数据...');
-    this.currentTime = new Date();
-  }
-}
+    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
+    }
+}

+ 21 - 368
industry-monitor-web/src/app/pages/factory-overview/factory-overview.css

@@ -1,9 +1,8 @@
-/* factory-overview.css */
+/* 组件容器样式 */
 :host {
   display: block;
   width: 100%;
   padding: 15px;
-  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 
 .dashboard {
@@ -25,53 +24,12 @@
   border-bottom: 1px solid #eee;
 }
 
-.header-left {
-  display: flex;
-  align-items: center;
-  gap: 30px;
-}
-
 .dashboard-header h2 {
   display: flex;
   align-items: center;
   gap: 10px;
   font-size: 24px;
   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 {
@@ -85,24 +43,6 @@
   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 {
   display: grid;
@@ -119,15 +59,6 @@
   display: flex;
   align-items: center;
   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 {
@@ -146,10 +77,6 @@
 .metric-icon.orange { background: #f39c12; }
 .metric-icon.purple { background: #9b59b6; }
 
-.metric-data {
-  flex: 1;
-}
-
 .metric-data h3 {
   font-size: 16px;
   font-weight: 600;
@@ -161,115 +88,19 @@
   font-size: 24px;
   font-weight: 700;
   color: #2c3e50;
-  margin: 5px 0;
 }
 
 .metric-label {
   font-size: 14px;
   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 {
   display: flex;
   align-items: center;
   gap: 30px;
-  padding: 10px 0;
+  padding: 20px 0;
 }
 
 .chart-container {
@@ -293,15 +124,6 @@
   top: 50%;
   left: 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 {
@@ -323,58 +145,9 @@
 .dot.warning { background: #f39c12; }
 .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 {
   margin-top: 15px;
-  max-height: 300px;
-  overflow-y: auto;
 }
 
 .alert-item {
@@ -386,12 +159,6 @@
   margin-bottom: 10px;
   background: #f9f9f9;
   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 {
@@ -432,158 +199,44 @@
   color: #95a5a6;
 }
 
-.alert-status {
-  padding: 4px 10px;
-  border-radius: 12px;
-  font-size: 12px;
-  font-weight: bold;
-}
-
-.alert-item.critical .alert-status {
-  background: #e74c3c;
-  color: white;
-}
-
-.alert-item.warning .alert-status {
-  background: #f39c12;
-  color: white;
-}
-
-.alert-item.info .alert-status {
-  background: #3498db;
-  color: white;
-}
-
-.alert-footer {
-  margin-top: 15px;
-  text-align: center;
-}
-
-.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;
-}
-
-.view-all-btn:hover {
-  background: #2980b9;
-}
-
 /* 趋势图样式 */
-.trend-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 15px;
-}
-
-.time-range-selector {
-  display: flex;
-  gap: 8px;
-}
-
-.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 {
   display: flex;
-  flex-direction: column;
+  align-items: flex-end;
+  gap: 10px;
   height: 200px;
   padding: 20px;
   background: #f8fafc;
   border-radius: 6px;
   margin-top: 15px;
-  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 {
   flex: 1;
   background: #3498db;
+  height: calc(var(--height) * 2px);
   border-radius: 4px 4px 0 0;
   position: relative;
-  transition: height 0.5s ease;
 }
 
-.graph-bar::after {
-  content: attr(style);
-  position: absolute;
-  top: -25px;
-  left: 50%;
-  transform: translateX(-50%);
-  background: rgba(0,0,0,0.7);
-  color: white;
-  padding: 3px 8px;
-  border-radius: 4px;
-  font-size: 12px;
-  opacity: 0;
-  transition: opacity 0.3s ease;
-}
-
-.graph-bar:hover::after {
-  opacity: 1;
+/* 仪表板行布局 */
+.dashboard-row {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
 }
 
-/* 响应式调整 */
-@media (max-width: 1200px) {
-  .dashboard-row {
-    flex-direction: column;
-  }
+.chart-card, .alert-card {
+  flex: 1;
+  background: white;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 }
 
-@media (max-width: 768px) {
-  .dashboard-header {
-    flex-direction: column;
-    align-items: flex-start;
-    gap: 15px;
-  }
-  
-  .header-left, .header-right {
-    width: 100%;
-  }
-  
-  .quick-nav {
-    overflow-x: auto;
-    padding-bottom: 10px;
-  }
-  
-  .chart-container-wrapper {
-    flex-direction: column;
-  }
+.trend-card {
+  background: white;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 }

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

@@ -1,37 +1,61 @@
-
 <!-- historical-data.component.html -->
 <div class="history-container">
   <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 class="filter-row">
     <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-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 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>
-        <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 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">
-        <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="checkbox-label">多设备对比</span>
         </label>
       </div>
     </div>
@@ -40,126 +64,236 @@
   <div class="chart-container">
     <div class="chart-card">
       <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 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 class="chart-hover-info">将鼠标悬停在图表上查看详细数据</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>
 
-<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">
-    <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">
-      <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>

+ 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
 })
 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();
    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;
   background-color: #f5f7fa;
   min-height: 100vh;
+  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 }
 
 .history-container {
   max-width: 1400px;
   margin: 0 auto;
-  padding: 25px;
   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 {
-  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;
   align-items: center;
   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 {
   display: flex;
   gap: 20px;
-  margin-bottom: 25px;
+  padding: 20px;
+  background: white;
+  border-bottom: 1px solid #eee;
 }
 
-.filter-card,
-.device-selector {
+.filter-card {
   flex: 1;
   background: white;
   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 {
   display: grid;
   grid-template-columns: 1fr 1fr auto;
-  gap: 15px;
+  gap: 12px;
   align-items: flex-end;
 }
 
 .date-input label {
   display: block;
-  margin-bottom: 8px;
-  font-size: 14px;
-  color: #4a5568;
+  margin-bottom: 6px;
+  font-size: 13px;
+  color: #666;
   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%;
   padding: 10px 12px;
   border-radius: 6px;
-  border: 1px solid #e2e8f0;
+  border: 1px solid #ddd;
   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;
   border-color: #3498db;
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
@@ -84,21 +179,37 @@
 
 .device-controls {
   display: flex;
-  gap: 15px;
+  gap: 16px;
   align-items: center;
 }
 
-.device-controls select {
+.select-wrapper {
+  position: relative;
   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: 1px solid #e2e8f0;
+  border: 1px solid #ddd;
   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;
   border-color: #3498db;
   box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
@@ -110,7 +221,7 @@
   cursor: pointer;
   font-size: 14px;
   user-select: none;
-  color: #4a5568;
+  gap: 8px;
 }
 
 .checkbox-container input {
@@ -120,406 +231,541 @@
 }
 
 .checkmark {
-  height: 20px;
-  width: 20px;
-  background-color: #edf2f7;
+  width: 18px;
+  height: 18px;
+  background-color: white;
+  border: 1px solid #ddd;
   border-radius: 4px;
-  margin-left: 10px;
   display: flex;
   align-items: center;
   justify-content: center;
-  transition: background-color 0.2s;
+  transition: all 0.2s;
 }
 
 .checkbox-container:hover .checkmark {
-  background-color: #e2e8f0;
+  border-color: #3498db;
 }
 
 .checkbox-container input:checked ~ .checkmark {
   background-color: #3498db;
+  border-color: #3498db;
 }
 
 .checkmark:after {
   content: "";
   display: none;
-  width: 5px;
-  height: 10px;
+  width: 4px;
+  height: 8px;
   border: solid white;
   border-width: 0 2px 2px 0;
   transform: rotate(45deg);
+  margin-top: -2px;
 }
 
 .checkbox-container input:checked ~ .checkmark:after {
   display: block;
 }
 
-.data-table-card {
-  margin-top: 30px;
+.checkbox-label {
+  color: #555;
+}
+
+.chart-container {
+  padding: 0 20px;
+}
+
+.chart-card {
   background: white;
   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;
-  font-size: 18px;
-  color: #2c3e50;
-  background-color: #f8fafc;
-  border-bottom: 1px solid #eaeef2;
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
   display: flex;
   align-items: center;
   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;
   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;
 }
 
-.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;
-  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%;
-  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;
   justify-content: space-between;
   align-items: center;
-  margin-bottom: 20px;
+  margin-bottom: 16px;
 }
 
-.chart-header h3 {
+.table-header h3 {
   margin: 0;
   font-size: 16px;
-  color: #2c3e50;
   font-weight: 600;
+  color: #333;
   display: flex;
   align-items: center;
   gap: 10px;
 }
 
-.chart-header h3 i {
+.table-header i {
   color: #3498db;
 }
 
-.chart-legend {
+.table-actions {
   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;
-  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;
-  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;
-  border: 1px solid #eaeef2;
   overflow: hidden;
 }
 
-.trend-chart {
-  width: 100%;
+.progress-fill {
   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;
-  top: 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;
-  flex-direction: column;
   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;
-  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;
-  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) {
-  .chart-header {
+  .filter-row {
     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();
   });
 });
-

+ 27 - 31
industry-monitor-web/src/app/pages/system-settings/system-settings.component.html

@@ -14,40 +14,36 @@
             </button>
         </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-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">

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

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

+ 384 - 141
industry-monitor-web/src/app/pages/system-settings/system-settings.css

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

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

@@ -1,36 +0,0 @@
-// 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();
-    }
-  }
-}

+ 0 - 6
package-lock.json

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