前端:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>智能安防监控系统 | SecureVision Pro</title> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style> :root { --primary-color: #2A5CAA; --secondary-color: #3AB0FF; --success-color: #30C172; --danger-color: #FF4D4D; --dark-color: #1A2330; --light-color: #F5F7FA; --transition-speed: 0.3s; } body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; background: var(--dark-color); color: var(--light-color); margin: 0; padding: 20px; line-height: 1.6; } .dashboard-container { max-width: 1800px; margin: 0 auto; } .system-header { background: linear-gradient(135deg, var(--primary-color), #1E3A5F); padding: 0.5rem; border-radius: 16px; margin-bottom: 0.5rem; box-shadow: 0 8px 24px rgba(0,0,0,0.2); position: relative; overflow: hidden; } .system-header::before { content: ""; position: absolute; top: -50%; right: -30%; width: 600px; height: 600px; background: radial-gradient(rgba(255,255,255,0.1) 10%, transparent 60%); } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; } .stat-card { background: rgba(255,255,255,0.05); padding: 0.5rem; border-radius: 12px; backdrop-filter: blur(10px); transition: transform var(--transition-speed) ease; border: 1px solid rgba(255,255,255,0.1); } .stat-card:hover { transform: translateY(-5px); background: rgba(255,255,255,0.08); } .camera-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(480px, 1fr)); gap: 2rem; margin-bottom: 3rem; } .camera-card { background: rgba(255,255,255,0.05); border-radius: 16px; overflow: hidden; transition: all var(--transition-speed) cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 6px 20px rgba(0,0,0,0.2); position: relative; border: 1px solid rgba(255,255,255,0.1); } .camera-card:hover { transform: translateY(-5px); box-shadow: 0 12px 30px rgba(0,0,0,0.3); } .camera-header { padding: 1.2rem; background: rgba(0,0,0,0.3); display: flex; justify-content: space-between; align-items: center; } .camera-title { font-weight: 600; font-size: 1.1em; display: flex; align-items: center; gap: 10px; } .status-indicator { width: 12px; height: 12px; border-radius: 50%; margin-right: 8px; position: relative; } .online { background: var(--success-color); box-shadow: 0 0 12px rgba(46, 204, 113, 0.3); animation: pulse 1.5s infinite; } .offline { background: var(--danger-color); opacity: 0.7; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.3); } 70% { box-shadow: 0 0 0 10px rgba(46, 204, 113, 0); } 100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); } } .video-container { position: relative; padding-bottom: 56.25%; background: #000; } .video-feed { width: 100%; height: 100%; object-fit: cover; position: absolute; top: 0; left: 0; transition: opacity 0.5s ease; } .object-list { padding: 1rem; background: rgba(0,0,0,0.3); margin: 0; font-size: 1.2em; color: var(--secondary-color); min-height: 60px; display: flex; align-items: center; flex-wrap: wrap; gap: 8px; } .object-tag { background: rgba(58, 176, 255, 0.15); padding: 4px 12px; border-radius: 20px; border: 1px solid var(--secondary-color); font-size: 0.85em; } .performance-badge { position: absolute; bottom: 15px; left: 15px; background: rgba(0,0,0,0.7); padding: 6px 12px; border-radius: 20px; font-size: 0.8em; display: flex; align-items: center; gap: 8px; } .system-title { font-size: 2.5rem; font-weight: 700; margin: 0; letter-spacing: -0.5px; display: flex; align-items: center; gap: 15px; } .metric-value { font-size: 1.8rem; font-weight: 600; margin: 8px 0; color: var(--secondary-color); } .metric-label { color: rgba(255,255,255,0.7); font-size: 0.9em; display: flex; align-items: center; gap: 8px; } .alert-badge { position: absolute; top: 15px; right: 15px; background: var(--danger-color); color: white; padding: 6px 12px; border-radius: 20px; font-size: 0.85em; animation: alert-pulse 1s infinite; } @keyframes alert-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.8); display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 15px; } .loading-spinner { width: 40px; height: 40px; border: 3px solid rgba(255,255,255,0.2); border-top-color: var(--secondary-color); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .camera-card.phone-alert { animation: phone-alert 1s infinite; position: relative; overflow: hidden; } @keyframes phone-alert { 0% { border-color: rgba(255,77,77,0); } 50% { border-color: var(--danger-color); } 100% { border-color: rgba(255,77,77,0); } } .phone-alert::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 3px solid var(--danger-color); border-radius: 16px; animation: phone-glow 1.5s infinite; z-index: 1; } @keyframes phone-glow { 0% { opacity: 0; box-shadow: 0 0 10px rgba(255,77,77,0); } 50% { opacity: 1; box-shadow: 0 0 20px rgba(255,77,77,0.5); } 100% { opacity: 0; box-shadow: 0 0 10px rgba(255,77,77,0); } } .phone-alert .video-container::after { content: "手机检测告警"; position: absolute; top: 10px; right: 10px; background: rgba(255,77,77,0.9); color: white; padding: 6px 12px; border-radius: 20px; font-size: 0.8em; z-index: 2; } .alert-summary { cursor: pointer; transition: all 0.3s ease; } .alert-summary:hover { background: rgba(255, 77, 77, 0.1); } .alert-count { font-size: 1.8rem; font-weight: 600; margin: 8px 0; } .no-alert { color: var(--success-color);