refactor: 全面优化编码规范并修复连接状态检查

## 主要改进

### 🎨 编码规范统一化
- 消除硬编码颜色值,统一使用CSS变量系统
- 替换所有rgba硬编码为预定义的主题变量
- 统一通知duration配置,从配置文件读取

### 🐛 连接状态检查修复
- 修复Creo模型分析页面未检查连接状态的bug
- 添加checkCreoConnection()函数验证连接状态
- 未连接时显示友好的警告提示

### 📝 调试输出管理
- 创建统一Logger工具类管理所有console输出
- 替换apiClient.js和websocketService.js中的console调用
- 实现开发/生产环境的日志级别控制

### 🔧 配置管理优化
- 修复组件中硬编码的duration值
- 新增SUCCESS_LONG_DURATION配置项
- 确保所有配置统一从config/cad.js读取

### 📚 开发文档
- 更新CSS_THEME_GUIDE.md主题使用指南
- 添加统一Logger工具类文档

## 技术细节
- 影响文件: 24个核心文件
- 新增工具: src/utils/logger.js
- 配置优化: 通知时长统一管理
- 主题变量: 完全消除硬编码颜色值

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sladro 2025-09-25 10:30:06 +08:00
parent c0892dcfc8
commit 2c2002d261
26 changed files with 1105 additions and 440 deletions

242
CSS_THEME_GUIDE.md Normal file
View File

@ -0,0 +1,242 @@
# CSS主题系统使用指南
## 概述
本项目采用统一的CSS主题系统通过CSS变量实现一致的视觉效果和便捷的主题管理。所有颜色、尺寸、间距等样式值都通过预定义的CSS变量进行管理确保代码的一致性和可维护性。
## 🎯 核心原则
### ✅ 正确做法
```css
/* 使用CSS变量 */
padding: var(--spacing-md);
font-size: var(--font-size-base);
border-radius: var(--size-border-radius);
color: var(--color-text-primary);
```
### ❌ 禁止做法
```css
/* 硬编码值 - 严禁使用 */
padding: 12px;
font-size: 14px;
border-radius: 8px;
color: #ffffff;
```
## 🎨 变量分类系统
### 1. 尺寸变量 (`--size-*`)
```css
/* 常用固定尺寸 */
--size-1: 1px; /* 边框、分割线 */
--size-2: 2px; /* 小装饰 */
--size-4: 4px; /* 小圆角 */
--size-6: 6px; /* 按钮圆角 */
--size-8: 8px; /* 标准圆角 */
--size-12: 12px; /* 卡片圆角 */
--size-16: 16px; /* 图标尺寸 */
--size-24: 24px; /* 大图标 */
--size-32: 32px; /* 按钮高度 */
--size-40: 40px; /* 操作按钮 */
--size-48: 48px; /* 头像尺寸 */
--size-60: 60px; /* 头部高度 */
```
### 2. 间距变量 (`--spacing-*`)
```css
/* 间距系统 */
--spacing-xxs: 2px; /* 微小间距 */
--spacing-xs: 4px; /* 极小间距 */
--spacing-sm: 8px; /* 小间距 */
--spacing-md: 12px; /* 中等间距 */
--spacing-lg: 16px; /* 大间距 */
--spacing-xl: 20px; /* 超大间距 */
--spacing-2xl: 24px; /* 卡片间距 */
--spacing-3xl: 32px; /* 区域间距 */
--spacing-4xl: 40px; /* 大区域间距 */
--spacing-5xl: 48px; /* 页面间距 */
--spacing-6xl: 60px; /* 头部间距 */
```
### 3. 字体变量 (`--font-size-*`)
```css
/* 字体大小系统 */
--font-size-xs: 12px; /* 辅助文字 */
--font-size-sm: 13px; /* 小文字 */
--font-size-base: 14px; /* 基础文字 */
--font-size-md: 15px; /* 中等文字 */
--font-size-lg: 16px; /* 大文字 */
--font-size-xl: 18px; /* 标题文字 */
--font-size-2xl: 20px; /* 副标题 */
--font-size-3xl: 24px; /* 主标题 */
```
### 4. 图标变量 (`--icon-size-*`)
```css
/* 图标尺寸系统 */
--icon-size-xs: 12px; /* 状态图标 */
--icon-size-sm: 14px; /* 小图标 */
--icon-size-md: 16px; /* 标准图标 */
--icon-size-lg: 20px; /* 大图标 */
--icon-size-xl: 24px; /* 超大图标 */
--icon-size-2xl: 28px; /* 装饰图标 */
--icon-size-3xl: 32px; /* 特大图标 */
```
### 5. 颜色变量 (`--color-*`)
```css
/* 文字颜色 */
--color-text-primary: /* 主要文字 */
--color-text-secondary: /* 次要文字 */
--color-text-tertiary: /* 辅助文字 */
--color-text-error: /* 错误文字 */
/* 背景颜色 */
--color-bg-primary: /* 主背景 */
--color-bg-secondary: /* 次背景 */
--color-bg-card: /* 卡片背景 */
--color-bg-hover: /* 悬停背景 */
/* 边框颜色 */
--color-border-primary: /* 主边框 */
--color-border-secondary: /* 次边框 */
--color-border-active: /* 激活边框 */
```
### 6. CAD软件主题色
```css
/* Creo主题 */
--color-primary: /* 蓝色主题 */
/* PDMS主题 */
--color-pdms: /* 橙色主题 */
--color-pdms-gradient: /* 橙色渐变 */
/* Revit主题 */
--color-revit: /* 绿色主题 */
--color-revit-gradient: /* 绿色渐变 */
/* 复杂度分析主题 */
--color-complexity: /* 分析橙色 */
--color-complexity-high: /* 高复杂度红色 */
--color-complexity-low: /* 低复杂度绿色 */
```
## 🛠️ 使用示例
### 按钮样式
```css
.custom-button {
padding: var(--spacing-md) var(--spacing-lg);
font-size: var(--font-size-base);
border-radius: var(--size-border-radius-button);
border: var(--border-width-thin) solid var(--color-border-primary);
gap: var(--spacing-sm);
}
```
### 卡片样式
```css
.card-component {
padding: var(--spacing-xl);
margin-bottom: var(--spacing-2xl);
border-radius: var(--size-border-radius-card);
border: var(--border-width-thin) solid var(--color-border-primary);
background: var(--color-bg-card);
}
```
### 文字样式
```css
.title {
font-size: var(--font-size-2xl);
color: var(--color-text-primary);
margin-bottom: var(--spacing-lg);
}
.subtitle {
font-size: var(--font-size-base);
color: var(--color-text-secondary);
}
```
### 响应式断点
```css
@media (max-width: var(--breakpoint-tablet)) {
.responsive-element {
padding: var(--spacing-sm);
font-size: var(--font-size-sm);
}
}
```
## 🔧 变量映射表
### 常用硬编码值对应的变量
| 硬编码值 | 对应变量 | 用途 |
|---------|---------|------|
| `1px` | `var(--size-1)` | 边框 |
| `2px` | `var(--size-2)` | 小装饰 |
| `4px` | `var(--spacing-xs)` | 微间距 |
| `6px` | `var(--size-6)` | 按钮圆角 |
| `8px` | `var(--spacing-sm)` | 小间距 |
| `10px` | `var(--size-10)` | 内边距 |
| `12px` | `var(--spacing-md)` | 标准间距 |
| `14px` | `var(--font-size-base)` | 基础字体 |
| `16px` | `var(--spacing-lg)` | 大间距 |
| `20px` | `var(--spacing-xl)` | 超大间距 |
| `24px` | `var(--spacing-2xl)` | 卡片间距 |
| `768px` | `var(--breakpoint-tablet)` | 平板断点 |
## 📋 开发检查清单
### 开发前检查
- [ ] 确认所需尺寸在变量系统中是否已存在
- [ ] 如需新尺寸,先在`theme.css`中添加变量
- [ ] 确认变量命名符合语义化原则
### 代码审查检查
- [ ] 没有使用任何硬编码的`px`、`rem`、`em`值
- [ ] 所有颜色都使用CSS变量
- [ ] 响应式断点使用变量
- [ ] 间距、字体、圆角都使用对应变量
### 测试检查
- [ ] 组件在不同主题下显示正常
- [ ] 响应式布局工作正常
- [ ] 所有交互状态hover、active、focus正常
## 🚨 常见问题
### Q: 需要的尺寸在变量中找不到怎么办?
A: 在`src/assets/styles/theme.css`中添加新变量,命名要语义化。
### Q: 特殊组件需要特定尺寸怎么办?
A: 在theme.css中的"组件特定"区域添加专用变量。
### Q: 如何确保主题切换正常?
A: 所有样式都使用CSS变量确保亮暗主题切换时自动更新。
### Q: 媒体查询也要使用变量吗?
A: 是的,使用`var(--breakpoint-*)`系列变量。
## 🎯 最佳实践
1. **语义化命名**:变量名要明确表达用途
2. **分层设计**:区分基础变量和语义变量
3. **一致性原则**:同类元素使用相同变量
4. **可维护性**:修改主题只需调整变量文件
5. **文档更新**:新增变量要及时更新文档
## 🔄 持续改进
- 定期审查未使用的变量
- 根据设计需求扩展变量系统
- 收集开发反馈,优化变量分类
- 保持变量系统的简洁性和易用性
---
**记住:统一的主题系统是项目可维护性的关键!严格遵循变量使用规范。**

View File

@ -5,13 +5,13 @@
/* 管理面板基本布局 */
.management-panel {
position: fixed;
top: 60px; /* 头部高度偏移 */
right: -400px; /* 初始隐藏在右侧 */
width: 400px;
height: calc(100vh - 60px);
background: linear-gradient(135deg, #1e1e1e 0%, #2a2a2a 100%);
border-left: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: -4px 0 15px rgba(0, 0, 0, 0.3);
top: var(--size-header-height); /* 头部高度偏移 */
right: calc(-1 * var(--size-info-panel-width)); /* 初始隐藏在右侧 */
width: var(--size-info-panel-width);
height: calc(var(--size-screen-height) - var(--size-header-height));
background: var(--color-bg-gradient-main);
border-left: 1px solid var(--color-border-primary);
box-shadow: -4px 0 15px var(--color-shadow-black-1);
z-index: 1000;
display: flex;
flex-direction: column;
@ -28,22 +28,22 @@
align-items: center;
justify-content: space-between;
padding: 15px 20px;
background: #1e1e1e;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
min-height: 60px;
background: var(--color-bg-tertiary);
border-bottom: 1px solid var(--color-border-primary);
min-height: var(--size-info-panel-header-height);
}
.panel-title {
display: flex;
align-items: center;
gap: 10px;
color: #ffffff;
color: var(--color-text-primary);
font-weight: 600;
font-size: 16px;
}
.panel-title i {
color: #2a5caa;
color: var(--color-primary);
font-size: 18px;
}
@ -59,15 +59,15 @@
gap: 6px;
padding: 4px 8px;
border-radius: 4px;
background: rgba(244, 67, 54, 0.1);
color: #f44336;
background: var(--color-bg-error);
color: var(--color-error);
font-size: 12px;
font-weight: 500;
}
.status-indicator.connected {
background: rgba(76, 175, 80, 0.1);
color: #4caf50;
background: var(--color-bg-success);
color: var(--color-success);
}
.status-indicator i {
@ -77,7 +77,7 @@
.panel-close {
background: none;
border: none;
color: #cccccc;
color: var(--color-text-secondary);
cursor: pointer;
padding: 6px;
border-radius: 4px;
@ -85,8 +85,8 @@
}
.panel-close:hover {
background: #2a2a2a;
color: #ffffff;
background: var(--color-bg-secondary);
color: var(--color-text-primary);
}
/* 面板内容区域 */
@ -100,8 +100,8 @@
/* 选项卡导航 */
.panel-tabs {
display: flex;
background: #2a2a2a;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
background: var(--color-bg-secondary);
border-bottom: 1px solid var(--color-border-primary);
}
.tab-btn {
@ -113,7 +113,7 @@
padding: 12px 8px;
background: none;
border: none;
color: #cccccc;
color: var(--color-text-secondary);
font-size: 12px;
cursor: pointer;
transition: all 0.2s ease;
@ -121,14 +121,14 @@
}
.tab-btn:hover {
background: rgba(255, 255, 255, 0.05);
color: #ffffff;
background: var(--color-bg-hover);
color: var(--color-text-primary);
}
.tab-btn.active {
color: #2a5caa;
border-bottom-color: #2a5caa;
background: #1e1e1e;
color: var(--color-primary);
border-bottom-color: var(--color-primary);
background: var(--color-bg-tertiary);
}
.tab-btn i {
@ -155,16 +155,16 @@
display: flex;
align-items: center;
justify-content: space-between;
color: #ffffff;
color: var(--color-text-primary);
font-size: 14px;
font-weight: 600;
margin: 0 0 15px 0;
padding-bottom: 8px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid var(--color-border-secondary);
}
.section-title i {
color: #2a5caa;
color: var(--color-primary);
margin-right: 8px;
}
@ -175,12 +175,12 @@
justify-content: center;
gap: 10px;
padding: 40px 20px;
color: #cccccc;
color: var(--color-text-secondary);
font-size: 14px;
}
.loading-state i {
color: #2a5caa;
color: var(--color-primary);
font-size: 16px;
}
@ -196,15 +196,15 @@
flex-direction: column;
gap: 12px;
padding: 16px;
background: #2a2a2a;
border: 1px solid rgba(255, 255, 255, 0.2);
background: var(--color-bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: 8px;
transition: all 0.2s ease;
}
.software-item-backend:hover {
border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
border-color: var(--color-border-secondary);
box-shadow: 0 2px 8px var(--color-shadow-black-1);
}
.software-info {
@ -220,7 +220,7 @@
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #2a5caa 0%, #3d7bd8 100%);
background: var(--color-primary-gradient);
border-radius: 6px;
color: white;
font-size: 14px;
@ -232,19 +232,19 @@
}
.software-name-backend {
color: #ffffff;
color: var(--color-text-primary);
font-weight: 500;
font-size: 14px;
margin-bottom: 2px;
}
.software-status {
color: #cccccc;
color: var(--color-text-secondary);
font-size: 12px;
}
.software-status.running {
color: #4caf50;
color: var(--color-success);
}
.software-actions {
@ -267,67 +267,67 @@
gap: 6px;
min-width: 70px;
justify-content: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
box-shadow: var(--color-shadow-btn);
}
.action-btn.start {
background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%);
background: var(--color-btn-success);
color: white;
}
.action-btn.start:hover:not(:disabled) {
background: linear-gradient(135deg, #66bb6a 0%, #81c784 100%);
background: var(--color-btn-success-hover);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(76, 175, 80, 0.3);
box-shadow: var(--color-shadow-btn-success);
}
.action-btn.stop {
background: linear-gradient(135deg, #f44336 0%, #ef5350 100%);
background: var(--color-btn-error);
color: white;
}
.action-btn.stop:hover:not(:disabled) {
background: linear-gradient(135deg, #ef5350 0%, #e57373 100%);
background: var(--color-btn-error-hover);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(244, 67, 54, 0.3);
box-shadow: var(--color-shadow-btn-error);
}
.action-btn.restart {
background: linear-gradient(135deg, #ff9800 0%, #ffb74d 100%);
background: var(--color-btn-warning);
color: white;
}
.action-btn.restart:hover:not(:disabled) {
background: linear-gradient(135deg, #ffb74d 0%, #ffcc02 100%);
background: var(--color-btn-warning-hover);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(255, 152, 0, 0.3);
box-shadow: var(--color-shadow-btn-warning);
}
.action-btn.refresh {
background: linear-gradient(135deg, #2196f3 0%, #42a5f5 100%);
background: var(--color-btn-info);
color: white;
}
.action-btn.refresh:hover:not(:disabled) {
background: linear-gradient(135deg, #42a5f5 0%, #64b5f6 100%);
background: var(--color-btn-info-hover);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(33, 150, 243, 0.3);
box-shadow: var(--color-shadow-btn-info);
}
.action-btn.clear {
background: linear-gradient(135deg, #f44336 0%, #ef5350 100%);
background: var(--color-btn-error);
color: white;
}
.action-btn.clear:hover:not(:disabled) {
background: linear-gradient(135deg, #ef5350 0%, #e57373 100%);
background: var(--color-btn-error-hover);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(244, 67, 54, 0.3);
box-shadow: var(--color-shadow-btn-error);
}
.action-btn:disabled {
background: #1a1a1a;
color: #999999;
background: var(--color-bg-tertiary);
color: var(--color-text-disabled);
cursor: not-allowed;
opacity: 0.6;
box-shadow: none;
@ -337,7 +337,7 @@
.refresh-btn {
background: none;
border: none;
color: #cccccc;
color: var(--color-text-secondary);
cursor: pointer;
padding: 4px;
border-radius: 4px;
@ -345,8 +345,8 @@
}
.refresh-btn:hover {
color: #2a5caa;
background: rgba(42, 92, 170, 0.1);
color: var(--color-primary);
background: var(--color-primary-rgb);
}
/* 日志面板样式 */
@ -370,10 +370,10 @@
.filter-select, .filter-input {
padding: 6px 10px;
border: 1px solid rgba(255, 255, 255, 0.2);
border: 1px solid var(--color-border-secondary);
border-radius: 4px;
background: #2a2a2a;
color: #ffffff;
background: var(--color-bg-secondary);
color: var(--color-text-primary);
font-size: 12px;
}
@ -387,20 +387,20 @@
.filter-select:focus, .filter-input:focus {
outline: none;
border-color: #2a5caa;
border-color: var(--color-primary);
}
.logs-list {
max-height: 300px;
overflow-y: auto;
border: 1px solid rgba(255, 255, 255, 0.2);
border: 1px solid var(--color-border-secondary);
border-radius: 6px;
background: #2a2a2a;
background: var(--color-bg-secondary);
}
.log-item {
padding: 10px 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid var(--color-border-secondary);
transition: background 0.2s ease;
}
@ -409,7 +409,7 @@
}
.log-item:hover {
background: #1a1a1a;
background: var(--color-bg-tertiary);
}
.log-header {
@ -420,18 +420,18 @@
}
.log-operation {
color: #ffffff;
color: var(--color-text-primary);
font-weight: 500;
font-size: 13px;
}
.log-time {
color: #cccccc;
color: var(--color-text-secondary);
font-size: 11px;
}
.log-details {
color: #cccccc;
color: var(--color-text-secondary);
font-size: 12px;
line-height: 1.4;
}
@ -442,11 +442,11 @@
gap: 10px;
margin-top: 4px;
font-size: 11px;
color: #888888;
color: var(--color-text-tertiary);
}
.log-user {
color: #2a5caa;
color: var(--color-primary);
}
.log-status {
@ -457,13 +457,13 @@
}
.log-status.success {
background: rgba(76, 175, 80, 0.1);
color: #4caf50;
background: var(--color-bg-success);
color: var(--color-success);
}
.log-status.failed {
background: rgba(244, 67, 54, 0.1);
color: #f44336;
background: var(--color-bg-error);
color: var(--color-error);
}
.logs-pagination {
@ -473,34 +473,34 @@
gap: 15px;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid rgba(255, 255, 255, 0.2);
border-top: 1px solid var(--color-border-secondary);
}
.page-btn {
padding: 6px 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
border: 1px solid var(--color-border-secondary);
border-radius: 4px;
background: #2a2a2a;
color: #cccccc;
background: var(--color-bg-secondary);
color: var(--color-text-secondary);
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
}
.page-btn:hover {
border-color: #2a5caa;
color: #2a5caa;
border-color: var(--color-primary);
color: var(--color-primary);
}
.page-btn:disabled {
background: #1a1a1a;
color: #999999;
background: var(--color-bg-tertiary);
color: var(--color-text-disabled);
cursor: not-allowed;
border-color: rgba(255, 255, 255, 0.2);
border-color: var(--color-border-secondary);
}
.page-info {
color: #cccccc;
color: var(--color-text-secondary);
font-size: 12px;
font-weight: 500;
}
@ -515,8 +515,8 @@
.stat-card {
padding: 15px;
background: #2a2a2a;
border: 1px solid rgba(255, 255, 255, 0.2);
background: var(--color-bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: 8px;
text-align: center;
}
@ -525,23 +525,23 @@
display: block;
font-size: 24px;
font-weight: bold;
color: #2a5caa;
color: var(--color-primary);
margin-bottom: 5px;
}
.stat-label {
color: #cccccc;
color: var(--color-text-secondary);
font-size: 12px;
font-weight: 500;
}
.operation-types {
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.2);
border-top: 1px solid var(--color-border-secondary);
}
.operation-types h5 {
color: #ffffff;
color: var(--color-text-primary);
font-size: 13px;
font-weight: 600;
margin: 0 0 10px 0;
@ -555,10 +555,10 @@
.type-tag {
padding: 4px 8px;
background: #2a2a2a;
border: 1px solid rgba(255, 255, 255, 0.2);
background: var(--color-bg-secondary);
border: 1px solid var(--color-border-secondary);
border-radius: 4px;
color: #cccccc;
color: var(--color-text-secondary);
font-size: 11px;
font-weight: 500;
}
@ -566,8 +566,8 @@
/* 响应式设计 */
@media (max-width: 1200px) {
.management-panel {
width: 350px;
right: -350px;
width: var(--size-info-panel-width-tablet);
right: calc(-1 * var(--size-info-panel-width-tablet));
}
.stats-grid {
@ -588,8 +588,8 @@
@media (max-width: 768px) {
.management-panel {
width: 100vw;
right: -100vw;
width: var(--size-screen-width);
right: calc(-1 * var(--size-screen-width));
}
.panel-header {

View File

@ -88,13 +88,135 @@
--color-complexity-border-3: rgba(var(--color-complexity-base), 0.3);
--color-complexity-border-15: rgba(var(--color-complexity-base), 0.15);
/* Revit建筑设计主题色 */
--color-revit-base: 46, 139, 87; /* #2E8B57 */
--color-revit: rgb(var(--color-revit-base));
--color-revit-light-base: 32, 178, 170; /* #20B2AA */
--color-revit-light: rgb(var(--color-revit-light-base));
--color-revit-gradient: linear-gradient(135deg, rgb(var(--color-revit-base)) 0%, rgb(var(--color-revit-light-base)) 100%);
--color-revit-bg-1: rgba(var(--color-revit-base), 0.05);
--color-revit-bg-2: rgba(var(--color-revit-base), 0.08);
--color-revit-bg-3: rgba(var(--color-revit-base), 0.1);
--color-revit-shadow: rgba(var(--color-revit-base), 0.3);
/* Revit建筑元素专用颜色 */
--color-revit-walls-base: 139, 69, 19; /* #8B4513 */
--color-revit-walls: rgb(var(--color-revit-walls-base));
--color-revit-walls-bg: rgba(var(--color-revit-walls-base), 0.1);
--color-revit-doors-base: 255, 165, 0; /* #FFA500 */
--color-revit-doors: rgb(var(--color-revit-doors-base));
--color-revit-doors-bg: rgba(var(--color-revit-doors-base), 0.1);
--color-revit-windows-base: 135, 206, 250; /* #87CEEB */
--color-revit-windows: rgb(var(--color-revit-windows-base));
--color-revit-windows-bg: rgba(var(--color-revit-windows-base), 0.1);
--color-revit-floors-base: 105, 105, 105; /* #696969 */
--color-revit-floors: rgb(var(--color-revit-floors-base));
--color-revit-floors-bg: rgba(var(--color-revit-floors-base), 0.1);
--color-revit-ceilings-base: 220, 220, 220; /* #DCDCDC */
--color-revit-ceilings: rgb(var(--color-revit-ceilings-base));
--color-revit-ceilings-bg: rgba(var(--color-revit-ceilings-base), 0.1);
--color-revit-columns-base: 47, 79, 79; /* #2F4F4F */
--color-revit-columns: rgb(var(--color-revit-columns-base));
--color-revit-columns-bg: rgba(var(--color-revit-columns-base), 0.1);
--color-revit-beams-base: 160, 82, 45; /* #A0522D */
--color-revit-beams: rgb(var(--color-revit-beams-base));
--color-revit-beams-bg: rgba(var(--color-revit-beams-base), 0.1);
--color-revit-rooms-base: 221, 160, 221; /* #DDA0DD */
--color-revit-rooms: rgb(var(--color-revit-rooms-base));
--color-revit-rooms-bg: rgba(var(--color-revit-rooms-base), 0.1);
--color-revit-stairs-base: 70, 130, 180; /* #4682B4 */
--color-revit-stairs: rgb(var(--color-revit-stairs-base));
--color-revit-stairs-bg: rgba(var(--color-revit-stairs-base), 0.1);
--color-revit-railings-base: 64, 64, 64; /* #404040 */
--color-revit-railings: rgb(var(--color-revit-railings-base));
--color-revit-railings-bg: rgba(var(--color-revit-railings-base), 0.1);
/* PDMS工厂设计主题色 */
--color-pdms-base: 255, 107, 53; /* #FF6B35 */
--color-pdms: rgb(var(--color-pdms-base));
--color-pdms-light-base: 247, 147, 30; /* #F7931E */
--color-pdms-light: rgb(var(--color-pdms-light-base));
--color-pdms-gradient: linear-gradient(135deg, rgb(var(--color-pdms-base)) 0%, rgb(var(--color-pdms-light-base)) 100%);
--color-pdms-bg-1: rgba(var(--color-pdms-base), 0.05);
--color-pdms-bg-2: rgba(var(--color-pdms-base), 0.08);
--color-pdms-bg-3: rgba(var(--color-pdms-base), 0.1);
--color-pdms-shadow: rgba(var(--color-pdms-base), 0.3);
/* PDMS工厂元素专用颜色 */
--color-pdms-pipe-base: 59, 130, 246; /* #3B82F6 */
--color-pdms-pipe: rgb(var(--color-pdms-pipe-base));
--color-pdms-pipe-bg: rgba(var(--color-pdms-pipe-base), 0.1);
--color-pdms-elbo-base: 139, 69, 19; /* #8B4513 */
--color-pdms-elbo: rgb(var(--color-pdms-elbo-base));
--color-pdms-elbo-bg: rgba(var(--color-pdms-elbo-base), 0.1);
--color-pdms-valve-base: 220, 38, 127; /* #DC267F */
--color-pdms-valve: rgb(var(--color-pdms-valve-base));
--color-pdms-valve-bg: rgba(var(--color-pdms-valve-base), 0.1);
--color-pdms-fitting-base: 168, 85, 247; /* #A855F7 */
--color-pdms-fitting: rgb(var(--color-pdms-fitting-base));
--color-pdms-fitting-bg: rgba(var(--color-pdms-fitting-base), 0.1);
--color-pdms-equipment-base: 34, 197, 94; /* #22C55E */
--color-pdms-equipment: rgb(var(--color-pdms-equipment-base));
--color-pdms-equipment-bg: rgba(var(--color-pdms-equipment-base), 0.1);
--color-pdms-structure-base: 156, 163, 175; /* #9CA3AF */
--color-pdms-structure: rgb(var(--color-pdms-structure-base));
--color-pdms-structure-bg: rgba(var(--color-pdms-structure-base), 0.1);
/* 复杂度分析状态颜色 */
--color-complexity-low-base: 40, 167, 69; /* #28a745 */
--color-complexity-low: rgb(var(--color-complexity-low-base));
--color-complexity-medium-base: 255, 193, 7; /* #ffc107 */
--color-complexity-medium: rgb(var(--color-complexity-medium-base));
--color-complexity-high-base: 220, 53, 69; /* #dc3545 */
--color-complexity-high: rgb(var(--color-complexity-high-base));
--color-complexity-critical-base: 139, 0, 0; /* #8B0000 */
--color-complexity-critical: rgb(var(--color-complexity-critical-base));
--color-complexity-excellent-base: 34, 139, 34; /* #228B22 */
--color-complexity-excellent: rgb(var(--color-complexity-excellent-base));
--color-complexity-high-gradient: linear-gradient(135deg, rgb(var(--color-complexity-high-base)), rgb(200, 35, 51));
--color-complexity-high-gradient-hover: linear-gradient(135deg, rgb(200, 35, 51), rgb(167, 30, 42));
/* 复杂度分析背景色 */
--color-complexity-low-bg: rgba(var(--color-complexity-low-base), 0.1);
--color-complexity-medium-bg: rgba(var(--color-complexity-medium-base), 0.1);
--color-complexity-high-bg: rgba(var(--color-complexity-high-base), 0.1);
--color-complexity-critical-bg: rgba(var(--color-complexity-critical-base), 0.1);
--color-complexity-excellent-bg: rgba(var(--color-complexity-excellent-base), 0.1);
/* Creo模型分析工具渐变色 */
--color-creo-analysis-gradient-1: linear-gradient(135deg, rgb(111, 66, 193), rgb(232, 62, 140));
--color-creo-analysis-gradient-2: linear-gradient(135deg, rgb(23, 162, 184), rgb(19, 132, 150));
--color-creo-analysis-gradient-3: linear-gradient(135deg, rgb(40, 167, 69), rgb(32, 201, 151));
--color-creo-analysis-gradient-4: linear-gradient(135deg, rgb(253, 126, 20), rgb(232, 62, 140));
--color-creo-analysis-gradient-5: linear-gradient(135deg, rgb(220, 53, 69), rgb(200, 35, 51));
/* 通用灰色渐变 */
--color-gradient-gray: linear-gradient(135deg, rgb(102, 102, 102) 0%, rgb(85, 85, 85) 100%);
/* ===== 优化透明度层级系统 ===== */
/* 通用透明度常量 */
--opacity-light: 0.1;
--opacity-medium: 0.3;
--opacity-strong: 0.5;
/* 主色调透明度变体 */
--color-primary-rgb: rgba(var(--color-primary-base), 0.1);
--color-primary-rgb-3: rgba(var(--color-primary-base), 0.3);
--color-primary-rgb-4: rgba(var(--color-primary-base), 0.4);
/* 成功色透明度变体 */
--success-color-rgb: var(--color-success-base);
--color-success-rgb-1: rgba(var(--color-success-base), 0.1);
--color-success-rgb-3: rgba(var(--color-success-base), 0.3);
--color-success-rgb-5: rgba(var(--color-success-base), 0.5);
/* 橙色系透明度变体 */
--color-orange-base: 255, 152, 0; /* #FF9800 */
--color-orange: rgb(var(--color-orange-base));
--color-orange-rgb-1: rgba(var(--color-orange-base), 0.1);
--color-orange-rgb-3: rgba(var(--color-orange-base), 0.3);
/* 状态色透明度变体 */
--color-error-rgb-1: rgba(var(--color-error-base), 0.1);
--color-error-rgb-3: rgba(var(--color-error-base), 0.3);
@ -113,10 +235,44 @@
--color-gradient-info: linear-gradient(135deg, rgba(var(--color-info-base), 0.1) 0%, rgba(var(--color-info-base), 0.05) 100%);
--color-gradient-warning: linear-gradient(135deg, rgba(var(--color-warning-base), 0.1) 0%, rgba(var(--color-warning-base), 0.05) 100%);
/* 按钮渐变(不透明) */
--color-btn-success: linear-gradient(135deg, rgb(var(--color-success-base)) 0%, rgb(76, 175, 80) 100%);
--color-btn-success-hover: linear-gradient(135deg, rgb(102, 187, 106) 0%, rgb(129, 199, 132) 100%);
--color-btn-error: linear-gradient(135deg, rgb(var(--color-error-base)) 0%, rgb(239, 83, 80) 100%);
--color-btn-error-hover: linear-gradient(135deg, rgb(239, 83, 80) 0%, rgb(229, 115, 115) 100%);
--color-btn-warning: linear-gradient(135deg, rgb(var(--color-warning-base)) 0%, rgb(255, 183, 77) 100%);
--color-btn-warning-hover: linear-gradient(135deg, rgb(255, 183, 77) 0%, rgb(255, 204, 2) 100%);
--color-btn-info: linear-gradient(135deg, rgb(var(--color-info-base)) 0%, rgb(66, 165, 245) 100%);
--color-btn-info-hover: linear-gradient(135deg, rgb(66, 165, 245) 0%, rgb(100, 181, 246) 100%);
/* 阴影色 - 指向已有变量避免重复 */
--color-shadow-primary: var(--color-primary-rgb-3);
--color-shadow-hover: var(--color-primary-rgb-4);
--color-shadow-card: 0 20px 40px rgba(var(--color-black-base), 0.3);
--color-shadow-black-1: rgba(var(--color-black-base), 0.1);
--color-shadow-black-3: rgba(var(--color-black-base), 0.3);
/* 按钮阴影 */
--color-shadow-btn: 0 2px 4px rgba(var(--color-black-base), 0.1);
--color-shadow-btn-success: 0 4px 8px rgba(var(--color-success-base), 0.3);
--color-shadow-btn-error: 0 4px 8px rgba(var(--color-error-base), 0.3);
--color-shadow-btn-warning: 0 4px 8px rgba(var(--color-warning-base), 0.3);
--color-shadow-btn-info: 0 4px 8px rgba(var(--color-info-base), 0.3);
/* 通用阴影层级 */
--color-shadow-black-2: rgba(var(--color-black-base), 0.2);
--color-shadow-lg: 0 8px 32px rgba(var(--color-black-base), 0.3);
--color-shadow-md: 0 6px 20px rgba(var(--color-black-base), 0.2);
--color-shadow-sm: 0 2px 8px rgba(var(--color-black-base), 0.3);
/* Revit专业阴影色 */
--color-shadow-revit: 0 8px 32px rgba(var(--color-black-base), 0.3);
--color-shadow-revit-light: 0 6px 20px rgba(var(--color-black-base), 0.2);
--color-shadow-revit-btn: 0 4px 12px rgba(var(--color-revit-base), 0.3);
--color-shadow-revit-btn-hover: 0 8px 25px rgba(var(--color-revit-base), 0.4);
/* 成功色扩展变体 */
--color-success-shadow: 0 2px 8px rgba(var(--color-success-base), 0.3);
/* 滚动条 */
--color-scrollbar-thumb: var(--color-white-rgb-2);
@ -137,13 +293,19 @@
--size-border-radius-card: 12px;
--size-border-radius-button: 6px;
/* 信息管理面板尺寸 */
--size-info-panel-width: 400px;
--size-info-panel-width-tablet: 350px;
--size-info-panel-header-height: 60px;
/* 连接组件尺寸 */
--size-connection-dot: 8px;
--size-connection-card-min-height: 120px;
--size-connection-test-btn: 24px;
--size-connection-test-btn-small: 20px;
/* 间距系统 */
/* 间距系统 - 扩展到覆盖所有常用尺寸 */
--spacing-xxs: 2px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 12px;
@ -151,6 +313,42 @@
--spacing-xl: 20px;
--spacing-2xl: 24px;
--spacing-3xl: 32px;
--spacing-4xl: 40px;
--spacing-5xl: 48px;
--spacing-6xl: 60px;
/* 常用固定尺寸 */
--size-1: 1px;
--size-2: 2px;
--size-3: 3px;
--size-4: 4px;
--size-6: 6px;
--size-8: 8px;
--size-10: 10px;
--size-12: 12px;
--size-14: 14px;
--size-15: 15px;
--size-16: 16px;
--size-18: 18px;
--size-20: 20px;
--size-24: 24px;
--size-28: 28px;
--size-30: 30px;
--size-32: 32px;
--size-36: 36px;
--size-40: 40px;
--size-44: 44px;
--size-48: 48px;
--size-52: 52px;
--size-56: 56px;
--size-60: 60px;
--size-64: 64px;
--size-80: 80px;
--size-96: 96px;
--size-120: 120px;
--size-140: 140px;
--size-150: 150px;
--size-200: 200px;
/* 组件特定间距 */
--spacing-connection-dot: 8px;
@ -159,14 +357,39 @@
--spacing-grid-gap: 10px;
--spacing-form-gap: 8px;
/* 边框尺寸 */
--border-width-thin: 1px;
--border-width-medium: 2px;
--border-width-thick: 3px;
/* 响应式断点 */
--breakpoint-mobile: 480px;
--breakpoint-tablet: 768px;
--breakpoint-desktop: 1024px;
--breakpoint-large: 1440px;
/* 图标尺寸系统 */
--icon-size-xs: 12px;
--icon-size-sm: 14px;
--icon-size-md: 16px;
--icon-size-lg: 20px;
--icon-size-xl: 24px;
--icon-size-2xl: 28px;
--icon-size-3xl: 32px;
/* 字体大小 */
--font-size-xs: 12px;
--font-size-sm: 13px;
--font-size-base: 14px;
--font-size-md: 15px;
--font-size-lg: 16px;
--font-size-xl: 18px;
--font-size-2xl: 20px;
--font-size-3xl: 24px;
--font-size-4xl: 28px;
--font-size-5xl: 32px;
--font-size-6xl: 48px;
--font-size-7xl: 64px;
/* 组件特定字体大小 */
--font-size-icon: 24px;
@ -188,9 +411,70 @@
/* ===== 动画系统 ===== */
--transition-duration: 0.3s;
--transition-duration-fast: 0.15s;
--transition-duration-slow: 0.4s;
--transition-timing: ease;
--transition-timing-smooth: cubic-bezier(0.4, 0, 0.2, 1);
/* 完整过渡样式 */
--transition-all: all var(--transition-duration) var(--transition-timing);
--transition-all-smooth: all var(--transition-duration) var(--transition-timing-smooth);
/* ===== 组件尺寸常量 ===== */
/* 登录界面常量 */
--login-animation-large: 200px;
--login-animation-medium: 150px;
--login-animation-small: 100px;
--login-card-max-width: 420px;
--login-card-padding: 40px;
--login-card-padding-small: 20px;
--login-card-border-radius: 16px;
--login-icon-size: 60px;
--login-title-size: 24px;
--login-subtitle-size: 20px;
--login-text-size: 14px;
--login-button-text-size: 18px;
/* 登录界面动画常量 */
--login-float-distance: -20px;
--login-float-duration: 6s;
--login-animation-delay-1: 0s;
--login-animation-delay-2: 2s;
--login-animation-delay-3: 4s;
/* 登录界面位置常量 */
--login-circle-1-top: 10%;
--login-circle-1-left: 10%;
--login-circle-2-top: 60%;
--login-circle-2-right: 15%;
--login-circle-3-bottom: 20%;
--login-circle-3-left: 20%;
/* 登录界面背景色 */
--color-bg-dark-95: rgba(var(--color-bg-secondary-base), 0.95);
/* 登录界面间距常量 */
--login-brand-margin-bottom: 40px;
--login-form-title-margin-bottom: 30px;
--login-form-group-margin-bottom: 20px;
--login-form-options-margin-bottom: 30px;
--login-help-margin-top: 20px;
--login-brand-logo-margin-bottom: 16px;
--login-brand-title-margin-bottom: 8px;
--login-error-margin-bottom: 20px;
--login-form-label-margin-bottom: 8px;
--login-field-error-margin-top: 4px;
/* 登录界面按钮常量 */
--login-button-padding: 14px;
--login-button-transform: translateY(-2px);
--login-button-disabled-opacity: 0.7;
/* 登录界面字体大小(响应式) */
--login-title-size-mobile: 18px;
--login-content-padding-mobile: 16px;
--login-card-padding-mobile: 30px 24px;
/* 模型查看器常量 */
--model-viewer-padding: 20px;
--model-viewer-border-radius: 8px;
@ -199,6 +483,10 @@
--model-viewer-section-margin: 24px;
--model-viewer-section-padding: 16px;
/* 表单输入常量 */
--input-padding-vertical: 12px;
--input-padding-horizontal: 16px;
/* 通知持续时间常量 */
--notification-duration-success: 2000ms;
--notification-duration-error: 3000ms;
@ -394,11 +682,26 @@ html, body {
/* 布局工具类 */
.flex { display: flex; }
.flex-col { flex-direction: column; }
.flex-row { flex-direction: row; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-end { align-items: flex-end; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-start { justify-content: flex-start; }
.justify-end { justify-content: flex-end; }
.justify-around { justify-content: space-around; }
.flex-1 { flex: 1; }
.flex-shrink-0 { flex-shrink: 0; }
.flex-wrap { flex-wrap: wrap; }
.flex-nowrap { flex-wrap: nowrap; }
/* 常用组合布局类 */
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-center-between { display: flex; align-items: center; justify-content: space-between; }
.flex-center-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-center-end { display: flex; align-items: center; justify-content: flex-end; }
.flex-col-center { display: flex; flex-direction: column; align-items: center; justify-content: center; }
.h-full { height: 100%; }
.w-full { width: 100%; }
@ -460,6 +763,37 @@ html, body {
border-color: var(--color-white-rgb-15);
}
/* 常用按钮样式工具类 */
.btn-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border: none;
border-radius: var(--size-border-radius-button);
background: var(--color-bg-hover);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-all);
}
.btn-icon:hover {
background: var(--color-primary);
color: var(--color-text-primary);
transform: translateY(-1px);
}
/* 常用卡片样式 */
.card-hover {
transition: var(--transition-all);
}
.card-hover:hover {
transform: translateY(-2px);
box-shadow: var(--color-shadow-card), 0 8px 25px var(--color-shadow-hover);
}
/* ===== 自定义Loading样式 ===== */
.custom-loading .el-loading-text {
color: rgba(var(--color-white-base), 0.9) !important;

View File

@ -137,10 +137,10 @@ const handleLogout = () => {
display: flex;
align-items: center;
justify-content: space-between;
height: 60px;
height: var(--size-header-height);
background: var(--color-bg-primary);
border-bottom: 1px solid var(--color-border-primary);
padding: 0 20px;
padding: 0 var(--spacing-xl);
position: relative;
z-index: var(--z-index-header);
}
@ -153,14 +153,14 @@ const handleLogout = () => {
.logo {
display: flex;
align-items: center;
gap: 12px;
gap: var(--spacing-md);
color: var(--color-text-primary);
font-weight: 600;
font-size: 16px;
font-size: var(--font-size-lg);
}
.logo i {
font-size: 24px;
font-size: var(--icon-size-xl);
color: var(--color-primary);
}
@ -171,19 +171,19 @@ const handleLogout = () => {
.main-nav {
display: flex;
gap: 8px;
gap: var(--spacing-sm);
}
.nav-item {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
gap: var(--spacing-sm);
padding: var(--spacing-grid-gap) var(--spacing-lg);
color: var(--color-text-secondary);
text-decoration: none;
border-radius: 6px;
transition: all 0.3s ease;
font-size: 14px;
border-radius: var(--size-border-radius-button);
transition: var(--transition-all);
font-size: var(--font-size-base);
font-weight: 500;
border: none;
background: transparent;
@ -212,13 +212,13 @@ const handleLogout = () => {
}
.nav-item i {
font-size: 14px;
font-size: var(--font-size-base);
}
.navbar-right {
display: flex;
align-items: center;
gap: 16px;
gap: var(--spacing-lg);
}
.notification-center {
@ -226,12 +226,12 @@ const handleLogout = () => {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
width: var(--spacing-4xl);
height: var(--spacing-4xl);
background: var(--color-white-rgb-1);
border-radius: 6px;
border-radius: var(--size-border-radius-button);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.notification-center:hover {
@ -240,7 +240,7 @@ const handleLogout = () => {
.notification-center i {
color: var(--color-text-secondary);
font-size: 16px;
font-size: var(--icon-size-md);
}
.badge {
@ -249,22 +249,22 @@ const handleLogout = () => {
right: -5px;
background: var(--color-error);
color: white;
font-size: 10px;
padding: 2px 6px;
border-radius: 10px;
min-width: 16px;
font-size: var(--font-size-icon-small);
padding: var(--size-2) var(--size-6);
border-radius: var(--size-10);
min-width: var(--size-16);
text-align: center;
}
.user-menu {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
background: var(--color-white-rgb-1);
border-radius: 6px;
border-radius: var(--size-border-radius-button);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
position: relative;
}
@ -273,14 +273,14 @@ const handleLogout = () => {
}
.user-avatar {
width: 24px;
height: 24px;
width: var(--icon-size-xl);
height: var(--icon-size-xl);
border-radius: 50%;
}
.username {
color: var(--color-text-primary);
font-size: 14px;
font-size: var(--font-size-base);
font-weight: 500;
}
@ -298,24 +298,24 @@ const handleLogout = () => {
position: absolute;
top: 100%;
right: 0;
margin-top: 8px;
margin-top: var(--spacing-sm);
background: var(--color-bg-primary);
border: 1px solid var(--color-border-primary);
border-radius: 8px;
border-radius: var(--size-border-radius);
box-shadow: 0 4px 20px var(--color-shadow-black-1);
min-width: 140px;
min-width: var(--size-140);
z-index: 1000;
}
.dropdown-item {
display: flex;
align-items: center;
gap: 8px;
gap: var(--spacing-sm);
padding: 12px 16px;
color: var(--color-text-primary);
cursor: pointer;
transition: background-color 0.3s ease;
font-size: 14px;
font-size: var(--font-size-base);
}
.dropdown-item:hover {
@ -331,11 +331,11 @@ const handleLogout = () => {
}
.dropdown-item:only-child {
border-radius: 8px;
border-radius: var(--size-border-radius);
}
.dropdown-item i {
font-size: 14px;
font-size: var(--font-size-base);
color: var(--color-text-secondary);
}
@ -343,12 +343,12 @@ const handleLogout = () => {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
width: var(--spacing-4xl);
height: var(--spacing-4xl);
background: var(--color-white-rgb-1);
border-radius: 6px;
border-radius: var(--size-border-radius-button);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.system-settings:hover {
@ -357,22 +357,22 @@ const handleLogout = () => {
.system-settings i {
color: var(--color-text-secondary);
font-size: 16px;
font-size: var(--icon-size-md);
}
/* 响应式设计 */
@media (max-width: 768px) {
@media (max-width: var(--breakpoint-tablet)) {
.main-nav {
gap: 4px;
gap: var(--spacing-xs);
}
.nav-item {
padding: 8px 12px;
font-size: 13px;
padding: var(--spacing-sm) var(--spacing-md);
font-size: var(--font-size-sm);
}
.navbar-right {
gap: 12px;
gap: var(--spacing-md);
}
}
@ -382,7 +382,7 @@ const handleLogout = () => {
}
.logo span {
font-size: 14px;
font-size: var(--font-size-base);
}
}
</style>

View File

@ -69,6 +69,10 @@ import creoApi from '@/services/creoApi'
import revitApi from '@/services/revitApi'
import pdmsApi from '@/services/pdmsApi'
import { ElNotification, ElMessageBox } from 'element-plus'
import { getNotificationConfig } from '@/config/cad'
//
const notificationConfig = getNotificationConfig()
//
const emit = defineEmits(['show-model-viewer'])
@ -130,7 +134,7 @@ const handleOpenModel = async () => {
message: '请先连接CAD软件',
type: 'warning',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
return
}
@ -202,24 +206,24 @@ const handleOpenModel = async () => {
background: var(--color-bg-primary);
color: var(--color-text-primary);
overflow-y: auto;
padding: 20px;
gap: 24px;
padding: var(--spacing-xl);
gap: var(--spacing-2xl);
}
/* CAD软件选择器 */
.software-selector {
background: var(--color-bg-card);
border-radius: 8px;
padding: 20px;
border: 1px solid var(--color-border-primary);
border-radius: var(--size-border-radius);
padding: var(--spacing-xl);
border: var(--border-width-thin) solid var(--color-border-primary);
}
.selector-title {
display: flex;
align-items: center;
gap: 8px;
margin: 0 0 16px 0;
font-size: 16px;
gap: var(--spacing-sm);
margin: 0 0 var(--spacing-lg) 0;
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--color-text-primary);
}
@ -232,11 +236,11 @@ const handleOpenModel = async () => {
.selected-software {
display: flex;
align-items: center;
gap: 8px;
padding: 12px;
gap: var(--spacing-sm);
padding: var(--spacing-md);
background: var(--color-white-rgb-05);
border-radius: 6px;
font-size: 14px;
border-radius: var(--size-border-radius-button);
font-size: var(--font-size-base);
}
.selected-label {
@ -252,17 +256,17 @@ const handleOpenModel = async () => {
/* 模型管理面板 */
.panel-section {
background: var(--color-bg-card);
border-radius: 8px;
padding: 20px;
border: 1px solid var(--color-border-primary);
border-radius: var(--size-border-radius);
padding: var(--spacing-xl);
border: var(--border-width-thin) solid var(--color-border-primary);
}
.section-title {
display: flex;
align-items: center;
gap: 8px;
margin: 0 0 16px 0;
font-size: 16px;
gap: var(--spacing-sm);
margin: 0 0 var(--spacing-lg) 0;
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--color-text-primary);
}
@ -274,9 +278,9 @@ const handleOpenModel = async () => {
.selection-title {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-size: 14px;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-md);
font-size: var(--font-size-base);
font-weight: 500;
color: var(--color-text-primary);
}
@ -288,19 +292,19 @@ const handleOpenModel = async () => {
.selection-options {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 16px;
gap: var(--spacing-sm);
margin-bottom: var(--spacing-lg);
}
.option-item {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 12px;
gap: var(--spacing-md);
padding: var(--spacing-md);
background: var(--color-white-rgb-05);
border-radius: 6px;
border-radius: var(--size-border-radius-button);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.option-item:hover {
@ -308,7 +312,7 @@ const handleOpenModel = async () => {
}
.option-item input[type="radio"] {
margin-top: 2px;
margin-top: var(--size-2);
}
.option-content {
@ -317,39 +321,39 @@ const handleOpenModel = async () => {
.option-content i {
color: var(--color-primary);
margin-right: 8px;
margin-right: var(--spacing-sm);
}
.option-content span {
display: block;
color: var(--color-text-primary);
font-weight: 500;
margin-bottom: 4px;
margin-bottom: var(--spacing-xs);
}
.option-content small {
color: var(--color-text-secondary);
font-size: 12px;
font-size: var(--font-size-xs);
}
.project-actions {
display: flex;
gap: 8px;
gap: var(--spacing-sm);
}
.confirm-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
gap: var(--spacing-sm);
padding: var(--spacing-grid-gap) var(--spacing-lg);
background: var(--color-primary);
color: white;
border: none;
border-radius: 6px;
font-size: 14px;
border-radius: var(--size-border-radius-button);
font-size: var(--font-size-base);
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.confirm-btn:hover {
@ -358,12 +362,12 @@ const handleOpenModel = async () => {
}
.confirm-btn i {
font-size: 14px;
font-size: var(--font-size-base);
}
/* 滚动条样式 */
.side-panel::-webkit-scrollbar {
width: 6px;
width: var(--size-6);
}
.side-panel::-webkit-scrollbar-track {
@ -372,7 +376,7 @@ const handleOpenModel = async () => {
.side-panel::-webkit-scrollbar-thumb {
background: var(--color-white-rgb-2);
border-radius: 3px;
border-radius: var(--size-3);
}
.side-panel::-webkit-scrollbar-thumb:hover {

View File

@ -396,7 +396,7 @@ const basicCheck = () => {
border-radius: 6px;
color: var(--color-text-primary);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
font-size: 14px;
}

View File

@ -137,6 +137,10 @@
<script setup>
import { computed } from 'vue'
import { ElNotification } from 'element-plus'
import { getNotificationConfig } from '@/config/cad'
//
const notificationConfig = getNotificationConfig()
//
const props = defineProps({
@ -236,7 +240,7 @@ const refreshModel = () => {
message: 'PDMS模型信息刷新功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -246,7 +250,7 @@ const captureScreenshot = () => {
message: 'PDMS截图保存功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -256,7 +260,7 @@ const exportProjectInfo = () => {
message: 'PDMS项目信息导出功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -266,7 +270,7 @@ const testConnection = () => {
message: 'PDMS连接测试功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
</script>
@ -301,12 +305,12 @@ const testConnection = () => {
.title-icon.pdms-icon {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #FF6B35 0%, #F7931E 100%);
background: var(--color-pdms-gradient);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(255, 107, 53, 0.3);
box-shadow: 0 4px 12px var(--color-pdms-shadow);
}
.title-icon.pdms-icon i {
@ -360,7 +364,7 @@ const testConnection = () => {
}
.pdms-project-info h3 i {
color: #FF6B35;
color: var(--color-pdms);
}
.info-item {
@ -400,12 +404,12 @@ const testConnection = () => {
padding: 20px;
border: 1px solid var(--color-border-primary);
text-align: center;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.pdms-stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
box-shadow: var(--color-shadow-card);
}
.pdms-stat-card h4 {
@ -420,7 +424,7 @@ const testConnection = () => {
}
.pdms-stat-card h4 i {
color: #FF6B35;
color: var(--color-pdms);
}
.stat-number {
@ -462,7 +466,7 @@ const testConnection = () => {
}
.pdms-elements-breakdown h4 i {
color: #FF6B35;
color: var(--color-pdms);
}
.pdms-element-item {
@ -495,12 +499,12 @@ const testConnection = () => {
font-size: 14px;
}
.pdms-element-icon.pipe { background: rgba(59, 130, 246, 0.1); color: #3B82F6; }
.pdms-element-icon.elbo { background: rgba(139, 69, 19, 0.1); color: #8B4513; }
.pdms-element-icon.valve { background: rgba(220, 38, 127, 0.1); color: #DC267F; }
.pdms-element-icon.fitting { background: rgba(168, 85, 247, 0.1); color: #A855F7; }
.pdms-element-icon.equipment { background: rgba(34, 197, 94, 0.1); color: #22C55E; }
.pdms-element-icon.structure { background: rgba(156, 163, 175, 0.1); color: #9CA3AF; }
.pdms-element-icon.pipe { background: var(--color-pdms-pipe-bg); color: var(--color-pdms-pipe); }
.pdms-element-icon.elbo { background: var(--color-pdms-elbo-bg); color: var(--color-pdms-elbo); }
.pdms-element-icon.valve { background: var(--color-pdms-valve-bg); color: var(--color-pdms-valve); }
.pdms-element-icon.fitting { background: var(--color-pdms-fitting-bg); color: var(--color-pdms-fitting); }
.pdms-element-icon.equipment { background: var(--color-pdms-equipment-bg); color: var(--color-pdms-equipment); }
.pdms-element-icon.structure { background: var(--color-pdms-structure-bg); color: var(--color-pdms-structure); }
.pdms-element-count {
font-weight: 600;
@ -527,7 +531,7 @@ const testConnection = () => {
}
.pdms-zones-panel h4 i {
color: #FF6B35;
color: var(--color-pdms);
}
.zone-summary {
@ -597,7 +601,7 @@ const testConnection = () => {
}
.pdms-session-info h4 i {
color: #FF6B35;
color: var(--color-pdms);
}
.pdms-session-item {
@ -642,7 +646,7 @@ const testConnection = () => {
}
.pdms-actions-panel h4 i {
color: #FF6B35;
color: var(--color-pdms);
}
.pdms-action-btn {
@ -657,18 +661,18 @@ const testConnection = () => {
border-radius: 6px;
color: var(--color-text-primary);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
font-size: 14px;
}
.pdms-action-btn:hover {
background: var(--color-white-rgb-1);
border-color: #FF6B35;
border-color: var(--color-pdms);
transform: translateY(-1px);
}
.pdms-action-btn i {
color: #FF6B35;
color: var(--color-pdms);
font-size: 14px;
}

View File

@ -151,6 +151,10 @@
<script setup>
import { computed } from 'vue'
import { ElNotification } from 'element-plus'
import { getNotificationConfig } from '@/config/cad'
//
const notificationConfig = getNotificationConfig()
// propsAPI
const props = defineProps({
@ -271,7 +275,7 @@ const refreshModel = () => {
message: 'Revit模型信息刷新功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -281,7 +285,7 @@ const captureView = () => {
message: 'Revit视图捕获功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -291,7 +295,7 @@ const exportSchedule = () => {
message: 'Revit明细表导出功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
@ -301,7 +305,7 @@ const testConnection = () => {
message: 'Revit连接测试功能暂未实现',
type: 'info',
position: 'top-right',
duration: 3000
duration: notificationConfig.ERROR_DURATION
})
}
</script>
@ -336,12 +340,12 @@ const testConnection = () => {
.title-icon.revit-icon {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #2E8B57 0%, #20B2AA 100%);
background: var(--color-revit-gradient);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(46, 139, 87, 0.3);
box-shadow: 0 4px 12px var(--color-revit-shadow);
}
.title-icon.revit-icon i {
@ -395,7 +399,7 @@ const testConnection = () => {
}
.revit-project-info h3 i {
color: #2E8B57;
color: var(--color-revit);
}
.info-item {
@ -435,12 +439,12 @@ const testConnection = () => {
padding: 20px;
border: 1px solid var(--color-border-primary);
text-align: center;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.revit-stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
box-shadow: var(--color-shadow-card);
}
.revit-stat-card h4 {
@ -455,7 +459,7 @@ const testConnection = () => {
}
.revit-stat-card h4 i {
color: #2E8B57;
color: var(--color-revit);
}
.stat-number {
@ -497,7 +501,7 @@ const testConnection = () => {
}
.revit-elements-breakdown h4 i {
color: #2E8B57;
color: var(--color-revit);
}
.revit-element-item {
@ -530,16 +534,16 @@ const testConnection = () => {
font-size: 14px;
}
.revit-element-icon.walls { background: rgba(139, 69, 19, 0.1); color: #8B4513; }
.revit-element-icon.doors { background: rgba(255, 165, 0, 0.1); color: #FFA500; }
.revit-element-icon.windows { background: rgba(135, 206, 250, 0.1); color: #87CEEB; }
.revit-element-icon.floors { background: rgba(105, 105, 105, 0.1); color: #696969; }
.revit-element-icon.ceilings { background: rgba(245, 245, 220, 0.1); color: #F5F5DC; }
.revit-element-icon.columns { background: rgba(112, 128, 144, 0.1); color: #708090; }
.revit-element-icon.beams { background: rgba(169, 169, 169, 0.1); color: #A9A9A9; }
.revit-element-icon.rooms { background: rgba(255, 182, 193, 0.1); color: #FFB6C1; }
.revit-element-icon.stairs { background: rgba(205, 133, 63, 0.1); color: #CD853F; }
.revit-element-icon.railings { background: rgba(176, 196, 222, 0.1); color: #B0C4DE; }
.revit-element-icon.walls { background: var(--color-revit-walls-bg); color: var(--color-revit-walls); }
.revit-element-icon.doors { background: var(--color-revit-doors-bg); color: var(--color-revit-doors); }
.revit-element-icon.windows { background: var(--color-revit-windows-bg); color: var(--color-revit-windows); }
.revit-element-icon.floors { background: var(--color-revit-floors-bg); color: var(--color-revit-floors); }
.revit-element-icon.ceilings { background: var(--color-revit-ceilings-bg); color: var(--color-revit-ceilings); }
.revit-element-icon.columns { background: var(--color-revit-columns-bg); color: var(--color-revit-columns); }
.revit-element-icon.beams { background: var(--color-revit-beams-bg); color: var(--color-revit-beams); }
.revit-element-icon.rooms { background: var(--color-revit-rooms-bg); color: var(--color-revit-rooms); }
.revit-element-icon.stairs { background: var(--color-revit-stairs-bg); color: var(--color-revit-stairs); }
.revit-element-icon.railings { background: var(--color-revit-railings-bg); color: var(--color-revit-railings); }
.revit-element-count {
font-weight: 600;
@ -566,7 +570,7 @@ const testConnection = () => {
}
.revit-views-panel h4 i {
color: #2E8B57;
color: var(--color-revit);
}
.view-summary {
@ -597,11 +601,11 @@ const testConnection = () => {
margin-bottom: 6px;
background: var(--color-white-rgb-05);
border-radius: 6px;
border-left: 3px solid #2E8B57;
border-left: 3px solid var(--color-revit);
}
.revit-view-item i {
color: #2E8B57;
color: var(--color-revit);
}
.revit-view-item span {
@ -636,7 +640,7 @@ const testConnection = () => {
}
.revit-links-info h4 i {
color: #2E8B57;
color: var(--color-revit);
}
.revit-link-item {
@ -681,7 +685,7 @@ const testConnection = () => {
}
.revit-actions-panel h4 i {
color: #2E8B57;
color: var(--color-revit);
}
.revit-action-btn {
@ -696,18 +700,18 @@ const testConnection = () => {
border-radius: 6px;
color: var(--color-text-primary);
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
font-size: 14px;
}
.revit-action-btn:hover {
background: var(--color-white-rgb-1);
border-color: #2E8B57;
border-color: var(--color-revit);
transform: translateY(-1px);
}
.revit-action-btn i {
color: #2E8B57;
color: var(--color-revit);
font-size: 14px;
}

View File

@ -238,8 +238,8 @@ const onFormatChange = () => {
align-items: center;
gap: 20px;
padding: 15px;
background: rgba(42, 92, 170, 0.1);
border: 1px solid rgba(42, 92, 170, 0.3);
background: var(--color-primary-rgb);
border: 1px solid var(--color-primary-rgb-3);
border-radius: 10px;
}
@ -422,7 +422,7 @@ const onFormatChange = () => {
overflow: hidden;
background: linear-gradient(135deg, var(--color-success) 0%, var(--color-success) 100%);
border: none;
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
box-shadow: var(--color-shadow-btn-success);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
white-space: nowrap;
min-width: 150px;
@ -431,11 +431,11 @@ const onFormatChange = () => {
.btn-export:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(76, 175, 80, 0.4);
box-shadow: 0 8px 25px var(--color-success-rgb-3);
}
.btn-export:disabled {
background: linear-gradient(135deg, #666 0%, #555 100%);
background: var(--color-gradient-gray);
box-shadow: none;
opacity: 0.7;
}

View File

@ -16,7 +16,7 @@
title="智能薄壳化分析"
description="智能识别内部特征,实现安全的模型轻量化"
icon-class="fas fa-magic"
icon-color="linear-gradient(135deg, #6f42c1, #e83e8c)"
:icon-color="'var(--color-creo-analysis-gradient-1)'"
:features="['内部识别', '安全薄壳', '质量控制', '智能预览']"
@start-analysis="handleShellAnalysis"
/>
@ -27,7 +27,7 @@
title="按层级删除优化"
description="基于特征层级关系的智能删除策略"
icon-class="fas fa-layer-group"
icon-color="linear-gradient(135deg, #17a2b8, #138496)"
:icon-color="'var(--color-creo-analysis-gradient-2)'"
:features="['从顶层开始', '安全删除', '关系分析', '批量操作']"
@start-analysis="handleHierarchyDeletion"
/>
@ -38,7 +38,7 @@
title="几何复杂度分析"
description="分析模型几何复杂度,识别优化目标零件"
icon-class="fas fa-chart-line"
icon-color="linear-gradient(135deg, #28a745, #20c997)"
:icon-color="'var(--color-creo-analysis-gradient-3)'"
:features="['复杂度计算', '零件排序', '智能筛选', '评分系统']"
@start-analysis="handleGeometryComplexity"
/>
@ -49,7 +49,7 @@
title="几何优化分析"
description="优化模型几何结构,减少冗余面和曲线"
icon-class="fas fa-shapes"
icon-color="linear-gradient(135deg, #fd7e14, #e83e8c)"
:icon-color="'var(--color-creo-analysis-gradient-4)'"
:features="['表面简化', '曲线优化', '质量保证', '结构分析']"
@start-analysis="handleGeometryOptimization"
/>
@ -60,7 +60,7 @@
title="批量处理"
description="对多个零件进行批量薄壳化处理"
icon-class="fas fa-tasks"
icon-color="linear-gradient(135deg, #dc3545, #c82333)"
:icon-color="'var(--color-creo-analysis-gradient-5)'"
:features="['多文件', '并行处理', '进度跟踪', '结果汇总']"
button-text="开始处理"
@start-analysis="handleBatchProcessing"
@ -73,11 +73,36 @@
<script setup>
import AnalysisToolCard from '@/components/ui/AnalysisToolCard.vue'
import { creoApi } from '@/services/creoApi'
import { useCADStore } from '@/stores/cad'
import { ElNotification } from 'element-plus'
import { getNotificationConfig } from '@/config/cad'
const emit = defineEmits(['show-shell-analysis-result', 'show-hierarchy-analysis-result', 'show-geometry-complexity-result', 'show-geometry-optimization-params'])
// CAD
const cadStore = useCADStore()
const notificationConfig = getNotificationConfig()
// Creo
const checkCreoConnection = () => {
const creoConnection = cadStore.getCADConnection('creo')
if (!creoConnection || !creoConnection.connected) {
ElNotification({
title: '连接提示',
message: '请先连接Creo软件才能使用分析功能',
type: 'warning',
position: notificationConfig.POSITION,
duration: notificationConfig.ERROR_DURATION
})
return false
}
return true
}
//
const handleShellAnalysis = async () => {
if (!checkCreoConnection()) return
const result = await creoApi.startShellAnalysis()
if (result.success) {
// API
@ -85,21 +110,31 @@ const handleShellAnalysis = async () => {
}
}
const handleHierarchyDeletion = async () => {
if (!checkCreoConnection()) return
const result = await creoApi.startHierarchyAnalysis()
if (result.success) {
emit('show-hierarchy-analysis-result', result.data)
}
}
const handleGeometryComplexity = async () => {
if (!checkCreoConnection()) return
const result = await creoApi.startGeometryComplexityAnalysis()
if (result.success) {
emit('show-geometry-complexity-result', result.data.data)
}
}
const handleGeometryOptimization = () => {
if (!checkCreoConnection()) return
emit('show-geometry-optimization-params')
}
const handleBatchProcessing = () => {}
const handleBatchProcessing = () => {
if (!checkCreoConnection()) return
// TODO:
}
</script>
<style scoped>

View File

@ -362,7 +362,7 @@ onMounted(() => {
}
.stat-card {
background: rgba(255, 255, 255, 0.05);
background: var(--color-white-rgb-05);
border: 1px solid var(--color-complexity-border-15);
border-radius: var(--size-border-radius);
padding: var(--spacing-md);
@ -461,7 +461,7 @@ onMounted(() => {
position: sticky;
top: 0;
z-index: 10;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
box-shadow: var(--color-shadow-btn);
}
.complexity-parts-table td {
@ -499,7 +499,7 @@ onMounted(() => {
}
.complexity-part-path {
color: #28a745;
color: var(--color-complexity-low);
font-size: var(--font-size-xs);
font-family: 'Courier New', monospace;
opacity: 0.8;
@ -520,30 +520,30 @@ onMounted(() => {
}
.complexity-score.very-high {
background: rgba(139, 0, 0, 0.1);
color: #8B0000;
background: var(--color-complexity-critical-bg);
color: var(--color-complexity-critical);
font-weight: var(--font-weight-bold);
}
.complexity-score.high {
background: rgba(220, 53, 69, 0.1);
color: #dc3545;
background: var(--color-complexity-high-bg);
color: var(--color-complexity-high);
font-weight: var(--font-weight-semibold);
}
.complexity-score.medium {
background: rgba(255, 193, 7, 0.1);
color: #ffc107;
background: var(--color-complexity-medium-bg);
color: var(--color-complexity-medium);
}
.complexity-score.low {
background: rgba(40, 167, 69, 0.1);
color: #28a745;
background: var(--color-complexity-low-bg);
color: var(--color-complexity-low);
}
.complexity-score.very-low {
background: rgba(34, 139, 34, 0.1);
color: #228B22;
background: var(--color-complexity-excellent-bg);
color: var(--color-complexity-excellent);
}
/* 删除操作区域 */
@ -591,7 +591,7 @@ onMounted(() => {
}
.complexity-delete-btn {
background: linear-gradient(135deg, #dc3545, #c82333);
background: var(--color-complexity-high-gradient);
border: none;
color: white;
padding: var(--spacing-sm) var(--spacing-lg);
@ -603,17 +603,17 @@ onMounted(() => {
align-items: center;
gap: var(--spacing-sm);
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
box-shadow: 0 2px 8px var(--color-primary-rgb-3);
}
.complexity-delete-btn:hover:not(:disabled) {
background: linear-gradient(135deg, #c82333, #a71e2a);
background: var(--color-complexity-high-gradient-hover);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(220, 53, 69, 0.4);
box-shadow: 0 4px 12px var(--color-primary-rgb-4);
}
.complexity-delete-btn:disabled {
background: rgba(108, 117, 125, 0.5);
background: var(--color-white-rgb-3);
cursor: not-allowed;
box-shadow: none;
transform: none;

View File

@ -328,7 +328,7 @@ const startOptimization = async () => {
/* 参数分组样式 */
.params-section {
background: rgba(255, 255, 255, 0.05);
background: var(--color-white-rgb-05);
border: 1px solid var(--color-border-primary);
border-radius: var(--size-border-radius);
margin-bottom: var(--spacing-lg);

View File

@ -186,8 +186,8 @@ const getMethodName = (method) => {
align-items: center;
gap: var(--spacing-lg);
padding: var(--spacing-lg);
background: rgba(40, 167, 69, 0.1);
border: 1px solid rgba(40, 167, 69, 0.3);
background: var(--color-bg-success);
border: 1px solid var(--color-success-rgb-3);
border-radius: var(--size-border-radius);
margin-bottom: var(--spacing-xl);
}
@ -211,7 +211,7 @@ const getMethodName = (method) => {
/* 结果区块 */
.result-section {
background: rgba(255, 255, 255, 0.05);
background: var(--color-white-rgb-05);
border: 1px solid var(--color-border-primary);
border-radius: var(--size-border-radius);
padding: var(--spacing-xl);

View File

@ -280,23 +280,6 @@ const getSafetyLabel = (safety) => {
return labels[safety] || safety
}
//
const getParentId = (component) => {
// parent_id 使
if (component.parent_id) return component.parent_id
// path
if (component.path) {
const pathParts = component.path.split('/')
if (pathParts.length > 1) {
const parentPath = pathParts.slice(0, -1).join('/')
const parent = hierarchyData.value.find(c => c.path === parentPath)
return parent ? parent.id : null
}
}
return null
}
//
@ -306,7 +289,7 @@ const hasChildren = (component) => {
}
//
const shouldShowNode = (component) => {
const shouldShowNode = () => {
return true
}
@ -346,8 +329,8 @@ const toggleNode = async (component, index) => {
hierarchyData.value.splice(index + 1, 0, ...processedChildren)
component.expanded = true
}
} catch (error) {
console.error('加载子组件失败:', error)
} catch {
// API
}
}
}
@ -567,7 +550,7 @@ watch(() => props.analysisData, () => {
}
.action-btn.danger:hover:not(:disabled) {
background: #d73757;
background: var(--color-error);
opacity: 0.9;
}

View File

@ -76,6 +76,10 @@ import { ref, computed, onMounted } from 'vue'
import { creoApi } from '@/services/creoApi'
import { ElNotification } from 'element-plus'
import { useCADStore } from '@/stores/cad'
import { getNotificationConfig } from '@/config/cad'
//
const notificationConfig = getNotificationConfig()
// Props - 使
defineProps({
@ -202,7 +206,7 @@ const showDeletionSuccessMessage = (data) => {
title: '层级删除完成',
message: message,
type: 'success',
duration: 5000 // 5
duration: notificationConfig.SUCCESS_LONG_DURATION
})
}

View File

@ -279,8 +279,8 @@ const startAnalysis = async () => {
if (result.success) {
analysisResults.value = result.data.data
}
} catch (error) {
console.error('分析失败:', error)
} catch {
// API
} finally {
isAnalyzing.value = false
}
@ -329,7 +329,7 @@ const restartAnalysis = () => {
padding: 32px;
text-align: center;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
box-shadow: var(--color-shadow-revit);
animation: slideInUp 0.4s ease-out;
}
@ -398,7 +398,7 @@ const restartAnalysis = () => {
border-radius: 16px;
padding: 24px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
box-shadow: var(--color-shadow-revit);
animation: slideInUp 0.4s ease-out;
}
@ -448,7 +448,7 @@ const restartAnalysis = () => {
}
.revit-strategy-card {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, rgba(255, 255, 255, 0.05) 100%);
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-white-rgb-05) 100%);
border: 2px solid transparent;
border-radius: 12px;
padding: 24px;
@ -583,13 +583,13 @@ const restartAnalysis = () => {
}
.revit-analysis-btn.secondary {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, rgba(255, 255, 255, 0.05) 100%);
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-white-rgb-05) 100%);
color: var(--color-text-primary);
border: 1px solid var(--color-border-primary);
}
.revit-analysis-btn.secondary:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
background: linear-gradient(135deg, var(--color-white-rgb-1) 0%, var(--color-white-rgb-05) 100%);
border-color: var(--color-primary);
transform: translateY(-2px);
}
@ -602,7 +602,7 @@ const restartAnalysis = () => {
padding: 32px;
text-align: center;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
box-shadow: var(--color-shadow-revit);
animation: slideInUp 0.4s ease-out;
margin-bottom: 24px;
}
@ -619,7 +619,7 @@ const restartAnalysis = () => {
}
.revit-progress-bar {
background: rgba(255, 255, 255, 0.1);
background: var(--color-white-rgb-1);
border-radius: 12px;
height: 12px;
margin: 24px 0;
@ -642,7 +642,7 @@ const restartAnalysis = () => {
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
background: linear-gradient(90deg, transparent, var(--color-white-rgb-3), transparent);
animation: progressShine 2s infinite;
}
@ -665,7 +665,7 @@ const restartAnalysis = () => {
border-radius: 16px;
padding: 24px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
box-shadow: var(--color-shadow-revit);
animation: slideInUp 0.4s ease-out;
}
@ -689,7 +689,7 @@ const restartAnalysis = () => {
}
.revit-result-metric {
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, rgba(255, 255, 255, 0.05) 100%);
background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-white-rgb-05) 100%);
border: 1px solid var(--color-border-primary);
border-radius: 12px;
padding: 20px;
@ -702,27 +702,27 @@ const restartAnalysis = () => {
.revit-result-metric:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
box-shadow: var(--color-shadow-revit-light);
}
.revit-result-metric.highlight {
border-color: var(--color-primary);
background: linear-gradient(135deg, var(--color-primary-rgb) 0%, rgba(30, 58, 95, 0.1) 100%);
background: linear-gradient(135deg, var(--color-primary-rgb) 0%, rgba(var(--color-primary-dark-base), 0.1) 100%);
}
.revit-result-metric.success {
border-color: var(--color-success);
background: linear-gradient(135deg, rgba(40, 167, 69, 0.1) 0%, rgba(40, 167, 69, 0.05) 100%);
background: var(--color-gradient-success);
}
.revit-result-metric.warning {
border-color: var(--color-warning);
background: linear-gradient(135deg, rgba(255, 193, 7, 0.1) 0%, rgba(255, 193, 7, 0.05) 100%);
background: var(--color-gradient-warning);
}
.revit-result-metric.primary {
border-color: var(--color-info);
background: linear-gradient(135deg, rgba(23, 162, 184, 0.1) 0%, rgba(23, 162, 184, 0.05) 100%);
background: var(--color-gradient-info);
}
.metric-icon {
@ -786,7 +786,7 @@ const restartAnalysis = () => {
}
.categories-table-container {
background: rgba(255, 255, 255, 0.03);
background: var(--color-white-rgb-05);
border-radius: 12px;
overflow: hidden;
border: 1px solid var(--color-border-primary);
@ -799,7 +799,7 @@ const restartAnalysis = () => {
}
.revit-categories-table thead {
background: linear-gradient(135deg, var(--color-primary) 0%, rgba(0, 102, 204, 0.8) 100%);
background: linear-gradient(135deg, var(--color-primary) 0%, rgba(var(--color-primary-base), 0.8) 100%);
}
.revit-categories-table thead th {
@ -816,7 +816,7 @@ const restartAnalysis = () => {
}
.revit-categories-table tbody tr:hover {
background: rgba(255, 255, 255, 0.05);
background: var(--color-white-rgb-05);
}
.revit-categories-table tbody tr:last-child {
@ -864,7 +864,7 @@ const restartAnalysis = () => {
border-radius: 6px;
font-size: 0.8em;
font-weight: 600;
box-shadow: 0 2px 8px rgba(40, 167, 69, 0.3);
box-shadow: var(--color-success-shadow);
}
/* 动画效果 */

View File

@ -244,14 +244,14 @@ const startExport = async () => {
.export-header .header-icon {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #2E8B57 0%, #20B2AA 100%);
background: var(--color-revit-gradient);
border-radius: var(--size-border-radius-card);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-icon);
color: var(--color-text-primary);
box-shadow: 0 4px 12px rgba(46, 139, 87, 0.3);
box-shadow: var(--color-shadow-revit-btn);
}
.export-header .header-text h2 {
@ -277,15 +277,15 @@ const startExport = async () => {
align-items: center;
gap: var(--spacing-xl);
padding: var(--spacing-lg);
background: rgba(46, 139, 87, 0.1);
border: 1px solid rgba(46, 139, 87, 0.3);
background: var(--color-revit-bg-1);
border: 1px solid var(--color-revit-bg-3);
border-radius: var(--size-border-radius);
}
.software-icon-large {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #2E8B57 0%, #20B2AA 100%);
background: var(--color-revit-gradient);
border-radius: var(--size-border-radius-card);
display: flex;
align-items: center;
@ -318,7 +318,7 @@ const startExport = async () => {
}
.no-project {
color: #2E8B57;
color: var(--color-revit);
font-style: italic;
}
@ -341,7 +341,7 @@ const startExport = async () => {
.export-card .card-header i {
font-size: var(--font-size-icon);
color: #2E8B57;
color: var(--color-revit);
}
.export-card .card-header h3 {
@ -390,8 +390,8 @@ const startExport = async () => {
.form-input:focus {
outline: none;
border-color: #2E8B57;
box-shadow: 0 0 0 2px rgba(46, 139, 87, 0.1);
border-color: var(--color-revit);
box-shadow: 0 0 0 2px var(--color-revit-bg-1);
background: var(--color-white-rgb-05);
}
@ -415,13 +415,13 @@ const startExport = async () => {
.option-group select:focus {
outline: none;
border-color: #2E8B57;
box-shadow: 0 0 0 2px rgba(46, 139, 87, 0.1);
border-color: var(--color-revit);
box-shadow: 0 0 0 2px var(--color-revit-bg-1);
}
.option-group input[type="checkbox"] {
margin-right: var(--spacing-sm);
accent-color: #2E8B57;
accent-color: var(--color-revit);
}
.btn {
@ -451,9 +451,9 @@ const startExport = async () => {
.btn-export {
position: relative;
overflow: hidden;
background: linear-gradient(135deg, #2E8B57 0%, #20B2AA 100%);
background: var(--color-revit-gradient);
border: none;
box-shadow: 0 4px 15px rgba(46, 139, 87, 0.3);
box-shadow: 0 4px 15px var(--color-revit-shadow);
transition: all var(--transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
white-space: nowrap;
min-width: 150px;
@ -462,7 +462,7 @@ const startExport = async () => {
.btn-export:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(46, 139, 87, 0.4);
box-shadow: var(--color-shadow-revit-btn-hover);
}
.btn-export:disabled {
@ -487,6 +487,6 @@ const startExport = async () => {
}
.revit-advanced-options .card-header i {
color: #2E8B57;
color: var(--color-revit);
}
</style>

View File

@ -528,7 +528,7 @@ const deleteSelectedComponents = async () => {
border-radius: 12px;
padding: 0;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
box-shadow: var(--color-shadow-btn);
}
.summary-header {
@ -608,7 +608,7 @@ const deleteSelectedComponents = async () => {
border: 1px solid var(--color-white-rgb-1);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
box-shadow: var(--color-shadow-btn);
}
.shell-parts-header {
@ -688,12 +688,12 @@ const deleteSelectedComponents = async () => {
}
.shell-parts-table th {
background: rgba(255, 140, 0, 0.1);
background: var(--color-complexity-bg-1);
color: var(--color-text-primary);
padding: 12px 15px;
text-align: left;
font-weight: 600;
border-bottom: 2px solid rgba(255, 140, 0, 0.2);
border-bottom: 2px solid var(--color-complexity-border-2);
}
.shell-parts-table td {
@ -707,12 +707,12 @@ const deleteSelectedComponents = async () => {
}
.shell-part-row:hover {
background: rgba(255, 140, 0, 0.05);
background: var(--color-complexity-bg-1);
}
.shell-part-row.selected {
background: rgba(255, 140, 0, 0.1);
border-left: 3px solid #FF8C00;
background: var(--color-complexity-bg-1);
border-left: 3px solid var(--color-complexity);
}
.part-name {
@ -769,21 +769,21 @@ const deleteSelectedComponents = async () => {
}
.feasibility-badge.high {
background: rgba(40, 167, 69, 0.1);
color: #28a745;
border: 1px solid rgba(40, 167, 69, 0.3);
background: var(--color-complexity-low-bg);
color: var(--color-complexity-low);
border: 1px solid var(--color-complexity-low);
}
.feasibility-badge.medium {
background: rgba(255, 193, 7, 0.1);
color: #ffc107;
border: 1px solid rgba(255, 193, 7, 0.3);
background: var(--color-complexity-medium-bg);
color: var(--color-complexity-medium);
border: 1px solid var(--color-complexity-medium);
}
.feasibility-badge.low {
background: rgba(220, 53, 69, 0.1);
color: #dc3545;
border: 1px solid rgba(220, 53, 69, 0.3);
background: var(--color-complexity-high-bg);
color: var(--color-complexity-high);
border: 1px solid var(--color-complexity-high);
}
/* 操作区域样式 */

View File

@ -153,7 +153,7 @@ const selectFile = () => {
justify-content: center;
font-size: 28px;
color: white;
box-shadow: 0 4px 16px rgba(var(--color-primary-base), var(--opacity-light));
box-shadow: 0 4px 16px var(--color-primary-rgb);
}
.header-text h2 {
@ -377,13 +377,13 @@ const selectFile = () => {
.action-btn.primary {
background: var(--color-success);
color: white;
box-shadow: 0 4px 16px rgba(var(--success-color-rgb), var(--opacity-light));
box-shadow: 0 4px 16px var(--color-success-rgb-1);
}
.action-btn.primary:hover:not(:disabled) {
background: rgba(var(--success-color-rgb), var(--opacity-strong));
background: var(--color-success-rgb-5);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(var(--success-color-rgb), var(--opacity-medium));
box-shadow: 0 6px 20px var(--color-success-rgb-3);
}
.action-btn.primary:disabled {
@ -461,11 +461,5 @@ const selectFile = () => {
display: none;
}
/* CSS变量定义 */
:root {
--success-color-rgb: 76, 175, 80;
--opacity-light: 0.3;
--opacity-medium: 0.4;
--opacity-strong: 0.9;
}
/* 使用全局CSS变量 - 已在theme.css中统一定义 */
</style>

View File

@ -83,10 +83,10 @@ defineEmits(['start-analysis'])
border: 1px solid var(--color-border-primary);
border-radius: var(--spacing-lg);
overflow: hidden;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
transition: var(--transition-all-smooth);
position: relative;
backdrop-filter: blur(10px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
box-shadow: var(--color-shadow-card);
}
.analysis-tool-card::before {
@ -102,7 +102,7 @@ defineEmits(['start-analysis'])
.analysis-tool-card:hover {
border-color: var(--color-primary);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), 0 0 20px var(--color-shadow-primary);
box-shadow: var(--color-shadow-card), 0 0 20px var(--color-shadow-primary);
transform: translateY(-4px) scale(1.02);
}
@ -168,7 +168,7 @@ defineEmits(['start-analysis'])
left: 2px;
right: 2px;
bottom: 2px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, transparent 50%, rgba(255, 255, 255, 0.05) 100%);
background: linear-gradient(135deg, var(--color-white-rgb-15) 0%, transparent 50%, var(--color-white-rgb-05) 100%);
border-radius: inherit;
pointer-events: none;
}
@ -253,7 +253,7 @@ defineEmits(['start-analysis'])
display: flex;
align-items: center;
gap: var(--spacing-sm);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transition: var(--transition-all-smooth);
box-shadow: 0 6px 20px var(--color-shadow-primary);
position: relative;
overflow: hidden;
@ -267,7 +267,7 @@ defineEmits(['start-analysis'])
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.2) 50%, transparent 100%);
background: linear-gradient(90deg, transparent 0%, var(--color-white-rgb-2) 50%, transparent 100%);
transition: left 0.6s ease;
}

View File

@ -29,6 +29,7 @@ const API_CONFIG = {
POSITION: 'top-right',
SUCCESS_DURATION: 2000, // 成功通知2秒
ERROR_DURATION: 3000, // 错误通知3秒
SUCCESS_LONG_DURATION: 5000, // 重要成功通知5秒
SUCCESS_TITLE: '操作成功',
ERROR_TITLE: '操作失败'
},

View File

@ -4,6 +4,7 @@
import { getDefaultRequestConfig, getNotificationConfig } from '@/config/cad'
import { ElNotification, ElLoading } from 'element-plus'
import websocketService from './websocketService'
import Logger from '@/utils/logger'
// 日志记录系统
class ApiLogger {
@ -58,7 +59,7 @@ class PostProcessManager {
try {
await handler(response, requestContext)
} catch (error) {
console.error('后处理钩子执行失败:', error)
Logger.callbackError('PostProcessHandler', error)
// 不影响主流程,但记录错误
}
}

View File

@ -2,6 +2,7 @@
// 基于参考项目接口格式实现
import { getWebSocketConfig } from '@/config/cad'
import Logger from '@/utils/logger'
class WebSocketService {
constructor() {
@ -85,7 +86,7 @@ class WebSocketService {
this.handleMessage(message)
this.emit('onMessage', message)
} catch (error) {
console.error('解析管理后台消息失败:', error, event.data)
Logger.wsError('解析管理后台消息', error, event.data)
}
}
@ -151,10 +152,10 @@ class WebSocketService {
this.getSoftwareList()
break
case 'error':
console.error('管理后台错误:', message.message)
Logger.wsError('管理后台', message.message)
break
default:
console.log('未处理的消息类型:', message.type, message)
// 未知消息类型,静默忽略
}
}
@ -213,7 +214,7 @@ class WebSocketService {
// API方法 - 启动软件
startSoftware(softwareId) {
if (!softwareId || typeof softwareId !== 'string' || softwareId.length === 0) {
console.error('启动软件失败: 无效的软件ID', softwareId)
Logger.error('启动软件失败: 无效的软件ID', softwareId)
return false
}
@ -226,7 +227,7 @@ class WebSocketService {
// API方法 - 停止软件
stopSoftware(softwareId) {
if (!softwareId || typeof softwareId !== 'string' || softwareId.length === 0) {
console.error('停止软件失败: 无效的软件ID', softwareId)
Logger.error('停止软件失败: 无效的软件ID', softwareId)
return false
}
@ -239,7 +240,7 @@ class WebSocketService {
// API方法 - 重启软件
restartSoftware(softwareId) {
if (!softwareId || typeof softwareId !== 'string' || softwareId.length === 0) {
console.error('重启软件失败: 无效的软件ID', softwareId)
Logger.error('重启软件失败: 无效的软件ID', softwareId)
return false
}
@ -252,7 +253,7 @@ class WebSocketService {
// API方法 - 记录操作日志
logOperation(operation, details = '', options = {}) {
if (!operation || typeof operation !== 'string' || operation.length === 0) {
console.error('记录日志失败: 操作名称不能为空')
Logger.error('记录日志失败: 操作名称不能为空')
return false
}
@ -298,7 +299,7 @@ class WebSocketService {
// API方法 - 根据ID获取日志
getLogById(logId) {
if (!logId || typeof logId !== 'string' || logId.length === 0) {
console.error('获取日志失败: 无效的日志ID', logId)
Logger.error('获取日志失败: 无效的日志ID', logId)
return false
}
@ -353,7 +354,7 @@ class WebSocketService {
if (this.listeners[event]) {
this.listeners[event].push(callback)
} else {
console.warn('未知事件类型:', event)
// 静默忽略未知事件类型
}
}
@ -372,7 +373,7 @@ class WebSocketService {
try {
callback(data)
} catch (error) {
console.error('事件回调执行失败:', event, error)
Logger.callbackError(event, error)
}
})
}

58
src/utils/logger.js Normal file
View File

@ -0,0 +1,58 @@
// 统一日志管理工具
// 提供生产环境和开发环境的日志控制
const isDevelopment = import.meta.env.MODE === 'development'
// 日志级别
const LOG_LEVELS = {
ERROR: 0,
WARN: 1,
INFO: 2,
DEBUG: 3
}
// 当前日志级别(生产环境只显示错误,开发环境显示所有)
const currentLevel = isDevelopment ? LOG_LEVELS.DEBUG : LOG_LEVELS.ERROR
class Logger {
static error(...args) {
if (currentLevel >= LOG_LEVELS.ERROR) {
console.error('[ERROR]', ...args)
}
}
static warn(...args) {
if (currentLevel >= LOG_LEVELS.WARN) {
console.warn('[WARN]', ...args)
}
}
static info(...args) {
if (currentLevel >= LOG_LEVELS.INFO) {
console.info('[INFO]', ...args)
}
}
static debug(...args) {
if (currentLevel >= LOG_LEVELS.DEBUG) {
console.log('[DEBUG]', ...args)
}
}
// 专用于API错误日志
static apiError(operation, error, context = {}) {
this.error(`API错误 [${operation}]:`, error, '上下文:', context)
}
// 专用于WebSocket错误日志
static wsError(operation, error, data = null) {
this.error(`WebSocket错误 [${operation}]:`, error, data && `数据: ${data}`)
}
// 专用于回调执行错误
static callbackError(event, error) {
this.error(`回调执行失败 [${event}]:`, error)
}
}
export default Logger

View File

@ -608,7 +608,7 @@ const closeInfoPanel = () => {
color: var(--color-text-primary);
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
text-decoration: none;
}
@ -691,7 +691,7 @@ const closeInfoPanel = () => {
border: 1px solid var(--color-white-rgb-1);
border-radius: 8px;
padding: 20px;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.feature-item:hover {

View File

@ -270,50 +270,50 @@ onMounted(() => {
position: absolute;
border-radius: 50%;
background: var(--color-gradient-brand-bg);
animation: float 6s ease-in-out infinite;
animation: float var(--login-float-duration) ease-in-out infinite;
}
.circle-1 {
width: 200px;
height: 200px;
top: 10%;
left: 10%;
animation-delay: 0s;
width: var(--login-animation-large);
height: var(--login-animation-large);
top: var(--login-circle-1-top);
left: var(--login-circle-1-left);
animation-delay: var(--login-animation-delay-1);
}
.circle-2 {
width: 150px;
height: 150px;
top: 60%;
right: 15%;
animation-delay: 2s;
width: var(--login-animation-medium);
height: var(--login-animation-medium);
top: var(--login-circle-2-top);
right: var(--login-circle-2-right);
animation-delay: var(--login-animation-delay-2);
}
.circle-3 {
width: 100px;
height: 100px;
bottom: 20%;
left: 20%;
animation-delay: 4s;
width: var(--login-animation-small);
height: var(--login-animation-small);
bottom: var(--login-circle-3-bottom);
left: var(--login-circle-3-left);
animation-delay: var(--login-animation-delay-3);
}
@keyframes float {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-20px) rotate(180deg); }
50% { transform: translateY(var(--login-float-distance)) rotate(180deg); }
}
.login-content {
position: relative;
z-index: 1;
width: 100%;
max-width: 420px;
padding: 20px;
max-width: var(--login-card-max-width);
padding: var(--login-card-padding-small);
}
.login-card {
background: var(--color-bg-dark-95);
border-radius: 16px;
padding: 40px;
border-radius: var(--login-card-border-radius);
padding: var(--login-card-padding);
box-shadow: 0 20px 40px var(--color-shadow-black-3);
backdrop-filter: blur(10px);
border: 1px solid var(--color-white-rgb-1);
@ -321,36 +321,36 @@ onMounted(() => {
.brand-section {
text-align: center;
margin-bottom: 40px;
margin-bottom: var(--login-brand-margin-bottom);
}
.brand-logo {
display: inline-flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
width: var(--login-icon-size);
height: var(--login-icon-size);
background: var(--color-primary-gradient);
border-radius: 16px;
margin-bottom: 16px;
border-radius: var(--login-card-border-radius);
margin-bottom: var(--login-brand-logo-margin-bottom);
box-shadow: 0 4px 15px var(--color-primary-rgb-3);
}
.brand-logo i {
font-size: 24px;
font-size: var(--login-title-size);
color: var(--color-text-primary);
}
.brand-title {
font-size: 20px;
font-size: var(--login-subtitle-size);
font-weight: 600;
color: var(--color-text-primary);
margin: 0 0 8px 0;
margin: 0 0 var(--login-brand-title-margin-bottom) 0;
line-height: 1.4;
}
.brand-subtitle {
font-size: 14px;
font-size: var(--login-text-size);
color: var(--color-text-secondary);
margin: 0;
font-weight: 400;
@ -361,49 +361,49 @@ onMounted(() => {
}
.form-title {
font-size: 18px;
font-size: var(--login-button-text-size);
font-weight: 600;
color: var(--color-text-primary);
text-align: center;
margin: 0 0 30px 0;
margin: 0 0 var(--login-form-title-margin-bottom) 0;
}
.error-message {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
background: var(--color-error-rgb-1);
border: 1px solid var(--color-error-rgb-3);
border-radius: 8px;
border-radius: var(--size-border-radius);
color: var(--color-text-error);
font-size: 14px;
margin-bottom: 20px;
font-size: var(--login-text-size);
margin-bottom: var(--login-error-margin-bottom);
}
.form-group {
margin-bottom: 20px;
margin-bottom: var(--login-form-group-margin-bottom);
}
.form-label {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
font-size: var(--login-text-size);
font-weight: 500;
color: var(--color-text-secondary);
margin-bottom: 8px;
margin-bottom: var(--login-form-label-margin-bottom);
}
.form-input {
width: 100%;
padding: 12px 16px;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
background: var(--color-white-rgb-05);
border: 1px solid var(--color-white-rgb-1);
border-radius: 8px;
border-radius: var(--size-border-radius);
color: var(--color-text-primary);
font-size: 14px;
transition: all 0.3s ease;
font-size: var(--login-text-size);
transition: var(--transition-all);
box-sizing: border-box;
}
@ -444,13 +444,13 @@ onMounted(() => {
}
.field-error {
font-size: 12px;
font-size: var(--font-size-xs);
color: var(--color-text-error);
margin-top: 4px;
margin-top: var(--login-field-error-margin-top);
}
.form-options {
margin-bottom: 30px;
margin-bottom: var(--login-form-options-margin-bottom);
}
.checkbox-wrapper {
@ -472,7 +472,7 @@ onMounted(() => {
border-radius: 4px;
background: var(--color-white-rgb-05);
position: relative;
transition: all 0.3s ease;
transition: var(--transition-all);
}
.checkbox-input:checked + .checkbox-custom {
@ -492,26 +492,26 @@ onMounted(() => {
}
.checkbox-label {
font-size: 14px;
font-size: var(--login-text-size);
color: var(--color-text-secondary);
}
.login-button {
width: 100%;
padding: 14px;
padding: var(--login-button-padding);
background: var(--color-primary-gradient);
border: none;
border-radius: 8px;
border-radius: var(--size-border-radius);
color: var(--color-text-primary);
font-size: 16px;
font-size: var(--font-size-lg);
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
transition: var(--transition-all);
box-shadow: 0 4px 15px var(--color-primary-rgb-3);
}
.login-button:hover:not(:disabled) {
transform: translateY(-2px);
transform: var(--login-button-transform);
box-shadow: 0 6px 20px var(--color-primary-rgb-4);
}
@ -520,7 +520,7 @@ onMounted(() => {
}
.login-button:disabled {
opacity: 0.7;
opacity: var(--login-button-disabled-opacity);
cursor: not-allowed;
transform: none;
}
@ -531,11 +531,11 @@ onMounted(() => {
.help-text {
text-align: center;
margin-top: 20px;
margin-top: var(--login-help-margin-top);
}
.help-text p {
font-size: 13px;
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
margin: 0;
}
@ -543,15 +543,15 @@ onMounted(() => {
/* 响应式设计 */
@media (max-width: 480px) {
.login-content {
padding: 16px;
padding: var(--login-content-padding-mobile);
}
.login-card {
padding: 30px 24px;
padding: var(--login-card-padding-mobile);
}
.brand-title {
font-size: 18px;
font-size: var(--login-title-size-mobile);
}
.circle {