摘要

本文详细介绍了一套功能完整、技术先进的“基于深度学习的安全帽佩戴识别检测系统”。该系统旨在解决工业生产、建筑工地、电力巡检等高风险场景下的人员安全监管难题。系统核心采用当下最前沿的YOLO系列目标检测模型(集成YOLOv8、YOLOv10、YOLOv11及YOLOv12),实现了对“安全帽”(helmet)和“头部”(head,即未佩戴安全帽)两类目标的高精度、实时检测。项目不仅构建了强大的算法后端,还创新性地开发了现代化的Web应用界面,采用前后端分离架构,确保了系统的可维护性与可扩展性。系统功能全面,支持图像、视频、实时摄像头流三种检测模式,并集成了DeepSeek大语言模型的智能分析功能,可对检测结果生成描述性报告。所有检测记录与用户数据均持久化存储于MySQL数据库,并配以丰富的数据可视化图表。系统管理模块完善,包含用户登录注册、个人中心、管理员对用户及识别记录的全面管理。本系统将尖端计算机视觉技术与实用的软件工程实践相结合,为安全生产的智能化、常态化监管提供了一个高效、可靠的一体化解决方案。

关键词: 安全帽检测;YOLO;深度学习;计算机视觉;Web应用;前后端分离;DeepSeek;MySQL;数据可视化

目录

 摘要

项目源码+数据集下载链接

1. 引言

2. 背景与相关工作

2.1 安全帽检测的技术背景

2.2 YOLO系列模型演进

2.3 系统集成与智能化趋势

3. 数据集介绍

4. 系统核心功能模块详解

4.1 用户体系与安全管理

4.2 多模型检测引擎

4.3 DeepSeek智能分析功能

4.4 数据记录与可视化

4.5 系统架构

功能模块

登录注册模块

可视化模块

图像检测模块

视频检测模块

实时检测模块

图片识别记录管理

视频识别记录管理

摄像头识别记录管理

用户管理模块

数据管理模块(MySQL表设计)

模型训练结果

YOLOv8

YOLOv10

YOLOv11

YOLOv12

前端代码展示

后端代码展示

项目源码+数据集下载链接

 项目安装教程


项目源码+数据集下载链接

完整代码在哔哩哔哩视频下方简介内获取

基于深度学习的安全帽佩戴识别检测系统(最新web界面+YOLOv8/YOLOv10/YOLOv11/YOLOv12+DeepSeek智能分析 +前后端分离)_哔哩哔哩_bilibili

基于深度学习的安全帽佩戴识别检测系统(最新web界面+YOLOv8/YOLOv10/YOLOv11/YOLOv12+DeepSeek智能分析 +前后端分离)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1StmyBZEsC/?vd_source=549d0b4e2b8999929a61a037fcce3b0fhttps://www.bilibili.com/video/BV1StmyBZEsC


1. 引言

安全生产是工业制造、建筑施工、矿产开采等领域的生命线。安全帽作为保护劳动者头部免受坠落物和碰撞伤害的关键个人防护装备,其规范佩戴是安全管理中最基本、最普遍的要求。然而,传统的人工巡检方式存在监管范围有限、效率低下、无法全天候覆盖、主观性强等问题,难以实现即时预警和精准管理。

近年来,深度学习技术的爆发式发展,特别是以YOLO(You Only Look Once)系列为代表的目标检测算法,在速度与精度上取得了革命性突破,为实时视觉监控提供了坚实的技术基础。同时,Web技术的成熟使得构建直观、交互友好的管理平台成为可能,而大语言模型(LLM)的兴起则为计算机视觉系统的输出赋予了更强的可解释性和智能分析能力。

为此,我们设计并实现了本套“基于深度学习的安全帽佩戴识别检测系统”。本系统旨在利用最先进的YOLO模型实现精准检测通过现代化的Web界面提供便捷交互借助DeepSeek大模型增强结果理解,并采用成熟的软件架构确保系统稳定与可扩展。该系统不仅是一个算法演示,更是一个集成了用户管理、数据持久化、可视化分析和多模态检测的完整生产级应用,能够切实助力企业将安全规章制度转化为可量化、可追溯、可预警的数字化管控能力。


2. 背景与相关工作

2.1 安全帽检测的技术背景

安全帽检测属于特定场景下的目标检测问题。早期方法多依赖于传统计算机视觉技术,如Haar特征、HOG特征结合SVM或模板匹配等。这些方法在固定场景、光照良好时有一定效果,但泛化能力差,对复杂环境、遮挡、多角度佩戴等情况鲁棒性不足。

随着深度卷积神经网络(CNN)的普及,基于两阶段(如Faster R-CNN)和单阶段(如SSD, YOLO)的检测框架逐渐成为主流。其中,YOLO系列因其在速度与精度间的卓越平衡,特别适合实时视频流分析场景。从YOLOv1到最新的YOLOv12,模型在骨干网络、特征融合机制、损失函数和训练策略上不断优化,检测性能持续提升。

2.2 YOLO系列模型演进
  • YOLOv8: 由Ultralytics发布,在易用性、速度和精度上达到新的高度,提供了完整的分类、检测、分割任务支持,是本系统的重要基准模型。

  • YOLOv10: 由清华大学研究团队提出,专注于消除非极大值抑制(NMS)后的冗余预测,在保持高精度的同时进一步提升推理效率。

  • YOLOv11 & YOLOv12: 代表了社区对YOLO架构的持续探索与优化(注:截至当前,v11和v12多为研究社区或特定团队的版本迭代,它们在网络设计、注意力机制或训练技巧上进行了创新,旨在追求极致的性能指标)。本系统前瞻性地集成这些最新变体,为用户提供了性能对比和选择的灵活性。

2.3 系统集成与智能化趋势

当前,单纯提供API接口的检测模型已无法满足实际部署需求。将模型封装为具有用户管理、数据记录、可视化看板的Web系统是必然趋势。前后端分离架构(如Vue.js/React前端 + Flask/Django/FastAPI后端)已成为开发标准范式。此外,融合AI大模型(如本系统采用的DeepSeek)为视觉系统增添自然语言理解和报告生成能力,是提升系统智能水平和用户体验的新方向。


3. 数据集介绍

一个高质量、标注精准的数据集是模型性能的基石。本系统所使用的安全帽检测数据集经过精心收集与标注,详情如下:

  • 类别定义(nc=2):

    • helmet:正确佩戴安全帽的头部。

    • head:未佩戴安全帽的裸露头部。

    • 注:这种两类定义直接聚焦于“是否佩戴”这一核心安全规则,逻辑清晰,便于模型学习与后续统计。

  • 数据规模与划分:

    • 训练集(Training Set):3500张图像。用于模型学习特征,是参数更新的主要数据来源。涵盖了多种场景(室内、室外、高空、地面)、光照条件(白天、夜晚、阴影)、人员密度(单人、多人、密集人群)以及不同颜色、样式的安全帽。

    • 验证集(Validation Set):750张图像。在训练过程中用于调整超参数、监控模型是否过拟合,并进行初步的模型选择。其分布与训练集相似但独立。

    • 测试集(Test Set):750张图像。用于最终评估模型泛化性能的独立数据集,模拟真实场景下的表现。评估指标包括均值平均精度(mAP@0.5, mAP@0.5:0.95)、召回率(Recall)、精确率(Precision)等。

  • 数据标注与格式:

    • 所有图像均使用专业标注工具(如LabelImg、CVAT)进行边界框(Bounding Box)标注,标注格式为标准化的YOLO格式(<class_id> <x_center> <y_center> <width> <height>,坐标已归一化)。

    • 数据进行了基础增强处理(如随机翻转、色彩抖动、模糊等),以提升模型的鲁棒性。

  • 数据集特点:

    • 针对性强:专注于安全帽佩戴场景,无无关类别干扰。

    • 场景多样:确保了模型在不同工作环境下的适应性。

    • 规模适中:总计5000张标注图像,足以训练出性能优异的深度模型,同时数据准备成本可控。


4. 系统核心功能模块详解

4.1 用户体系与安全管理
  • 用户登录/注册:实现基于用户名/密码的认证。注册时集成密码强度检测(长度、复杂度),保障账户安全。所有用户凭证经加密后存入MySQL。

  • 个人中心:用户可自主更新个人信息,如姓名、头像(上传与裁剪)、密码修改(需验证旧密码)等。

  • 用户管理模块(管理员权限):系统管理员拥有高级后台,可对注册用户进行增、删、改、查操作,并分配或调整用户角色与权限。

4.2 多模型检测引擎
  • 模型切换:系统后台集成YOLOv8, YOLOv10, YOLOv11, YOLOv12四个版本的预训练或自定义训练模型。用户可通过前端界面一键切换,灵活比较不同模型在相同输入下的检测速度与效果。

  • 多模态检测支持

    • 图像检测:上传图片,系统返回带检测框(区分helmet/head,用不同颜色标注)的结果图,并列出统计信息。

    • 视频检测:上传视频文件,系统进行逐帧分析,输出带有检测框和实时统计信息的视频结果,并可下载。

    • 摄像头实时检测:调用用户本地或连接的网络摄像头,进行实时流分析。

4.3 DeepSeek智能分析功能
  • 在图片检测完成后,用户可选择“AI分析”功能。系统将检测结果(类别、位置、数量)结构化后,发送给DeepSeek大语言模型API。

  • DeepSeek将生成一段自然语言描述的报告,例如:“在这张施工现场图片中,系统检测到8名工人,其中7人规范佩戴了黄色或白色的安全帽(helmet),但画面右侧有1人未佩戴安全帽(head),存在安全风险。建议立即提醒该人员。” 这极大地提升了结果的直观性和可读性。

4.4 数据记录与可视化
  • 记录管理:所有检测行为(图片、视频、摄像头)的记录均自动保存至MySQL数据库,包含时间戳、使用的模型、文件路径、检测结果摘要(如helmethead的数量)。

  • 可视化看板:通过图表(如折线图、柱状图、饼图)展示历史数据。

4.5 系统架构
  • 前端:采用Vue.js框架构建响应式Web界面,提供流畅的用户交互体验。

  • 后端:使用spring boot构建RESTful API,处理业务逻辑、模型推理和数据库操作。

  • 通信:前后端通过HTTP协议进行数据交换(如实时视频流)。

  • 数据库:使用MySQL关系型数据库,存储用户信息、检测记录、系统日志等结构化数据。

  • AI服务:YOLO模型部署在后端,DeepSeek通过调用其官方API集成。

功能模块


✅ 用户登录注册:支持密码检测,保存到MySQL数据库。

✅ 支持四种YOLO模型切换,YOLOv8、YOLOv10、YOLOv11、YOLOv12。

✅ 信息可视化,数据可视化。

✅ 图片检测支持AI分析功能,deepseek

✅ 支持图像检测、视频检测和摄像头实时检测,检测结果保存到MySQL数据库。

✅ 图片识别记录管理、视频识别记录管理和摄像头识别记录管理。

✅ 用户管理模块,管理员可以对用户进行增删改查。

✅ 个人中心,可以修改自己的信息,密码姓名头像等等。
 

登录注册模块

可视化模块

图像检测模块

  • YOLO模型集成 (v8/v10/v11/v12)

  • DeepSeek多模态分析

  • 支持格式:JPG/PNG/MP4/RTSP

视频检测模块

实时检测模块

图片识别记录管理

视频识别记录管理

摄像头识别记录管理

用户管理模块

数据管理模块(MySQL表设计)

  • users - 用户信息表

  • imgrecords- 图片检测记录表

  • videorecords- 视频检测记录表

  • camerarecords- 摄像头检测记录表

模型训练结果

#coding:utf-8
#根据实际情况更换模型
# yolon.yaml (nano):轻量化模型,适合嵌入式设备,速度快但精度略低。
# yolos.yaml (small):小模型,适合实时任务。
# yolom.yaml (medium):中等大小模型,兼顾速度和精度。
# yolob.yaml (base):基本版模型,适合大部分应用场景。
# yolol.yaml (large):大型模型,适合对精度要求高的任务。
 
from ultralytics import YOLO
 
model_path = 'pt/yolo12s.pt'
data_path = 'data.yaml'
 
if __name__ == '__main__':
    model = YOLO(model_path)
    results = model.train(data=data_path,
                          epochs=500,
                          batch=64,
                          device='0',
                          workers=0,
                          project='runs',
                          name='exp',
                          )
 
 
 
 
 
 
 
 

YOLOv8

YOLOv10

YOLOv11

YOLOv12

前端代码展示

部分代码

<template>
	<div class="login-container">
		<!-- AI检测动态背景 -->
		<div class="ai-background">
			<!-- 神经网络可视化层 -->
			<div class="neural-network-layer">
				<div class="neuron-grid">
					<div class="neuron-node" v-for="n in 120" :key="`neuron-${n}`" :style="getNeuronStyle(n)"></div>
				</div>
				<div class="neuron-connections">
					<svg class="connections-svg" width="100%" height="100%">
						<path v-for="n in 80" :key="`connection-${n}`" :style="getConnectionStyle(n)" />
					</svg>
				</div>
			</div>
			
			<!-- AI检测波形 -->
			<div class="ai-waveform">
				<div class="wave-line" v-for="n in 6" :key="`wave-${n}`" :style="getWaveStyle(n)"></div>
			</div>
			
			<!-- 数据流场 -->
			<div class="data-flow-field">
				<div class="data-particle" v-for="n in 40" :key="`particle-${n}`" :style="getParticleStyle(n)"></div>
				<div class="flow-lines">
					<div class="flow-line" v-for="n in 15" :key="`flow-${n}`" :style="getFlowLineStyle(n)"></div>
				</div>
			</div>
			
			<!-- YOLO检测可视化 -->
			<div class="yolo-visualization">
				<div class="detection-radar">
					<div class="radar-sweep"></div>
					<div class="radar-points">
						<div class="radar-point" v-for="n in 24" :key="`radar-${n}`" :style="getRadarPointStyle(n)"></div>
					</div>
				</div>
			</div>
			
			<!-- 科技光晕 -->
			<div class="tech-glows">
				<div class="glow-orb glow-1"></div>
				<div class="glow-orb glow-2"></div>
				<div class="glow-orb glow-3"></div>
			</div>
		</div>

		<!-- 登录主容器 -->
		<div class="login-main">
			<!-- 全息玻璃面板 -->
			<div class="hologlass-panel">
				<!-- 面板发光边缘 -->
				<div class="panel-glow-edge"></div>
				<div class="panel-glow-corner corner-1"></div>
				<div class="panel-glow-corner corner-2"></div>
				<div class="panel-glow-corner corner-3"></div>
				<div class="panel-glow-corner corner-4"></div>
				
				<!-- 全息扫描线 -->
				<div class="hologram-scanline"></div>
				
				<!-- 系统标志 -->
				<div class="system-brand">
					<div class="brand-icon">
						<div class="yolo-icon">
							<div class="yolo-core">
								<span class="yolo-text">YOLO</span>
								<span class="version">DeepSeek</span>
							</div>
							<div class="ai-ring">
								<div class="ring-segment"></div>
								<div class="ring-segment"></div>
								<div class="ring-segment"></div>
							</div>
							<div class="helmet-shape">
								<div class="helmet-curve"></div>
								<div class="helmet-visor"></div>
							</div>
						</div>
						<div class="icon-halo"></div>
					</div>
					<div class="brand-text">
						<h1 class="system-title">
							<span class="main-title">智能安全帽检测系统</span>
						</h1>
						<p class="system-subtitle">YOLOv8/v10/v11/v12</p>
						<p class="system-tagline">DeepSeek智能分析</p>
					</div>
				</div>

				<!-- 登录面板 -->
				<div class="login-panel">
					<div class="panel-header">
						<div class="header-glow"></div>
						<h2>系统安全认证</h2>
						<p class="header-sub">Secure Access Verification</p>
					</div>
					
					<div class="panel-content">
						<el-form :model="ruleForm" :rules="registerRules" ref="ruleFormRef">
							<!-- 用户名输入 -->
							<el-form-item prop="username">
								<div class="input-field">
									<div class="field-glow-effect"></div>
									<div class="field-icon">
										<svg class="icon-svg" viewBox="0 0 24 24">
											<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
										</svg>
									</div>
									<el-input 
										v-model="ruleForm.username" 
										placeholder="请输入用户名/工号" 
										class="tech-input"
										size="large"
										@focus="onInputFocus"
										@blur="onInputBlur"
									/>
									<div class="input-glow"></div>
								</div>
								<div class="input-hint">请输入您的用户名或工号</div>
							</el-form-item>

							<!-- 密码输入 -->
							<el-form-item prop="password">
								<div class="input-field">
									<div class="field-glow-effect"></div>
									<div class="field-icon">
										<svg class="icon-svg" viewBox="0 0 24 24">
											<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
										</svg>
									</div>
									<el-input 
										v-model="ruleForm.password" 
										type="password" 
										placeholder="请输入安全密码" 
										show-password
										class="tech-input"
										size="large"
										@focus="onInputFocus"
										@blur="onInputBlur"
									/>
									<div class="input-glow"></div>
								</div>
								<div class="input-hint">请输入5-30位安全密码</div>
							</el-form-item>

							<!-- 登录按钮 -->
							<el-form-item>
								<div class="login-action">
									<el-button 
										type="primary" 
										class="tech-btn"
										@click="submitForm(ruleFormRef)"
										@mouseenter="onBtnHover"
										@mouseleave="onBtnLeave"
									>
										<div class="btn-content">
											<div class="btn-glow"></div>
											<div class="btn-icon">
												<svg class="btn-svg" viewBox="0 0 24 24">
													<path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"/>
												</svg>
											</div>
											<div class="btn-text">
												<span class="text-main">进入监控系统</span>
												<span class="text-sub">AI DETECTION CENTER</span>
											</div>
											<div class="btn-trail"></div>
										</div>
										<div class="btn-energy-waves">
											<div class="energy-wave"></div>
											<div class="energy-wave"></div>
											<div class="energy-wave"></div>
										</div>
										<div class="btn-particles">
											<div class="particle" v-for="n in 6" :key="`btn-particle-${n}`"></div>
										</div>
									</el-button>
									
									<div class="system-status">
										<div class="status-indicator">
											<div class="status-pulse"></div>
											<span>AI检测系统 · 实时在线</span>
										</div>
										<div class="status-info">
											<span>识别准确率 94.7% · 平均响应时间 23ms</span>
										</div>
									</div>
								</div>
							</el-form-item>
						</el-form>

						<!-- 辅助选项 -->
						<div class="panel-options">
							<router-link to="/register" class="option-link">
								<div class="link-glow"></div>
								<div class="link-icon">
									<svg class="link-svg" viewBox="0 0 24 24">
										<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
									</svg>
								</div>
								<span>新用户注册</span>
								<div class="link-arrow"></div>
							</router-link>
							

						</div>
					</div>
				</div>

				<!-- 系统状态信息 -->
				<div class="system-stats">
					<div class="stats-grid">
						<div class="stat-item">
							<div class="stat-icon">
								<div class="stat-glow"></div>
								<svg class="stat-svg" viewBox="0 0 24 24">
									<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
								</svg>
							</div>
							<div class="stat-content">
								<span class="stat-value">94.7%</span>
								<span class="stat-label">识别准确率</span>
							</div>
						</div>
						<div class="stat-item">
							<div class="stat-icon">
								<div class="stat-glow"></div>
								<svg class="stat-svg" viewBox="0 0 24 24">
									<path d="M13 2.05v3.03c3.39.49 6 3.39 6 6.92 0 .9-.18 1.75-.5 2.54l2.62 1.53c.56-1.24.88-2.62.88-4.07 0-5.18-3.95-9.45-9-9.95zM12 19c-3.87 0-7-3.13-7-7 0-3.53 2.61-6.43 6-6.92V2.05c-5.06.5-9 4.76-9 9.95 0 5.52 4.47 10 9.99 10 3.31 0 6.24-1.61 8.06-4.09l-2.6-1.53C16.17 17.98 14.21 19 12 19z"/>
								</svg>
							</div>
							<div class="stat-content">
								<span class="stat-value">45 FPS</span>
								<span class="stat-label">实时帧率</span>
							</div>
						</div>
						<div class="stat-item">
							<div class="stat-icon">
								<div class="stat-glow"></div>
								<svg class="stat-svg" viewBox="0 0 24 24">
									<path d="M18 10.48V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4.48l4 3.98v-11l-4 3.98zM16 18H4V6h12v12z"/>
								</svg>
							</div>
							<div class="stat-content">

							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- 浮动科技元素 -->
		<div class="floating-tech">
			<div class="hexagon-grid">
				<div class="hexagon" v-for="n in 18" :key="`hex-${n}`" :style="getHexagonStyle(n)"></div>
			</div>
			<div class="binary-rain">
				<div class="binary-column" v-for="n in 12" :key="`binary-${n}`" :style="getBinaryStyle(n)">
					<div class="binary-digit" v-for="d in 15" :key="`digit-${n}-${d}`">01</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script lang="ts" setup>
import { reactive, ref, computed, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { useI18n } from 'vue-i18n';
import Cookies from 'js-cookie';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
import { initBackEndControlRoutes } from '/@/router/backEnd';
import { Session } from '/@/utils/storage';
import { formatAxis } from '/@/utils/formatTime';
import { NextLoading } from '/@/utils/loading';
import type { FormInstance, FormRules } from 'element-plus';
import request from '/@/utils/request';

// 定义变量内容
const { t } = useI18n();
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
const route = useRoute();
const router = useRouter();
const formSize = ref('default');
const ruleFormRef = ref<FormInstance>();

// 定义表单数据
const ruleForm = reactive({
	username: '',
	password: '',
});

// 校验规则
const registerRules = reactive<FormRules>({
	username: [
		{ required: true, message: '请输入用户名或工号', trigger: 'blur' },
		{ min: 3, max: 20, message: '长度在3-20个字符', trigger: 'blur' },
	],
	password: [
		{ required: true, message: '请输入安全密码', trigger: 'blur' },
		{ min: 5, max: 30, message: '长度在5-30个字符', trigger: 'blur' },
	],
});

// 神经元样式
const getNeuronStyle = (index: number) => {
	const left = Math.random() * 100;
	const top = Math.random() * 100;
	const size = 3 + Math.random() * 6;
	const hue = 210 + Math.random() * 90; // 蓝色到紫色范围
	const opacity = 0.3 + Math.random() * 0.7;
	
	return {
		left: `${left}%`,
		top: `${top}%`,
		width: `${size}px`,
		height: `${size}px`,
		backgroundColor: `hsla(${hue}, 80%, 60%, ${opacity})`,
		boxShadow: `0 0 ${size * 2}px hsla(${hue}, 100%, 60%, ${opacity * 0.5})`,
		animationDelay: `${Math.random() * 2}s`
	};
};

// 连接线样式
const getConnectionStyle = (index: number) => {
	return {
		stroke: `hsla(${210 + Math.random() * 60}, 80%, 60%, ${0.1 + Math.random() * 0.3})`,
		strokeWidth: `${0.5 + Math.random() * 1.5}px`,
		filter: 'blur(1px)'
	};
};

// 波形样式
const getWaveStyle = (index: number) => {
	const height = 30 + index * 15;
	const speed = 3 + index * 0.5;
	const opacity = 0.05 + index * 0.03;
	
	return {
		height: `${height}px`,
		animationDuration: `${speed}s`,
		opacity: opacity.toString(),
		animationDelay: `${index * 0.3}s`
	};
};

// 粒子样式
const getParticleStyle = (index: number) => {
	const left = Math.random() * 100;
	const top = Math.random() * 100;
	const size = 1 + Math.random() * 4;
	const hue = 180 + Math.random() * 120;
	const duration = 8 + Math.random() * 12;
	const delay = Math.random() * 5;
	
	return {
		left: `${left}%`,
		top: `${top}%`,
		width: `${size}px`,
		height: `${size}px`,
		backgroundColor: `hsla(${hue}, 100%, 60%, 0.8)`,
		animationDuration: `${duration}s`,
		animationDelay: `${delay}s`
	};
};

// 数据流线样式
const getFlowLineStyle = (index: number) => {
	const left = Math.random() * 100;
	const width = 30 + Math.random() * 200;
	const height = 1 + Math.random() * 3;
	const duration = 6 + Math.random() * 10;
	const delay = Math.random() * 4;
	const hue = 200 + Math.random() * 40;
	
	return {
		left: `${left}%`,
		width: `${width}px`,
		height: `${height}px`,
		background: `linear-gradient(90deg, transparent, hsla(${hue}, 100%, 60%, 0.6), transparent)`,
		animationDuration: `${duration}s`,
		animationDelay: `${delay}s`
	};
};

// 雷达点样式
const getRadarPointStyle = (index: number) => {
	const angle = (index / 24) * Math.PI * 2;
	const radius = 30 + Math.random() * 40;
	const left = 50 + Math.cos(angle) * radius;
	const top = 50 + Math.sin(angle) * radius;
	const size = 2 + Math.random() * 4;
	
	return {
		left: `${left}%`,
		top: `${top}%`,
		width: `${size}px`,
		height: `${size}px`,
		animationDelay: `${index * 0.1}s`
	};
};

// 六边形网格样式
const getHexagonStyle = (index: number) => {
	const left = Math.random() * 100;
	const top = Math.random() * 100;
	const size = 15 + Math.random() * 40;
	const opacity = 0.02 + Math.random() * 0.08;
	const rotation = Math.random() * 360;
	
	return {
		left: `${left}%`,
		top: `${top}%`,
		width: `${size}px`,
		height: `${size}px`,
		opacity: opacity.toString(),
		transform: `rotate(${rotation}deg)`,
		animationDelay: `${Math.random() * 5}s`
	};
};

// 二进制雨样式
const getBinaryStyle = (index: number) => {
	const left = (index / 12) * 100;
	const delay = Math.random() * 2;
	const duration = 10 + Math.random() * 15;
	
	return {
		left: `${left}%`,
		animationDelay: `${delay}s`,
		animationDuration: `${duration}s`
	};
};

// 事件处理
const onInputFocus = (event: Event) => {
	const target = event.target as HTMLElement;
	target.parentElement?.parentElement?.classList.add('focused');
};

const onInputBlur = (event: Event) => {
	const target = event.target as HTMLElement;
	target.parentElement?.parentElement?.classList.remove('focused');
};

const onBtnHover = (event: Event) => {
	const btn = event.currentTarget as HTMLElement;
	btn.classList.add('hover');
};

const onBtnLeave = (event: Event) => {
	const btn = event.currentTarget as HTMLElement;
	btn.classList.remove('hover');
};

// 原有的登录逻辑保持不变
const currentTime = computed(() => {
	return formatAxis(new Date());
});

const onSignIn = async () => {
	Session.set('token', Math.random().toString(36).substr(0));
	Cookies.set('userName', ruleForm.username);
	
	if (!themeConfig.value.isRequestRoutes) {
		const isNoPower = await initFrontEndControlRoutes();
		signInSuccess(isNoPower);
	} else {
		const isNoPower = await initBackEndControlRoutes();
		signInSuccess(isNoPower);
	}
};

const signInSuccess = (isNoPower: boolean | undefined) => {
	if (isNoPower) {
		ElMessage.warning('抱歉,您没有登录权限');
		Session.clear();
	} else {
		let currentTimeInfo = currentTime.value;
		if (route.query?.redirect) {
			router.push({
				path: <string>route.query?.redirect,
				query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
			});
		} else {
			router.push('/');
		}
		const signInText = t('message.signInText');
		ElMessage.success(`${currentTimeInfo},${signInText}`);
		NextLoading.start();
	}
};

const submitForm = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate((valid) => {
		if (valid) {
			request.post('/api/user/login', ruleForm).then((res) => {
				console.log(res);
				if (res.code == 0) {
					Cookies.set('role', res.data.role);
					onSignIn();
				} else {
					ElMessage({
						type: 'error',
						message: res.msg,
					});
				}
			});
		} else {
			console.log('error submit!');
			return false;
		}
	});
};

// 初始化
onMounted(() => {
	// 可以添加一些初始化逻辑
});
</script>

<style scoped>
.login-container {
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(135deg, 
		#0a0e17 0%, 
		#13182e 25%, 
		#1a2342 50%, 
		#0f1526 75%, 
		#0a0e17 100%);
	padding: 20px;
	position: relative;
	overflow: hidden;
	font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
	color: #ffffff;
}

/* AI背景 */
.ai-background {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 1;
	overflow: hidden;
	background: 
		radial-gradient(circle at 20% 80%, rgba(41, 128, 185, 0.15) 0%, transparent 50%),
		radial-gradient(circle at 80% 20%, rgba(155, 89, 182, 0.1) 0%, transparent 50%),
		radial-gradient(circle at 40% 40%, rgba(39, 174, 96, 0.08) 0%, transparent 50%);
}

/* 神经网络层 */
.neural-network-layer {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.neuron-grid {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.neuron-node {
	position: absolute;
	border-radius: 50%;
	background: #2ecc71;
	animation: neuronPulse 3s ease-in-out infinite alternate;
	filter: blur(1px);
	z-index: 1;
}

@keyframes neuronPulse {
	0% {
		transform: scale(1);
		box-shadow: 0 0 10px currentColor;
		opacity: 0.3;
	}
	100% {
		transform: scale(1.5);
		box-shadow: 0 0 25px currentColor;
		opacity: 0.8;
	}
}

.neuron-connections {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.connections-svg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.connections-svg path {
	fill: none;
	stroke-linecap: round;
	animation: connectionFlow 4s linear infinite;
}

@keyframes connectionFlow {
	0% {
		stroke-dasharray: 10, 20;
		stroke-dashoffset: 0;
	}
	100% {
		stroke-dashoffset: -1000;
	}
}

/* AI波形 */
.ai-waveform {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 200px;
	display: flex;
	align-items: flex-end;
	gap: 10px;
	padding: 0 20px;
}

.wave-line {
	flex: 1;
	background: linear-gradient(to top, 
		rgba(41, 128, 185, 0.8) 0%, 
		rgba(155, 89, 182, 0.6) 50%, 
		transparent 100%);
	border-radius: 4px 4px 0 0;
	animation: waveMotion ease-in-out infinite alternate;
	transform-origin: bottom;
}

@keyframes waveMotion {
	0% {
		transform: scaleY(0.3);
	}
	100% {
		transform: scaleY(1);
	}
}

/* 数据流场 */
.data-flow-field {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.data-particle {
	position: absolute;
	border-radius: 50%;
	background: #3498db;
	animation: particleFloat linear infinite;
	filter: blur(0.5px);
	z-index: 2;
}

@keyframes particleFloat {
	0% {
		transform: translateY(100vh) rotate(0deg);
		opacity: 0;
	}
	10% {
		opacity: 0.6;
	}
	90% {
		opacity: 0.6;
	}
	100% {
		transform: translateY(-100px) rotate(360deg);
		opacity: 0;
	}
}

.flow-lines {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.flow-line {
	position: absolute;
	background: linear-gradient(90deg, transparent, #9b59b6, transparent);
	animation: flowMove linear infinite;
	transform: translateX(-100%);
}

@keyframes flowMove {
	0% {
		transform: translateX(-100%);
		opacity: 0;
	}
	10% {
		opacity: 1;
	}
	90% {
		opacity: 1;
	}
	100% {
		transform: translateX(100vw);
		opacity: 0;
	}
}

/* YOLO检测可视化 */
.yolo-visualization {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 50%;
	height: 50%;
}

.detection-radar {
	position: relative;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	border: 1px solid rgba(52, 152, 219, 0.3);
	background: radial-gradient(circle, 
		transparent 30%, 
		rgba(52, 152, 219, 0.05) 70%);
	overflow: hidden;
}

.radar-sweep {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: conic-gradient(
		transparent 0deg,
		rgba(52, 152, 219, 0.2) 90deg,
		transparent 120deg,
		transparent 360deg
	);
	animation: radarSweep 3s linear infinite;
}

@keyframes radarSweep {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

.radar-points {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.radar-point {
	position: absolute;
	background: #2ecc71;
	border-radius: 50%;
	animation: radarPointPulse 2s ease-in-out infinite;
	box-shadow: 0 0 10px #2ecc71;
}

@keyframes radarPointPulse {
	0%, 100% {
		transform: scale(1);
		opacity: 0.7;
	}
	50% {
		transform: scale(1.5);
		opacity: 1;
	}
}

/* 科技光晕 */
.tech-glows {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.glow-orb {
	position: absolute;
	border-radius: 50%;
	filter: blur(60px);
	opacity: 0.3;
}

.glow-1 {
	top: 20%;
	left: 10%;
	width: 300px;
	height: 300px;
	background: radial-gradient(circle, #3498db, transparent 70%);
	animation: glowFloat 20s ease-in-out infinite;
}

.glow-2 {
	top: 60%;
	right: 15%;
	width: 250px;
	height: 250px;
	background: radial-gradient(circle, #9b59b6, transparent 70%);
	animation: glowFloat 25s ease-in-out infinite reverse;
}

.glow-3 {
	bottom: 10%;
	left: 40%;
	width: 200px;
	height: 200px;
	background: radial-gradient(circle, #2ecc71, transparent 70%);
	animation: glowFloat 30s ease-in-out infinite;
}

@keyframes glowFloat {
	0%, 100% {
		transform: translate(0, 0) scale(1);
	}
	25% {
		transform: translate(50px, -30px) scale(1.1);
	}
	50% {
		transform: translate(-30px, 40px) scale(0.9);
	}
	75% {
		transform: translate(40px, 20px) scale(1.05);
	}
}

/* 主登录容器 */
.login-main {
	position: relative;
	z-index: 3;
	width: 100%;
	max-width: 480px;
	margin: 0 auto;
}

/* 全息玻璃面板 */
.hologlass-panel {
	position: relative;
	background: rgba(15, 20, 35, 0.85);
	border-radius: 20px;
	padding: 40px;
	backdrop-filter: blur(15px);
	border: 1px solid rgba(52, 152, 219, 0.4);
	box-shadow: 
		0 25px 50px rgba(0, 0, 0, 0.6),
		0 0 100px rgba(52, 152, 219, 0.2),
		inset 0 0 40px rgba(255, 255, 255, 0.05);
	animation: panelAppear 1.2s ease-out;
	overflow: hidden;
}

@keyframes panelAppear {
	from {
		opacity: 0;
		transform: translateY(30px) scale(0.98);
		backdrop-filter: blur(0);
	}
	to {
		opacity: 1;
		transform: translateY(0) scale(1);
		backdrop-filter: blur(15px);
	}
}

.panel-glow-edge {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 20px;
	box-shadow: 
		inset 0 0 0 1px rgba(52, 152, 219, 0.2),
		inset 0 0 30px rgba(52, 152, 219, 0.1);
	pointer-events: none;
}

.panel-glow-corner {
	position: absolute;
	width: 40px;
	height: 40px;
	border: 2px solid rgba(52, 152, 219, 0.8);
	opacity: 0.8;
}

.corner-1 {
	top: -1px;
	left: -1px;
	border-right: none;
	border-bottom: none;
	border-top-left-radius: 20px;
}
.corner-2 {
	top: -1px;
	right: -1px;
	border-left: none;
	border-bottom: none;
	border-top-right-radius: 20px;
}
.corner-3 {
	bottom: -1px;
	left: -1px;
	border-right: none;
	border-top: none;
	border-bottom-left-radius: 20px;
}
.corner-4 {
	bottom: -1px;
	right: -1px;
	border-left: none;
	border-top: none;
	border-bottom-right-radius: 20px;
}

.hologram-scanline {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 2px;
	background: linear-gradient(90deg,
		transparent,
		rgba(52, 152, 219, 0.6),
		transparent
	);
	box-shadow: 0 0 10px rgba(52, 152, 219, 0.4);
	animation: scanlineSweep 4s linear infinite;
	z-index: 1;
}

@keyframes scanlineSweep {
	0% {
		top: 0;
		opacity: 0;
	}
	10% {
		opacity: 1;
	}
	90% {
		opacity: 1;
	}
	100% {
		top: 100%;
		opacity: 0;
	}
}

/* 系统品牌 */
.system-brand {
	text-align: center;
	margin-bottom: 40px;
	position: relative;
}

.brand-icon {
	display: flex;
	justify-content: center;
	margin-bottom: 24px;
	position: relative;
	height: 120px;
}

.yolo-icon {
	position: relative;
	width: 120px;
	height: 120px;
	z-index: 2;
}

.yolo-core {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 70px;
	height: 70px;
	background: linear-gradient(135deg, #3498db, #9b59b6);
	border-radius: 12px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	z-index: 3;
	animation: corePulse 3s ease-in-out infinite alternate;
	box-shadow: 
		0 0 30px rgba(52, 152, 219, 0.6),
		inset 0 0 20px rgba(255, 255, 255, 0.1);
}

.yolo-text {
	color: white;
	font-size: 14px;
	font-weight: 800;
	letter-spacing: 2px;
}

.version {
	color: rgba(255, 255, 255, 0.7);
	font-size: 10px;
	font-weight: 500;
	letter-spacing: 1px;
	margin-top: 2px;
}

@keyframes corePulse {
	0% {
		transform: translate(-50%, -50%) scale(1);
		box-shadow: 0 0 30px rgba(52, 152, 219, 0.6);
	}
	100% {
		transform: translate(-50%, -50%) scale(1.05);
		box-shadow: 0 0 50px rgba(52, 152, 219, 0.8);
	}
}

.ai-ring {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 2;
}

.ring-segment {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border: 2px solid transparent;
	border-radius: 50%;
	border-top-color: #2ecc71;
	animation: ringRotate 6s linear infinite;
}

.ring-segment:nth-child(2) {
	border-top-color: #3498db;
	animation-delay: -2s;
}
.ring-segment:nth-child(3) {
	border-top-color: #9b59b6;
	animation-delay: -4s;
}

@keyframes ringRotate {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

.helmet-shape {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 90px;
	height: 70px;
	z-index: 1;
}

.helmet-curve {
	width: 100%;
	height: 80%;
	background: linear-gradient(135deg, rgba(255, 152, 0, 0.3), rgba(255, 87, 34, 0.3));
	border-radius: 50% 50% 40% 40%;
	position: relative;
	overflow: hidden;
}

.helmet-visor {
	position: absolute;
	bottom: 0;
	left: 20%;
	width: 60%;
	height: 20%;
	background: rgba(255, 152, 0, 0.5);
	border-radius: 10px 10px 0 0;
}

.icon-halo {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 180px;
	height: 180px;
	background: radial-gradient(circle, rgba(52, 152, 219, 0.15) 0%, transparent 70%);
	z-index: 1;
	animation: haloPulse 5s ease-in-out infinite alternate;
}

@keyframes haloPulse {
	0% {
		opacity: 0.2;
		transform: translate(-50%, -50%) scale(1);
	}
	100% {
		opacity: 0.4;
		transform: translate(-50%, -50%) scale(1.1);
	}
}

.brand-text {
	position: relative;
	z-index: 2;
}

.system-title {
	font-size: 28px;
	font-weight: 700;
	margin-bottom: 12px;
	background: linear-gradient(135deg, #3498db, #9b59b6, #2ecc71);
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	text-shadow: 0 0 30px rgba(52, 152, 219, 0.3);
	letter-spacing: 1px;
}

.system-subtitle {
	font-size: 16px;
	color: rgba(255, 255, 255, 0.9);
	margin-bottom: 6px;
	font-weight: 500;
	letter-spacing: 2px;
}

.system-tagline {
	font-size: 14px;
	color: rgba(255, 255, 255, 0.5);
	letter-spacing: 1px;
	font-weight: 300;
}

/* 登录面板 */
.panel-header {
	text-align: center;
	margin-bottom: 40px;
	position: relative;
	padding-bottom: 20px;
}

.header-glow {
	position: absolute;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
	width: 100px;
	height: 2px;
	background: linear-gradient(90deg, transparent, #3498db, transparent);
	box-shadow: 0 0 10px #3498db;
}

.panel-header h2 {
	color: #ffffff;
	font-size: 22px;
	font-weight: 600;
	letter-spacing: 2px;
	margin-bottom: 8px;
}

.header-sub {
	color: rgba(255, 255, 255, 0.6);
	font-size: 12px;
	font-weight: 400;
	letter-spacing: 2px;
	text-transform: uppercase;
}

/* 输入字段 */
.input-field {
	position: relative;
	margin-bottom: 8px;
}

.field-glow-effect {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 12px;
	background: linear-gradient(135deg, rgba(52, 152, 219, 0.1), rgba(155, 89, 182, 0.1));
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
	z-index: 1;
}

.field-icon {
	position: absolute;
	left: 16px;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	width: 24px;
	height: 24px;
	color: rgba(52, 152, 219, 0.8);
}

.icon-svg {
	width: 100%;
	height: 100%;
	fill: currentColor;
}

.input-glow {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 12px;
	box-shadow: 0 0 20px rgba(52, 152, 219, 0);
	transition: box-shadow 0.3s ease;
	pointer-events: none;
}

:deep(.tech-input .el-input__wrapper) {
	box-shadow: 0 0 0 1px rgba(52, 152, 219, 0.2) !important;
	border-radius: 12px !important;
	padding: 0 20px 0 56px !important;
	background: rgba(255, 255, 255, 0.05) !important;
	backdrop-filter: blur(5px);
	border: none;
	height: 56px;
	transition: all 0.3s ease;
	position: relative;
	z-index: 2;
}

:deep(.tech-input .el-input__inner) {
	color: #ffffff !important;
	font-size: 16px !important;
	font-weight: 400;
	letter-spacing: 0.5px;
	background: transparent !important;
}

:deep(.tech-input .el-input__inner::placeholder) {
	color: rgba(255, 255, 255, 0.3) !important;
}

:deep(.tech-input .el-input__wrapper:hover) {
	box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.4) !important;
	background: rgba(255, 255, 255, 0.08) !important;
}

:deep(.tech-input .el-input__wrapper.is-focus) {
	box-shadow: 0 0 0 2px #3498db, 0 0 20px rgba(52, 152, 219, 0.4) !important;
	background: rgba(255, 255, 255, 0.1) !important;
}

.input-field.focused .field-glow-effect {
	opacity: 1;
}

.input-field.focused .input-glow {
	box-shadow: 0 0 20px rgba(52, 152, 219, 0.3);
}

.input-hint {
	font-size: 12px;
	color: rgba(255, 255, 255, 0.4);
	margin-top: 6px;
	margin-left: 56px;
	font-weight: 300;
	letter-spacing: 0.5px;
}

/* 科技按钮 */
.login-action {
	margin-top: 40px;
}

.tech-btn {
	width: 100%;
	height: 64px;
	padding: 0;
	border: none;
	border-radius: 16px;
	background: linear-gradient(135deg, 
		rgba(52, 152, 219, 0.9) 0%,
		rgba(155, 89, 182, 0.9) 50%,
		rgba(46, 204, 113, 0.9) 100%);
	position: relative;
	overflow: hidden;
	transition: all 0.4s ease;
	transform-style: preserve-3d;
	perspective: 1000px;
}

.btn-content {
	position: relative;
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
	height: 100%;
	transform: translateZ(20px);
}

.btn-glow {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: linear-gradient(45deg, 
		rgba(255, 255, 255, 0.1) 0%,
		rgba(255, 255, 255, 0.05) 50%,
		rgba(255, 255, 255, 0.1) 100%);
	opacity: 0.5;
	z-index: 1;
}

.btn-icon {
	width: 24px;
	height: 24px;
	color: white;
}

.btn-svg {
	width: 100%;
	height: 100%;
	fill: currentColor;
}

.btn-text {
	display: flex;
	flex-direction: column;
	gap: 4px;
	text-align: left;
}

.text-main {
	color: white;
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 1px;
	text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.text-sub {
	color: rgba(255, 255, 255, 0.8);
	font-size: 10px;
	font-weight: 500;
	letter-spacing: 2px;
	text-transform: uppercase;
}

.btn-trail {
	position: absolute;
	top: 50%;
	right: -20px;
	transform: translateY(-50%);
	width: 40px;
	height: 2px;
	background: white;
	opacity: 0;
	transition: all 0.3s ease;
}

.btn-energy-waves {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.energy-wave {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border-radius: 16px;
	border: 2px solid rgba(255, 255, 255, 0.3);
	animation: waveExpand 2s ease-out infinite;
}

.energy-wave:nth-child(2) {
	animation-delay: 0.5s;
}
.energy-wave:nth-child(3) {
	animation-delay: 1s;
}

@keyframes waveExpand {
	0% {
		transform: scale(1);
		opacity: 1;
	}
	100% {
		transform: scale(1.2);
		opacity: 0;
	}
}

.btn-particles {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 2;
}

.particle {
	position: absolute;
	width: 3px;
	height: 3px;
	background: white;
	border-radius: 50%;
	opacity: 0;
}

.tech-btn:hover {
	transform: translateY(-4px);
	box-shadow: 
		0 15px 35px rgba(52, 152, 219, 0.4),
		0 0 80px rgba(46, 204, 113, 0.3),
		inset 0 0 30px rgba(255, 255, 255, 0.1);
}

.tech-btn.hover .btn-trail {
	right: 32px;
	opacity: 1;
}

.tech-btn.hover .particle {
	animation: techParticleFloat 1.5s ease-out forwards;
}

.particle:nth-child(1) { top: 20%; left: 10%; animation-delay: 0.1s; }
.particle:nth-child(2) { top: 30%; left: 20%; animation-delay: 0.2s; }
.particle:nth-child(3) { top: 50%; left: 30%; animation-delay: 0.3s; }
.particle:nth-child(4) { top: 70%; left: 60%; animation-delay: 0.4s; }
.particle:nth-child(5) { top: 40%; left: 70%; animation-delay: 0.5s; }
.particle:nth-child(6) { top: 80%; left: 80%; animation-delay: 0.6s; }

@keyframes techParticleFloat {
	0% {
		transform: translateY(0) scale(1);
		opacity: 0;
	}
	20% {
		opacity: 1;
	}
	100% {
		transform: translateY(-60px) rotate(360deg) scale(0);
		opacity: 0;
	}
}

.tech-btn:active {
	transform: translateY(-2px);
	transition: transform 0.1s ease;
}

/* 系统状态 */
.system-status {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-top: 20px;
	padding: 0 8px;
}

.status-indicator {
	display: flex;
	align-items: center;
	gap: 12px;
}

.status-pulse {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: #2ecc71;
	box-shadow: 0 0 10px #2ecc71;
	animation: statusPulse 2s ease-in-out infinite;
	position: relative;
}

.status-indicator span {
	color: rgba(255, 255, 255, 0.7);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.5px;
}

.status-info span {
	color: rgba(255, 255, 255, 0.4);
	font-size: 11px;
	font-weight: 400;
	letter-spacing: 0.5px;
}

/* 面板选项 */
.panel-options {
	display: flex;
	flex-direction: column;
	gap: 16px;
	margin-top: 32px;
}

.option-link {
	display: flex;
	align-items: center;
	gap: 16px;
	color: rgba(255, 255, 255, 0.6);
	text-decoration: none;
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.5px;
	padding: 14px 20px;
	border-radius: 12px;
	transition: all 0.3s ease;
	position: relative;
	overflow: hidden;
	background: rgba(255, 255, 255, 0.03);
	border: 1px solid rgba(52, 152, 219, 0.1);
}

.link-glow {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: linear-gradient(90deg, 
		rgba(52, 152, 219, 0.1) 0%,
		rgba(155, 89, 182, 0.1) 50%,
		rgba(52, 152, 219, 0.1) 100%);
	opacity: 0;
	transition: opacity 0.3s ease;
}

.link-icon {
	width: 20px;
	height: 20px;
	color: rgba(52, 152, 219, 0.7);
	z-index: 1;
}

.link-svg {
	width: 100%;
	height: 100%;
	fill: currentColor;
}

.link-arrow {
	position: absolute;
	right: 20px;
	top: 50%;
	transform: translateY(-50%);
	width: 0;
	height: 0;
	border-top: 4px solid transparent;
	border-bottom: 4px solid transparent;
	border-left: 6px solid rgba(52, 152, 219, 0.5);
	transition: all 0.3s ease;
}

.option-link:hover {
	color: #ffffff;
	background: rgba(52, 152, 219, 0.15);
	border-color: rgba(52, 152, 219, 0.3);
	transform: translateX(8px);
}

.option-link:hover .link-glow {
	opacity: 1;
}

.option-link:hover .link-icon {
	color: #ffffff;
}

.option-link:hover .link-arrow {
	right: 16px;
	border-left-color: #ffffff;
}

/* 系统状态信息 */
.system-stats {
	margin-top: 40px;
	padding-top: 30px;
	border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.stats-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
}

.stat-item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 16px;
	background: rgba(255, 255, 255, 0.03);
	border-radius: 12px;
	border: 1px solid rgba(52, 152, 219, 0.1);
	transition: all 0.3s ease;
	position: relative;
	overflow: hidden;
}

.stat-glow {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: linear-gradient(45deg, 
		rgba(52, 152, 219, 0.1) 0%,
		rgba(155, 89, 182, 0.1) 100%);
	opacity: 0;
	transition: opacity 0.3s ease;
}

.stat-icon {
	width: 40px;
	height: 40px;
	border-radius: 10px;
	background: rgba(52, 152, 219, 0.15);
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
	z-index: 1;
}

.stat-svg {
	width: 20px;
	height: 20px;
	fill: rgba(52, 152, 219, 0.8);
}

.stat-content {
	display: flex;
	flex-direction: column;
	gap: 4px;
	z-index: 1;
}

.stat-value {
	font-size: 18px;
	font-weight: 700;
	color: #ffffff;
}

.stat-label {
	font-size: 12px;
	color: rgba(255, 255, 255, 0.5);
	font-weight: 500;
	letter-spacing: 0.5px;
}

.stat-item:hover {
	background: rgba(52, 152, 219, 0.1);
	border-color: rgba(52, 152, 219, 0.3);
	transform: translateY(-3px);
	box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}

.stat-item:hover .stat-glow {
	opacity: 1;
}

.stat-item:hover .stat-svg {
	fill: #ffffff;
}

/* 浮动科技元素 */
.floating-tech {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	z-index: 2;
}

.hexagon-grid {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

.hexagon {
	position: absolute;
	background: rgba(52, 152, 219, 0.05);
	clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
	animation: hexagonFloat 20s linear infinite;
}

@keyframes hexagonFloat {
	0% {
		transform: rotate(0deg) translateY(0);
	}
	100% {
		transform: rotate(360deg) translateY(20px);
	}
}

.binary-rain {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	opacity: 0.1;
}

.binary-column {
	position: absolute;
	top: -100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	color: rgba(52, 152, 219, 0.8);
	font-family: monospace;
	font-size: 12px;
	font-weight: 700;
	animation: binaryFall linear infinite;
}

.binary-digit {
	opacity: 0.5;
	transition: opacity 0.3s ease;
}

@keyframes binaryFall {
	0% {
		top: -100%;
	}
	100% {
		top: 100%;
	}
}

/* 响应式设计 */
@media (max-width: 768px) {
	.login-main {
		max-width: 90%;
		padding: 0;
	}
	
	.hologlass-panel {
		padding: 30px 25px;
	}
	
	.system-title {
		font-size: 24px;
	}
	
	.system-subtitle {
		font-size: 14px;
		letter-spacing: 1px;
	}
	
	.system-tagline {
		font-size: 12px;
	}
	
	.yolo-icon {
		width: 100px;
		height: 100px;
	}
	
	.yolo-core {
		width: 60px;
		height: 60px;
	}
	
	.yolo-text {
		font-size: 12px;
	}
	
	.version {
		font-size: 9px;
	}
	
	.stats-grid {
		grid-template-columns: 1fr;
		gap: 12px;
	}
	
	:deep(.tech-input .el-input__wrapper) {
		height: 52px;
	}
	
	.tech-btn {
		height: 56px;
	}
	
	.text-main {
		font-size: 16px;
	}
	
	.text-sub {
		font-size: 9px;
	}
}

@media (max-width: 480px) {
	.hologlass-panel {
		padding: 24px 20px;
		border-radius: 16px;
	}
	
	.panel-header h2 {
		font-size: 20px;
	}
	
	.header-sub {
		font-size: 11px;
	}
	
	.panel-options {
		gap: 12px;
	}
	
	.option-link {
		padding: 12px 16px;
	}
}
</style>

后端代码展示

项目源码+数据集下载链接

完整代码在哔哩哔哩视频下方简介内获取

基于深度学习的安全帽佩戴识别检测系统(最新web界面+YOLOv8/YOLOv10/YOLOv11/YOLOv12+DeepSeek智能分析 +前后端分离)_哔哩哔哩_bilibili

基于深度学习的安全帽佩戴识别检测系统(最新web界面+YOLOv8/YOLOv10/YOLOv11/YOLOv12+DeepSeek智能分析 +前后端分离)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1StmyBZEsC/?vd_source=549d0b4e2b8999929a61a037fcce3b0fhttps://www.bilibili.com/video/BV1StmyBZEsC

 项目安装教程

https://www.bilibili.com/video/BV1YLsXzJE2X/?spm_id_from=333.1387.homepage.video_card.click

YOLO+spring boot+vue项目环境部署教程(YOLOv8、YOLOv10、YOLOv11、YOLOv12)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1YLsXzJE2X/?spm_id_from=333.1387.homepage.video_card.click&vd_source=549d0b4e2b8999929a61a037fcce3b0f

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐