From 061fdfa6854ce6a8a4fbd3e64883ff8c94ded033 Mon Sep 17 00:00:00 2001 From: Yep_Q Date: Thu, 9 Oct 2025 14:50:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=B1=E5=BA=A6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=83=BD=E6=BA=90=E8=AE=A2=E5=8D=95=E7=8F=AD=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 详细说明: - 左右交替图文布局: Section 2采用split-layout,图文交替展示I/O配置 - Timeline时间轴: Section 3使用垂直时间轴展示机器人分拣流程 - 全宽视觉分隔区: 在section间添加视差滚动的全屏图片分隔 - 环形进度条: 替换普通统计卡片,使用SVG环形进度条展示关键数据 - 微交互动画: 添加涟漪效果、磁吸效果、边框光效、呼吸动画等 - 滚动条美化: 自定义滚动条样式 - 焦点优化: 增强可访问性的焦点显示 影响文件: - web_frontend/web_result/order-classes/energy/index.html - web_frontend/web_result/order-classes/energy/css/styles.css 影响模块: 能源订单班展示页面布局系统 --- .../order-classes/energy/css/styles.css | 684 ++++++++++++++++++ .../order-classes/energy/index.html | 277 +++++-- 2 files changed, 904 insertions(+), 57 deletions(-) diff --git a/web_frontend/web_result/order-classes/energy/css/styles.css b/web_frontend/web_result/order-classes/energy/css/styles.css index f6d16e26..6ab5049c 100644 --- a/web_frontend/web_result/order-classes/energy/css/styles.css +++ b/web_frontend/web_result/order-classes/energy/css/styles.css @@ -673,6 +673,382 @@ body.dark-theme tr:hover { grid-template-columns: repeat(3, 1fr); } +/* ========== 左右交替图文布局 ========== */ +.split-layout { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-2xl); + align-items: center; + margin: var(--spacing-2xl) 0; +} + +.split-layout-reverse { + direction: rtl; +} + +.split-layout-reverse > * { + direction: ltr; +} + +.split-layout-image { + position: relative; + border-radius: var(--radius-2xl); + overflow: hidden; + aspect-ratio: 4/3; + box-shadow: var(--shadow-xl); + transition: all var(--transition-base); +} + +.split-layout-image:hover { + transform: scale(1.02); + box-shadow: var(--shadow-xl), var(--shadow-orange); +} + +.split-layout-image img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.split-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, rgba(0,0,0,0.3), transparent); + display: flex; + align-items: flex-start; + justify-content: flex-end; + padding: var(--spacing-lg); +} + +.split-badge { + background: var(--primary-orange); + color: white; + padding: var(--spacing-sm) var(--spacing-lg); + border-radius: var(--radius-full); + font-weight: var(--font-bold); + font-size: var(--text-base); + box-shadow: var(--shadow-lg); +} + +.split-layout-content { + background: var(--bg-card); + backdrop-filter: blur(15px); + padding: var(--spacing-2xl); + border-radius: var(--radius-2xl); + border: 2px solid var(--border-light); + box-shadow: var(--shadow-lg); +} + +.split-title { + font-size: var(--text-2xl); + color: var(--primary-orange); + margin-bottom: var(--spacing-lg); + display: flex; + align-items: center; + gap: var(--spacing-md); +} + +.split-title i { + width: 32px !important; + height: 32px !important; +} + +@media (max-width: 1024px) { + .split-layout, + .split-layout-reverse { + grid-template-columns: 1fr; + direction: ltr; + } + + .split-layout-image { + order: 1; + } + + .split-layout-content { + order: 2; + } +} + +/* ========== 全宽视觉分隔区 ========== */ +.visual-divider { + height: 400px; + background-size: cover; + background-position: center; + background-attachment: fixed; + position: relative; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} + +.visual-divider::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, + rgba(120, 53, 15, 0.85) 0%, + rgba(217, 119, 6, 0.7) 100% + ); + backdrop-filter: blur(2px); +} + +body:not(.dark-theme) .visual-divider::before { + background: linear-gradient(135deg, + rgba(255, 251, 235, 0.85) 0%, + rgba(254, 243, 199, 0.9) 100% + ); +} + +.divider-content { + position: relative; + z-index: 1; + text-align: center; + color: var(--text-light); + animation: fadeInUp 1s ease; +} + +.divider-icon { + width: 80px; + height: 80px; + margin: 0 auto var(--spacing-lg); + background: var(--bg-card); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 3px solid var(--primary-orange); + box-shadow: var(--shadow-xl), 0 0 30px rgba(245, 158, 11, 0.5); + animation: pulse 2s ease-in-out infinite; +} + +.divider-icon i { + width: 40px !important; + height: 40px !important; + color: var(--primary-orange); +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + box-shadow: var(--shadow-xl), 0 0 30px rgba(245, 158, 11, 0.5); + } + 50% { + transform: scale(1.05); + box-shadow: var(--shadow-xl), 0 0 50px rgba(245, 158, 11, 0.8); + } +} + +.divider-content h3 { + font-size: var(--text-4xl); + font-weight: var(--font-bold); + margin-bottom: var(--spacing-md); + text-shadow: 0 4px 20px rgba(0,0,0,0.5); +} + +.divider-content p { + font-size: var(--text-xl); + opacity: 0.95; + text-shadow: 0 2px 10px rgba(0,0,0,0.5); +} + +@media (max-width: 768px) { + .visual-divider { + height: 300px; + background-attachment: scroll; + } + + .divider-icon { + width: 60px; + height: 60px; + } + + .divider-icon i { + width: 30px !important; + height: 30px !important; + } + + .divider-content h3 { + font-size: var(--text-2xl); + } + + .divider-content p { + font-size: var(--text-base); + } +} + +/* ========== Timeline时间轴布局 ========== */ +.timeline-container { + margin: var(--spacing-2xl) 0; +} + +.timeline-title { + font-size: var(--text-3xl); + color: var(--primary-orange); + margin-bottom: var(--spacing-2xl); + display: flex; + align-items: center; + gap: var(--spacing-md); + text-align: center; + justify-content: center; +} + +.timeline-title i { + width: 40px !important; + height: 40px !important; +} + +.timeline { + position: relative; + max-width: 1000px; + margin: 0 auto; + padding: var(--spacing-xl) 0; +} + +/* 时间轴中心线 */ +.timeline::before { + content: ''; + position: absolute; + left: 50%; + top: 0; + bottom: 0; + width: 3px; + background: linear-gradient(to bottom, + transparent, + var(--primary-orange) 10%, + var(--primary-orange) 90%, + transparent + ); + transform: translateX(-50%); +} + +.timeline-item { + position: relative; + display: flex; + align-items: center; + margin-bottom: var(--spacing-2xl); +} + +.timeline-item:nth-child(odd) { + justify-content: flex-start; +} + +.timeline-item:nth-child(even) { + justify-content: flex-end; +} + +.timeline-marker { + position: absolute; + left: 50%; + transform: translateX(-50%); + width: 60px; + height: 60px; + border-radius: 50%; + background: var(--bg-card); + border: 4px solid var(--primary-orange); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + box-shadow: var(--shadow-lg), 0 0 0 8px var(--bg-dark); + transition: all var(--transition-base); +} + +.timeline-marker i { + width: 28px !important; + height: 28px !important; + color: var(--primary-orange); +} + +.timeline-item:hover .timeline-marker { + transform: translateX(-50%) scale(1.1); + box-shadow: var(--shadow-xl), 0 0 0 12px var(--bg-dark), var(--shadow-orange); +} + +.timeline-content { + width: calc(50% - 60px); + background: var(--bg-card); + backdrop-filter: blur(15px); + padding: var(--spacing-xl); + border-radius: var(--radius-xl); + border: 2px solid var(--border-light); + box-shadow: var(--shadow-md); + transition: all var(--transition-base); +} + +.timeline-item:nth-child(odd) .timeline-content { + margin-right: calc(50% + 40px); +} + +.timeline-item:nth-child(even) .timeline-content { + margin-left: calc(50% + 40px); +} + +.timeline-content:hover { + transform: translateY(-4px); + box-shadow: var(--shadow-xl), var(--shadow-orange); + border-color: var(--primary-orange); +} + +.timeline-step { + font-size: var(--text-sm); + color: var(--primary-orange); + font-weight: var(--font-bold); + text-transform: uppercase; + letter-spacing: 0.1em; + margin-bottom: var(--spacing-xs); +} + +.timeline-content h4 { + font-size: var(--text-xl); + color: var(--text-light); + margin-bottom: var(--spacing-sm); + font-weight: var(--font-semibold); +} + +.timeline-content p { + color: var(--text-gray); + font-size: var(--text-base); + line-height: 1.6; + margin-bottom: var(--spacing-md); +} + +.timeline-badge { + display: inline-block; + padding: var(--spacing-xs) var(--spacing-md); + background: var(--active-bg); + color: var(--primary-orange); + border-radius: var(--radius-full); + font-size: var(--text-sm); + font-weight: var(--font-medium); +} + +@media (max-width: 768px) { + .timeline::before { + left: 30px; + } + + .timeline-item { + justify-content: flex-end !important; + } + + .timeline-marker { + left: 30px; + } + + .timeline-content { + width: calc(100% - 100px); + margin-left: 100px !important; + margin-right: 0 !important; + } +} + /* ========== Bento Grid布局 - 不等大小网格 ========== */ .bento-grid { display: grid; @@ -877,6 +1253,104 @@ body.dark-theme tr:hover { text-shadow: none; } +/* ========== 增强数据可视化 - 环形进度条 ========== */ +.stats-enhanced { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: var(--spacing-xl); + padding: var(--spacing-xl); + background: var(--bg-overlay); + backdrop-filter: blur(15px); + border-radius: var(--radius-2xl); + border: 2px solid var(--border-light); + box-shadow: var(--shadow-lg); +} + +.stat-circle-item { + text-align: center; + transition: all var(--transition-base); +} + +.stat-circle-item:hover { + transform: translateY(-8px); +} + +.circle-progress { + position: relative; + width: 160px; + height: 160px; + margin: 0 auto var(--spacing-md); +} + +.circle-progress svg { + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.circle-bg, +.circle-fill { + fill: none; + stroke-width: 8; +} + +.circle-bg { + stroke: var(--border-light); +} + +.circle-fill { + stroke: var(--primary-orange); + stroke-linecap: round; + stroke-dasharray: 326.73; /* 2 * π * r = 2 * π * 52 */ + stroke-dashoffset: calc(326.73 * (1 - var(--progress, 0) / 100)); + transition: stroke-dashoffset 2s cubic-bezier(0.16, 1, 0.3, 1); + filter: drop-shadow(0 0 8px rgba(245, 158, 11, 0.5)); +} + +.circle-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} + +.circle-value { + font-size: var(--text-3xl); + font-weight: var(--font-bold); + color: var(--primary-orange); + line-height: 1; + margin-bottom: var(--spacing-xs); +} + +.circle-unit { + font-size: var(--text-sm); + color: var(--text-gray); + font-weight: var(--font-medium); +} + +.stat-circle-item .stat-label { + font-size: var(--text-base); + color: var(--text-light); + font-weight: var(--font-semibold); +} + +@media (max-width: 768px) { + .stats-enhanced { + grid-template-columns: repeat(2, 1fr); + gap: var(--spacing-lg); + } + + .circle-progress { + width: 120px; + height: 120px; + } + + .circle-value { + font-size: var(--text-2xl); + } +} + /* ========== 表格 ========== */ .table-container { overflow-x: auto; @@ -1204,6 +1678,216 @@ tr:hover { left: 100%; } +/* ========== 微交互动画细节 ========== */ + +/* 按钮点击涟漪效果 */ +.nav-item, +.hero-badge, +.timeline-marker { + position: relative; + overflow: hidden; +} + +.nav-item::after, +.hero-badge::after { + content: ''; + position: absolute; + width: 100%; + height: 100%; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) scale(0); + background: radial-gradient(circle, rgba(245, 158, 11, 0.3), transparent); + border-radius: 50%; + opacity: 0; + transition: all 0.5s ease; + pointer-events: none; +} + +.nav-item:active::after, +.hero-badge:active::after { + transform: translate(-50%, -50%) scale(2.5); + opacity: 1; + transition: 0s; +} + +/* 图片磁吸效果 */ +.image-container { + cursor: pointer; +} + +.image-container::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) scale(0); + width: 60px; + height: 60px; + background: rgba(245, 158, 11, 0.9); + border-radius: 50%; + opacity: 0; + transition: all 0.3s ease; + pointer-events: none; +} + +.image-container::before { + content: '👁'; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 24px; + opacity: 0; + z-index: 10; + transition: all 0.3s ease; + pointer-events: none; +} + +.image-container:hover::after { + transform: translate(-50%, -50%) scale(1); + opacity: 0.8; +} + +.image-container:hover::before { + opacity: 1; +} + +/* 链接下划线动画 */ +.feature-list li { + position: relative; +} + +.feature-list li::after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + width: 0; + height: 2px; + background: var(--primary-orange); + transition: width 0.3s ease; +} + +.feature-list li:hover::after { + width: 100%; +} + +/* 卡片边框光效 */ +@keyframes borderGlow { + 0%, 100% { + box-shadow: + var(--shadow-md), + 0 0 20px rgba(245, 158, 11, 0.3), + inset 0 0 20px rgba(245, 158, 11, 0.1); + } + 50% { + box-shadow: + var(--shadow-lg), + 0 0 30px rgba(245, 158, 11, 0.5), + inset 0 0 30px rgba(245, 158, 11, 0.2); + } +} + +.card:hover { + animation: borderGlow 2s ease-in-out infinite; +} + +/* 文字打字机效果类 */ +.typewriter { + overflow: hidden; + border-right: 2px solid var(--primary-orange); + white-space: nowrap; + animation: typing 3.5s steps(40) 1s 1 normal both, + blink 0.75s step-end infinite; +} + +@keyframes typing { + from { width: 0; } + to { width: 100%; } +} + +@keyframes blink { + 50% { border-color: transparent; } +} + +/* 表格行悬停效果 */ +tr { + transition: all var(--transition-fast); + position: relative; +} + +tr::before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 3px; + height: 0; + background: var(--primary-orange); + transition: height var(--transition-base); +} + +tr:hover::before { + height: 100%; +} + +/* Agent头像呼吸效果 */ +.agent-avatar { + animation: breathe 3s ease-in-out infinite; +} + +@keyframes breathe { + 0%, 100% { + box-shadow: 0 0 20px rgba(245, 158, 11, 0.4); + } + 50% { + box-shadow: 0 0 30px rgba(245, 158, 11, 0.7); + } +} + +/* 滚动条美化 */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +::-webkit-scrollbar-track { + background: var(--bg-semi-dark); +} + +::-webkit-scrollbar-thumb { + background: var(--primary-orange); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--accent-amber); +} + +/* 选中文本样式 */ +::selection { + background: var(--primary-orange); + color: white; +} + +::-moz-selection { + background: var(--primary-orange); + color: white; +} + +/* 焦点可见性优化 */ +*:focus-visible { + outline: 2px solid var(--primary-orange); + outline-offset: 2px; + border-radius: var(--radius-sm); +} + +/* 工具提示hover */ +[title] { + position: relative; +} + /* ========== 工具类 ========== */ .text-center { text-align: center; } .text-left { text-align: left; } diff --git a/web_frontend/web_result/order-classes/energy/index.html b/web_frontend/web_result/order-classes/energy/index.html index 4f5dd358..77cf81fa 100644 --- a/web_frontend/web_result/order-classes/energy/index.html +++ b/web_frontend/web_result/order-classes/energy/index.html @@ -206,28 +206,84 @@ -
-
+ +
+ +
+
+ + + + +
+
3600
+
片/时
+
+
设计产能
-
3600片/时
-
+ +
+
+ + + + +
+
99.7
+
%
+
+
+
检出率
+
+ +
+
+ + + + +
+
0.5
+
%
+
+
误检率
-
≤0.5%
-
-
漏检率
-
≤0.3%
-
-
+ +
+
+ + + + +
+
300
+
ms
+
+
检测时间
-
0ms
+ +
+
+
+ +
+

智能化生产线

+

PLC + 机器视觉 + 机器人协同工作

+
+
+
@@ -252,37 +308,50 @@
系统控制流程Mermaid图
-
-
-
-

输入信号配置(14路)

-
-
-
    -
  • I0.0~I0.2: 急停/安全门/光栅(安全链)
  • -
  • I0.3~I0.5: 来料/到位/离开传感器
  • -
  • I0.6~I0.7: 相机触发完成/异常信号
  • -
  • I1.0~I1.2: 机器人就绪/抓取完成/报警
  • -
  • I1.3~I1.4: 温度/湿度监测
  • -
  • I1.5: 手动/自动模式切换
  • -
+ +
+ +
+ PLC I/O配置 +
+
14路输入
-
-
-

输出信号配置(13路)

-
-
-
    -
  • Q0.0: 输送电机启动(变频器使能)
  • -
  • Q0.1~Q0.2: 定位气缸/夹持气缸
  • -
  • Q0.3~Q0.4: 相机触发/光源控制
  • -
  • Q0.5~Q0.7: 机器人启动/结果1/结果2
  • -
  • Q1.0~Q1.2: 指示灯(运行/故障/待机)
  • -
  • Q1.3: 蜂鸣器报警输出
  • -
  • Q1.4: MES数据上传握手信号
  • -
+ +
+

输入信号配置

+
    +
  • I0.0~I0.2: 急停/安全门/光栅(安全链)
  • +
  • I0.3~I0.5: 来料/到位/离开传感器
  • +
  • I0.6~I0.7: 相机触发完成/异常信号
  • +
  • I1.0~I1.2: 机器人就绪/抓取完成/报警
  • +
  • I1.3~I1.4: 温度/湿度监测
  • +
  • I1.5: 手动/自动模式切换
  • +
+
+
+ +
+ +
+

输出信号配置

+
    +
  • Q0.0: 输送电机启动(变频器使能)
  • +
  • Q0.1~Q0.2: 定位气缸/夹持气缸
  • +
  • Q0.3~Q0.4: 相机触发/光源控制
  • +
  • Q0.5~Q0.7: 机器人启动/结果1/结果2
  • +
  • Q1.0~Q1.2: 指示灯(运行/故障/待机)
  • +
  • Q1.3: 蜂鸣器报警输出
  • +
  • Q1.4: MES数据上传握手信号
  • +
+
+ + +
+ PLC控制流程 +
+
13路输出
@@ -398,6 +467,17 @@
+ +
+
+
+ +
+

精密机器人分拣

+

±0.02mm定位精度 · ≤0.8秒单次节拍

+
+
+
@@ -422,32 +502,104 @@
机器人分拣路径三维仿真
-
-
-
-

分拣逻辑流程

+ +
+

分拣逻辑流程

+ +
+ +
+
+ +
+
+
步骤 1
+

等待PLC就绪信号

+

检测DI1=1,确认系统准备就绪

+
初始化
+
-
-
    -
  • 1. 等待PLC就绪信号(DI1=1)
  • -
  • 2. 移动至拾取点→开启真空→检测吸附
  • -
  • 3. 读取检测结果(DI2-DI3编码)
  • -
  • 4. 分支判断: OK→托盘1, RW→托盘2, NG→废料箱
  • -
  • 5. 到达目标位置→关闭真空→等待释放
  • -
  • 6. 返回原点→发送完成信号(DO1=1)→循环
  • -
+ + +
+
+ +
+
+
步骤 2
+

移动至拾取点

+

机器人移动→开启真空→检测吸附成功

+
拾取
+
+
+ + +
+
+ +
+
+
步骤 3
+

读取检测结果

+

从PLC读取DI2-DI3编码,获取质量判定

+
判断
+
+
+ + +
+
+ +
+
+
步骤 4
+

分支判断路径

+

OK→托盘1 | RW→托盘2 | NG→废料箱

+
分拣
+
+
+ + +
+
+ +
+
+
步骤 5
+

到达目标位置

+

精确定位→关闭真空→等待释放确认

+
放置
+
+
+ + +
+
+ +
+
+
步骤 6
+

返回原点并循环

+

发送完成信号DO1=1,准备下一次循环

+
完成
+
+
-
-
-

安全策略设计

-
-
+ +
+
+

安全策略设计

+
+
+
  • 工作区域: 4个WorldZone限制区域
  • 急停响应: ≤50ms安全断电
  • 碰撞检测: 力矩阈值80%触发保护
  • +
+
  • 示教模式: 速度限制250mm/s
  • 负载监控: 超7kg触发报警
  • 安全评级: PL=d / SIL=2
  • @@ -567,6 +719,17 @@
+ +
+
+
+ +
+

深度学习视觉检测

+

99.7%检出率 · 0.05mm缺陷可检出

+
+
+