diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index cc7d8c1..e072dd9 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -5,7 +5,11 @@
"Bash(done)",
"Bash(npm run lint)",
"Read(//d/App/vue/Miany/**)",
- "Bash(find:*)"
+ "Bash(find:*)",
+ "mcp__sequential-thinking__sequentialthinking",
+ "Bash(for dir in src/assets src/components src/config src/router src/stores src/views)",
+ "Bash(do echo \"=== $dir ===\")",
+ "Bash(ls:*)"
],
"deny": [],
"ask": [],
diff --git a/CLAUDE.md b/CLAUDE.md
index e920ed5..6a6e9d6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -436,6 +436,75 @@ src/assets/styles/theme.css
这次优化在保持视觉效果不变的前提下,大幅简化了颜色变量系统,提升了主题系统的可维护性和扩展性。
+## 📋 用户首页设计与实现记录
+
+### 2025年9月16日 - 登录后首页内容设计
+
+#### 🎯 功能概述
+为工业CAD模型管理平台设计并实现了专业的登录后首页内容,提供平台功能介绍和使用指导。
+
+#### ✅ 完成的设计工作
+
+**1. 首页内容设计**
+- **项目描述段落**: 详细介绍MianyVue平台的定位、目标用户和核心价值
+- **核心能力展示**: 四大功能模块的专业介绍
+ - 多CAD软件统一管理(可扩展设计,避免硬编码数量)
+ - 智能模型分析(层级分析、几何复杂度等)
+ - 灵活导出支持(工业标准格式)
+ - 实时状态监控(系统稳定性保障)
+- **技术特色说明**: 平台技术架构和安全性介绍
+- **使用引导**: 简洁的操作提示
+
+**2. UI设计特色**
+- **文字内容丰富**: 大段专业描述,体现工业软件特色
+- **卡片式布局**: 使用响应式网格展示功能特性
+- **专业配色**: 完全集成现有CSS变量主题系统
+- **交互效果**: hover动画、平滑过渡、视觉层次
+
+**3. 技术实现**
+- **DashboardView.vue修改**: 替换默认空页面为欢迎内容
+- **样式系统集成**: 使用现有theme.css变量和工业化配色
+- **响应式设计**: 移动端和桌面端的适配
+- **路由配置**: 设置默认显示首页内容
+
+#### 📊 设计成果
+
+**内容架构**
+```
+欢迎页面布局
+├── 标题区域 (平台名称和副标题)
+├── 项目描述 (专业介绍段落)
+├── 核心能力 (4个功能卡片)
+├── 技术特色 (技术架构说明)
+└── 使用引导 (操作提示)
+```
+
+**样式特点**
+- **居中布局**: 最大宽度800px,内容居中显示
+- **丰富间距**: 32px间距,良好的视觉层次
+- **图标配色**: 使用主色调蓝色(#2A5CAA)统一图标颜色
+- **卡片交互**: hover效果,轻微上浮动画
+- **文字排版**: 合适的行高(1.6-1.8)和字体大小层级
+
+**响应式适配**
+- **桌面端**: 2列网格显示功能卡片
+- **移动端**: 单列布局,优化间距和字体大小
+- **灵活布局**: 自适应不同屏幕尺寸
+
+#### 🔧 修改的文件
+- `src/views/DashboardView.vue` - 添加欢迎页面内容和样式
+- 路由默认值: currentPage从'connection'改为'home'
+
+#### 🚀 遵循原则
+
+✅ **内容导向**: 提供丰富的文字内容和项目介绍
+✅ **专业定位**: 体现工业CAD软件的专业性和技术特色
+✅ **可扩展设计**: 避免硬编码数量,强调平台的扩展能力
+✅ **设计一致性**: 完全集成现有主题系统和UI风格
+✅ **用户体验**: 清晰的使用指导和操作提示
+
+本次首页设计成功为用户提供了专业、信息丰富的平台介绍,建立了良好的第一印象,符合工业软件的专业定位和用户期望。
+
## 📋 CSS变量系统深度优化记录
### 2025年9月16日 - CSS变量冗余清理
diff --git a/src/assets/styles/theme.css b/src/assets/styles/theme.css
index 835dc77..cce4573 100644
--- a/src/assets/styles/theme.css
+++ b/src/assets/styles/theme.css
@@ -4,86 +4,112 @@
@import './variables.css';
:root {
- /* ===== 颜色系统 ===== */
-
+ /* ===== 基础颜色常量 ===== */
+
+ /* 核心调色板 - 基础颜色值 */
+ --color-primary-base: 42, 92, 170; /* #2A5CAA */
+ --color-primary-light-base: 77, 148, 255; /* #4d94ff */
+ --color-primary-dark-base: 30, 74, 140; /* #1e4a8c */
+ --color-success-base: 76, 175, 80; /* #4CAF50 */
+ --color-warning-base: 255, 152, 0; /* #FF9800 */
+ --color-error-base: 244, 67, 54; /* #F44336 */
+ --color-info-base: 33, 150, 243; /* #2196F3 */
+ --color-bg-primary-base: 30, 30, 30; /* #1E1E1E */
+ --color-bg-secondary-base: 42, 42, 42; /* #2A2A2A */
+ --color-bg-tertiary-base: 26, 26, 26; /* #1A1A1A */
+ --color-white-base: 255, 255, 255; /* #ffffff */
+ --color-black-base: 0, 0, 0; /* #000000 */
+
+ /* ===== 语义化颜色系统 ===== */
+
/* 主色调 */
- --color-primary: #2A5CAA;
- --color-primary-light: #4d94ff;
- --color-primary-dark: #1e4a8c;
- --color-primary-gradient: linear-gradient(135deg, #2A5CAA 0%, #4d94ff 100%);
- --color-primary-gradient-hover: linear-gradient(135deg, #1e4a8c 0%, #2A5CAA 100%);
-
+ --color-primary: rgb(var(--color-primary-base));
+ --color-primary-light: rgb(var(--color-primary-light-base));
+ --color-primary-dark: rgb(var(--color-primary-dark-base));
+ --color-primary-gradient: linear-gradient(135deg, rgb(var(--color-primary-base)) 0%, rgb(var(--color-primary-light-base)) 100%);
+ --color-primary-gradient-hover: linear-gradient(135deg, rgb(var(--color-primary-dark-base)) 0%, rgb(var(--color-primary-base)) 100%);
+
/* 状态色 */
- --color-success: #4CAF50;
- --color-warning: #FF9800;
- --color-error: #F44336;
- --color-info: #2196F3;
+ --color-success: rgb(var(--color-success-base));
+ --color-warning: rgb(var(--color-warning-base));
+ --color-error: rgb(var(--color-error-base));
+ --color-info: rgb(var(--color-info-base));
/* 背景状态色 */
- --color-bg-error: rgba(244, 67, 54, 0.1);
- --color-bg-success: rgba(76, 175, 80, 0.1);
- --color-bg-warning: rgba(255, 152, 0, 0.1);
- --color-bg-info: rgba(33, 150, 243, 0.1);
-
+ --color-bg-error: rgba(var(--color-error-base), 0.1);
+ --color-bg-success: rgba(var(--color-success-base), 0.1);
+ --color-bg-warning: rgba(var(--color-warning-base), 0.1);
+ --color-bg-info: rgba(var(--color-info-base), 0.1);
+
/* 背景色 */
- --color-bg-primary: #1E1E1E;
- --color-bg-secondary: #2A2A2A;
- --color-bg-tertiary: #1A1A1A;
- --color-bg-quaternary: #252525;
- --color-bg-card: rgba(42, 42, 42, 0.8);
- --color-bg-hover: rgba(255, 255, 255, 0.05);
- --color-bg-active: rgba(42, 92, 170, 0.1);
- --color-bg-input: rgba(255, 255, 255, 0.05);
-
+ --color-bg-primary: rgb(var(--color-bg-primary-base));
+ --color-bg-secondary: rgb(var(--color-bg-secondary-base));
+ --color-bg-tertiary: rgb(var(--color-bg-tertiary-base));
+ --color-bg-quaternary: rgb(37, 37, 37);
+ --color-bg-card: rgba(var(--color-bg-secondary-base), 0.8);
+ --color-bg-hover: rgba(var(--color-white-base), 0.05);
+ --color-bg-active: rgba(var(--color-primary-base), 0.1);
+ --color-bg-input: rgba(var(--color-white-base), 0.05);
+
/* 渐变背景 */
- --color-bg-gradient-main: linear-gradient(135deg, #1E1E1E 0%, #2A2A2A 100%);
- --color-bg-gradient-sidebar: linear-gradient(135deg, #1a1a1a 0%, #252525 100%);
- --color-bg-gradient-header: linear-gradient(135deg, #1a1a1a 0%, #252525 100%);
- --color-bg-gradient-brand: linear-gradient(135deg, #2A5CAA 0%, #4d94ff 100%);
- --color-bg-gradient-brand-hover: linear-gradient(135deg, #1e4a8c 0%, #2A5CAA 100%);
-
+ --color-bg-gradient-main: linear-gradient(135deg, rgb(var(--color-bg-primary-base)) 0%, rgb(var(--color-bg-secondary-base)) 100%);
+ --color-bg-gradient-sidebar: linear-gradient(135deg, rgb(var(--color-bg-tertiary-base)) 0%, rgb(37, 37, 37) 100%);
+ --color-bg-gradient-header: linear-gradient(135deg, rgb(var(--color-bg-tertiary-base)) 0%, rgb(37, 37, 37) 100%);
+ --color-bg-gradient-brand: var(--color-primary-gradient);
+ --color-bg-gradient-brand-hover: var(--color-primary-gradient-hover);
+
/* 边框色 */
- --color-border-primary: rgba(255, 255, 255, 0.1);
- --color-border-secondary: rgba(255, 255, 255, 0.2);
- --color-border-active: #2A5CAA;
- --color-border-error: #F44336;
+ --color-border-primary: rgba(var(--color-white-base), 0.1);
+ --color-border-secondary: rgba(var(--color-white-base), 0.2);
+ --color-border-active: var(--color-primary);
+ --color-border-error: var(--color-error);
/* 文字色 */
- --color-text-primary: #ffffff;
- --color-text-secondary: #cccccc;
- --color-text-tertiary: #888888;
- --color-text-quaternary: #666666;
- --color-text-disabled: #999999;
- --color-text-error: #F44336;
+ --color-text-primary: rgb(var(--color-white-base));
+ --color-text-secondary: rgb(204, 204, 204);
+ --color-text-tertiary: rgb(136, 136, 136);
+ --color-text-quaternary: rgb(102, 102, 102);
+ --color-text-disabled: rgb(153, 153, 153);
+ --color-text-error: var(--color-error);
/* 特殊文字色 */
- --color-text-orange: #ff6b35;
- --color-text-red: #ff0000;
- --color-text-blue: #0064c8;
+ --color-text-orange: rgb(255, 107, 53);
+ --color-text-red: rgb(255, 0, 0);
+ --color-text-blue: rgb(0, 100, 200);
+
+ /* ===== 优化透明度层级系统 ===== */
+
+ /* 主色调透明度变体 */
+ --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);
+
+ /* 状态色透明度变体 */
+ --color-error-rgb-1: rgba(var(--color-error-base), 0.1);
+ --color-error-rgb-3: rgba(var(--color-error-base), 0.3);
+
+ /* 白色透明度变体(标准5级层级)*/
+ --color-white-rgb-05: rgba(var(--color-white-base), 0.05);
+ --color-white-rgb-1: rgba(var(--color-white-base), 0.1);
+ --color-white-rgb-15: rgba(var(--color-white-base), 0.15);
+ --color-white-rgb-2: rgba(var(--color-white-base), 0.2);
+ --color-white-rgb-3: rgba(var(--color-white-base), 0.3);
+
+ /* 渐变背景 */
+ --color-gradient-brand-bg: linear-gradient(135deg, rgba(var(--color-primary-base), 0.1) 0%, rgba(var(--color-primary-light-base), 0.05) 100%);
+ --color-gradient-brand-bg-2: linear-gradient(135deg, rgba(var(--color-primary-base), 0.2) 0%, rgba(var(--color-primary-light-base), 0.1) 100%);
+ --color-gradient-success: linear-gradient(135deg, rgba(var(--color-success-base), 0.1) 0%, rgba(var(--color-success-base), 0.05) 100%);
+ --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-primary-rgb: rgba(42, 92, 170, 0.1);
- --color-primary-rgb-3: rgba(42, 92, 170, 0.3);
- --color-primary-rgb-4: rgba(42, 92, 170, 0.4);
- --color-error-rgb-1: rgba(244, 67, 54, 0.1);
- --color-error-rgb-3: rgba(244, 67, 54, 0.3);
- --color-white-rgb-05: rgba(255, 255, 255, 0.05);
- --color-white-rgb-1: rgba(255, 255, 255, 0.1);
- --color-white-rgb-15: rgba(255, 255, 255, 0.15);
- --color-white-rgb-2: rgba(255, 255, 255, 0.2);
- --color-white-rgb-3: rgba(255, 255, 255, 0.3);
- --color-bg-dark-95: rgba(42, 42, 42, 0.95);
- --color-shadow-black-3: rgba(0, 0, 0, 0.3);
- --color-gradient-brand-bg: linear-gradient(135deg, rgba(42, 92, 170, 0.1) 0%, rgba(77, 148, 255, 0.05) 100%);
-
/* 阴影色 - 指向已有变量避免重复 */
--color-shadow-primary: var(--color-primary-rgb-3);
--color-shadow-hover: var(--color-primary-rgb-4);
- --color-shadow-card: 0 20px 40px rgba(0, 0, 0, 0.3);
-
+ --color-shadow-card: 0 20px 40px rgba(var(--color-black-base), 0.3);
+
/* 滚动条 */
- --color-scrollbar-thumb: rgba(255, 255, 255, 0.2);
- --color-scrollbar-thumb-hover: rgba(255, 255, 255, 0.3);
+ --color-scrollbar-thumb: var(--color-white-rgb-2);
+ --color-scrollbar-thumb-hover: var(--color-white-rgb-3);
--color-scrollbar-track: transparent;
/* ===== 尺寸系统 ===== */
@@ -141,7 +167,14 @@
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
-
+
+ /* Z-Index层级 */
+ --z-index-header: 1000;
+ --z-index-sidebar: 1000;
+ --z-index-modal: 1000;
+ --z-index-overlay: 999;
+ --z-index-dropdown: 998;
+
/* ===== 动画系统 ===== */
--transition-duration: 0.3s;
--transition-timing: ease;
@@ -149,25 +182,25 @@
/* 亮色主题(可选) */
[data-theme="light"] {
- --color-bg-primary: #ffffff;
- --color-bg-secondary: #f5f5f5;
- --color-bg-tertiary: #fafafa;
- --color-bg-quaternary: #eeeeee;
- --color-bg-card: rgba(255, 255, 255, 0.9);
- --color-bg-hover: rgba(0, 0, 0, 0.05);
- --color-bg-active: rgba(42, 92, 170, 0.1);
- --color-bg-input: rgba(0, 0, 0, 0.02);
-
- --color-border-primary: rgba(0, 0, 0, 0.1);
- --color-border-secondary: rgba(0, 0, 0, 0.2);
-
- --color-text-primary: #1a1a1a;
- --color-text-secondary: #333333;
- --color-text-tertiary: #666666;
- --color-text-quaternary: #999999;
- --color-text-disabled: #888888;
-
- --color-shadow-card: 0 20px 40px rgba(0, 0, 0, 0.1);
+ --color-bg-primary: rgb(var(--color-white-base));
+ --color-bg-secondary: rgb(245, 245, 245);
+ --color-bg-tertiary: rgb(250, 250, 250);
+ --color-bg-quaternary: rgb(238, 238, 238);
+ --color-bg-card: rgba(var(--color-white-base), 0.9);
+ --color-bg-hover: rgba(var(--color-black-base), 0.05);
+ --color-bg-active: rgba(var(--color-primary-base), 0.1);
+ --color-bg-input: rgba(var(--color-black-base), 0.02);
+
+ --color-border-primary: rgba(var(--color-black-base), 0.1);
+ --color-border-secondary: rgba(var(--color-black-base), 0.2);
+
+ --color-text-primary: rgb(26, 26, 26);
+ --color-text-secondary: rgb(51, 51, 51);
+ --color-text-tertiary: rgb(102, 102, 102);
+ --color-text-quaternary: rgb(153, 153, 153);
+ --color-text-disabled: rgb(136, 136, 136);
+
+ --color-shadow-card: 0 20px 40px rgba(var(--color-black-base), 0.1);
}
/* 全局基础样式 */
@@ -263,20 +296,20 @@ html, body {
}
.btn-secondary:hover {
- background: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-15);
color: var(--color-text-primary);
border-color: var(--color-border-primary);
}
.btn-error {
- background: rgba(244, 67, 54, 0.1);
- border-color: rgba(244, 67, 54, 0.3);
+ background: var(--color-error-rgb-1);
+ border-color: var(--color-error-rgb-3);
color: var(--color-error);
}
.btn-error:hover {
- background: rgba(244, 67, 54, 0.2);
- border-color: rgba(244, 67, 54, 0.5);
+ background: var(--color-error-rgb-1);
+ border-color: var(--color-error-rgb-3);
}
/* 输入框基础样式 */
@@ -295,8 +328,8 @@ html, body {
.form-input:focus {
outline: none;
border-color: var(--color-border-active);
- box-shadow: 0 0 0 var(--input-focus-border-width) rgba(42, 92, 170, 0.1);
- background: rgba(255, 255, 255, 0.08);
+ box-shadow: 0 0 0 var(--input-focus-border-width) var(--color-primary-rgb);
+ background: var(--color-white-rgb-05);
}
.form-input::placeholder {
@@ -319,7 +352,7 @@ html, body {
.card-header {
padding: var(--spacing-2xl);
border-bottom: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
.card-body {
@@ -331,7 +364,7 @@ html, body {
.card-footer {
padding: var(--spacing-xl) var(--spacing-2xl);
border-top: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
/* 布局工具类 */
@@ -393,12 +426,12 @@ html, body {
/* 玻璃态效果 */
.glass {
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
backdrop-filter: blur(10px);
- border: 1px solid rgba(255, 255, 255, 0.1);
+ border: 1px solid var(--color-white-rgb-1);
}
.glass-hover:hover {
- background: rgba(255, 255, 255, 0.08);
- border-color: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-05);
+ border-color: var(--color-white-rgb-15);
}
\ No newline at end of file
diff --git a/src/components/layout/AppHeader.vue b/src/components/layout/AppHeader.vue
index 1d6ccfe..ec8f11f 100644
--- a/src/components/layout/AppHeader.vue
+++ b/src/components/layout/AppHeader.vue
@@ -64,7 +64,7 @@
border-bottom: 1px solid var(--color-border-primary);
padding: 0 20px;
position: relative;
- z-index: 1000;
+ z-index: var(--z-index-header);
}
.navbar-left {
diff --git a/src/components/layout/CadSidebar.vue b/src/components/layout/CadSidebar.vue
index 22036b2..8433441 100644
--- a/src/components/layout/CadSidebar.vue
+++ b/src/components/layout/CadSidebar.vue
@@ -138,7 +138,7 @@ const testConnection = (software) => {
align-items: center;
gap: 8px;
padding: 12px;
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
border-radius: 6px;
font-size: 14px;
}
@@ -201,14 +201,14 @@ const testConnection = (software) => {
align-items: flex-start;
gap: 12px;
padding: 12px;
- background: rgba(255, 255, 255, 0.03);
+ background: var(--color-white-rgb-05);
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
}
.option-item:hover {
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
}
.option-item input[type="radio"] {
@@ -275,11 +275,11 @@ const testConnection = (software) => {
}
.side-panel::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.2);
+ background: var(--color-white-rgb-2);
border-radius: 3px;
}
.side-panel::-webkit-scrollbar-thumb:hover {
- background: rgba(255, 255, 255, 0.3);
+ background: var(--color-white-rgb-3);
}
\ No newline at end of file
diff --git a/src/components/layout/ContentArea.vue b/src/components/layout/ContentArea.vue
index bba95be..ad308c0 100644
--- a/src/components/layout/ContentArea.vue
+++ b/src/components/layout/ContentArea.vue
@@ -87,8 +87,8 @@ defineProps({
}
.content-card {
- background: rgba(42, 42, 42, 0.8);
- border: 1px solid rgba(255, 255, 255, 0.1);
+ background: var(--color-bg-dark-8);
+ border: 1px solid var(--color-white-rgb-1);
border-radius: 12px;
height: 100%;
display: flex;
@@ -101,8 +101,8 @@ defineProps({
align-items: center;
justify-content: space-between;
padding: 20px 24px;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
- background: rgba(255, 255, 255, 0.02);
+ border-bottom: 1px solid var(--color-white-rgb-1);
+ background: var(--color-white-rgb-05);
flex-shrink: 0;
}
@@ -128,8 +128,8 @@ defineProps({
.card-footer {
padding: 16px 24px;
- border-top: 1px solid rgba(255, 255, 255, 0.1);
- background: rgba(255, 255, 255, 0.02);
+ border-top: 1px solid var(--color-white-rgb-1);
+ background: var(--color-white-rgb-05);
flex-shrink: 0;
}
@@ -172,12 +172,12 @@ defineProps({
}
.card-body::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.2);
+ background: var(--color-white-rgb-2);
border-radius: 3px;
}
.card-body::-webkit-scrollbar-thumb:hover {
- background: rgba(255, 255, 255, 0.3);
+ background: var(--color-white-rgb-3);
}
/* 按钮基础样式 */
@@ -186,9 +186,9 @@ defineProps({
align-items: center;
gap: 8px;
padding: 8px 16px;
- border: 1px solid rgba(255, 255, 255, 0.2);
+ border: 1px solid var(--color-white-rgb-2);
border-radius: 6px;
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
color: var(--color-text-primary);
font-size: 14px;
cursor: pointer;
@@ -197,8 +197,8 @@ defineProps({
}
.btn:hover {
- background: rgba(255, 255, 255, 0.1);
- border-color: rgba(255, 255, 255, 0.3);
+ background: var(--color-white-rgb-1);
+ border-color: var(--color-white-rgb-3);
}
.btn-primary {
@@ -209,17 +209,17 @@ defineProps({
.btn-primary:hover {
background: var(--color-primary-gradient-hover);
- box-shadow: 0 4px 15px rgba(42, 92, 170, 0.3);
+ box-shadow: 0 4px 15px var(--color-primary-rgb-3);
}
.btn-secondary {
- background: rgba(255, 255, 255, 0.1);
- border-color: rgba(255, 255, 255, 0.2);
+ background: var(--color-white-rgb-1);
+ border-color: var(--color-white-rgb-2);
color: var(--color-text-secondary);
}
.btn-secondary:hover {
- background: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-15);
color: var(--color-text-primary);
}
\ No newline at end of file
diff --git a/src/components/layout/MainLayout.vue b/src/components/layout/MainLayout.vue
index 6d2e5a6..c6eed7d 100644
--- a/src/components/layout/MainLayout.vue
+++ b/src/components/layout/MainLayout.vue
@@ -70,7 +70,7 @@ import AppHeader from './AppHeader.vue'
.app-header {
height: 60px;
flex-shrink: 0;
- z-index: 1000;
+ z-index: var(--z-index-sidebar);
}
.app-body {
@@ -123,7 +123,7 @@ import AppHeader from './AppHeader.vue'
display: flex;
align-items: center;
justify-content: center;
- background: rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-1);
border: none;
border-radius: 6px;
color: var(--color-text-secondary);
@@ -132,7 +132,7 @@ import AppHeader from './AppHeader.vue'
}
.tool-btn:hover {
- background: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-15);
color: var(--color-text-primary);
}
@@ -219,12 +219,12 @@ import AppHeader from './AppHeader.vue'
.app-sidebar::-webkit-scrollbar-thumb,
.work-content::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.2);
+ background: var(--color-white-rgb-2);
border-radius: 3px;
}
.app-sidebar::-webkit-scrollbar-thumb:hover,
.work-content::-webkit-scrollbar-thumb:hover {
- background: rgba(255, 255, 255, 0.3);
+ background: var(--color-white-rgb-3);
}
\ No newline at end of file
diff --git a/src/components/layout/ModelManagement.vue b/src/components/layout/ModelManagement.vue
index affc19f..e600dde 100644
--- a/src/components/layout/ModelManagement.vue
+++ b/src/components/layout/ModelManagement.vue
@@ -389,16 +389,16 @@ const openSelectedFile = async () => {
}
.action-card:hover .action-card-inner {
- background: rgba(255, 255, 255, 0.08);
- border-color: rgba(255, 255, 255, 0.2);
+ background: var(--color-white-rgb-05);
+ border-color: var(--color-white-rgb-2);
transform: translateY(-4px);
- box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 12px 30px var(--color-black-rgb-2);
}
.action-card.active .action-card-inner {
- background: rgba(42, 92, 170, 0.1);
+ background: var(--color-primary-rgb);
border-color: var(--color-primary);
- box-shadow: 0 0 20px rgba(42, 92, 170, 0.2);
+ box-shadow: 0 0 20px var(--color-primary-rgb-2);
}
.action-card.active::before {
@@ -430,7 +430,7 @@ const openSelectedFile = async () => {
justify-content: center;
width: 80px;
height: 80px;
- background: linear-gradient(135deg, rgba(42, 92, 170, 0.1) 0%, rgba(77, 148, 255, 0.05) 100%);
+ background: linear-gradient(135deg, var(--color-primary-rgb) 0%, var(--color-primary-light-rgb-05) 100%);
border-radius: var(--size-border-radius);
font-size: 32px;
color: var(--color-primary);
@@ -446,7 +446,7 @@ const openSelectedFile = async () => {
left: -50%;
width: 200%;
height: 200%;
- background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
+ background: linear-gradient(45deg, transparent, var(--color-white-rgb-1), transparent);
transform: rotate(45deg);
transition: all 0.6s ease;
}
@@ -465,9 +465,9 @@ const openSelectedFile = async () => {
}
.action-card.active .action-icon {
- background: linear-gradient(135deg, rgba(42, 92, 170, 0.2) 0%, rgba(77, 148, 255, 0.1) 100%);
+ background: linear-gradient(135deg, var(--color-primary-rgb-2) 0%, var(--color-primary-light-rgb-1) 100%);
color: var(--color-primary);
- box-shadow: 0 0 20px rgba(42, 92, 170, 0.3);
+ box-shadow: 0 0 20px var(--color-primary-rgb-3);
}
.action-badge {
@@ -484,7 +484,7 @@ const openSelectedFile = async () => {
justify-content: center;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
- box-shadow: 0 2px 8px rgba(42, 92, 170, 0.3);
+ box-shadow: 0 2px 8px var(--color-primary-rgb-3);
z-index: 2;
}
@@ -513,15 +513,15 @@ const openSelectedFile = async () => {
color: var(--color-error);
font-weight: var(--font-weight-medium);
padding: var(--spacing-xs) var(--spacing-sm);
- background: rgba(244, 67, 54, 0.1);
+ background: var(--color-error-rgb-1);
border-radius: var(--size-border-radius);
- border: 1px solid rgba(244, 67, 54, 0.2);
+ border: 1px solid var(--color-error-rgb-1);
}
.action-preview {
padding: var(--spacing-md) var(--spacing-lg);
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-05);
+ border: 1px solid var(--color-white-rgb-1);
border-radius: var(--size-border-radius);
display: flex;
align-items: center;
@@ -563,11 +563,11 @@ const openSelectedFile = async () => {
left: 0;
right: 0;
bottom: 0;
- background: rgba(0, 0, 0, 0.6);
+ background: var(--color-black-rgb-6);
display: flex;
align-items: center;
justify-content: center;
- z-index: 1000;
+ z-index: var(--z-index-modal);
backdrop-filter: blur(4px);
}
@@ -580,7 +580,7 @@ const openSelectedFile = async () => {
max-height: 70vh;
display: flex;
flex-direction: column;
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
+ box-shadow: 0 20px 40px var(--color-black-rgb-4);
overflow: hidden;
transform: scale(1);
transition: all var(--transition-duration) var(--transition-timing);
@@ -592,7 +592,7 @@ const openSelectedFile = async () => {
justify-content: space-between;
padding: var(--spacing-xl);
border-bottom: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
.dialog-title-section {
@@ -647,7 +647,7 @@ const openSelectedFile = async () => {
gap: var(--spacing-sm);
margin-bottom: var(--spacing-lg);
padding: var(--spacing-sm) var(--spacing-md);
- background: rgba(255, 255, 255, 0.03);
+ background: var(--color-white-rgb-05);
border-radius: var(--size-border-radius);
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
@@ -685,14 +685,14 @@ const openSelectedFile = async () => {
}
.file-item:hover {
- background: rgba(255, 255, 255, 0.05);
- border-color: rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-05);
+ border-color: var(--color-white-rgb-1);
}
.file-item.selected {
- background: rgba(42, 92, 170, 0.1);
+ background: var(--color-primary-rgb);
border-color: var(--color-primary);
- box-shadow: 0 0 15px rgba(42, 92, 170, 0.2);
+ box-shadow: 0 0 15px var(--color-primary-rgb-2);
}
.file-item.recent {
@@ -705,7 +705,7 @@ const openSelectedFile = async () => {
justify-content: center;
width: 40px;
height: 40px;
- background: rgba(42, 92, 170, 0.1);
+ background: var(--color-primary-rgb);
border-radius: var(--size-border-radius);
color: var(--color-primary);
font-size: var(--font-size-lg);
@@ -766,7 +766,7 @@ const openSelectedFile = async () => {
justify-content: space-between;
padding: var(--spacing-xl);
border-top: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
.dialog-info {
diff --git a/src/components/layout/OpenedModelsTable.vue b/src/components/layout/OpenedModelsTable.vue
index 7fc3184..b41f43d 100644
--- a/src/components/layout/OpenedModelsTable.vue
+++ b/src/components/layout/OpenedModelsTable.vue
@@ -188,16 +188,20 @@ import { useCADStore } from '@/stores/cad'
// 时间常量配置
const TIME_CONSTANTS = {
+ // 基础时间单位
MILLISECONDS_PER_SECOND: 1000,
SECONDS_PER_MINUTE: 60,
MINUTES_PER_HOUR: 60,
- HOURS_PER_DAY: 24,
- // 计算常量
- MILLISECONDS_PER_MINUTE: 1000 * 60,
- MILLISECONDS_PER_HOUR: 1000 * 60 * 60,
- MILLISECONDS_PER_DAY: 1000 * 60 * 60 * 24,
+ HOURS_PER_DAY: 24
+}
+
+// 计算常量 - 使用基础常量计算避免魔术数字
+const DERIVED_TIME_CONSTANTS = {
+ MILLISECONDS_PER_MINUTE: TIME_CONSTANTS.MILLISECONDS_PER_SECOND * TIME_CONSTANTS.SECONDS_PER_MINUTE,
+ MILLISECONDS_PER_HOUR: TIME_CONSTANTS.MILLISECONDS_PER_SECOND * TIME_CONSTANTS.SECONDS_PER_MINUTE * TIME_CONSTANTS.MINUTES_PER_HOUR,
+ MILLISECONDS_PER_DAY: TIME_CONSTANTS.MILLISECONDS_PER_SECOND * TIME_CONSTANTS.SECONDS_PER_MINUTE * TIME_CONSTANTS.MINUTES_PER_HOUR * TIME_CONSTANTS.HOURS_PER_DAY,
// 业务常量
- RECENT_MODEL_THRESHOLD: 1000 * 60 * 60 // 1小时内算最近
+ RECENT_MODEL_THRESHOLD: TIME_CONSTANTS.MILLISECONDS_PER_SECOND * TIME_CONSTANTS.SECONDS_PER_MINUTE * TIME_CONSTANTS.MINUTES_PER_HOUR // 1小时内算最近
}
const emit = defineEmits(['select', 'view', 'export', 'close', 'refresh', 'add'])
@@ -255,7 +259,7 @@ const refreshModels = async () => {
const isRecentModel = (model) => {
const now = new Date()
const diff = now - model.openTime
- return diff < TIME_CONSTANTS.RECENT_MODEL_THRESHOLD
+ return diff < DERIVED_TIME_CONSTANTS.RECENT_MODEL_THRESHOLD
}
const getModelIconClass = (model) => {
@@ -294,9 +298,9 @@ const getSourceIcon = (source) => {
const formatTime = (time) => {
const now = new Date()
const diff = now - time
- const minutes = Math.floor(diff / TIME_CONSTANTS.MILLISECONDS_PER_MINUTE)
- const hours = Math.floor(diff / TIME_CONSTANTS.MILLISECONDS_PER_HOUR)
- const days = Math.floor(diff / TIME_CONSTANTS.MILLISECONDS_PER_DAY)
+ const minutes = Math.floor(diff / DERIVED_TIME_CONSTANTS.MILLISECONDS_PER_MINUTE)
+ const hours = Math.floor(diff / DERIVED_TIME_CONSTANTS.MILLISECONDS_PER_HOUR)
+ const days = Math.floor(diff / DERIVED_TIME_CONSTANTS.MILLISECONDS_PER_DAY)
if (minutes < TIME_CONSTANTS.MINUTES_PER_HOUR) {
return `${minutes}分钟前`
@@ -334,8 +338,8 @@ const formatTimeDetail = (time) => {
align-items: center;
justify-content: space-between;
padding: var(--spacing-lg);
- background: rgba(255, 255, 255, 0.02);
- border: 1px solid rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-05);
+ border: 1px solid var(--color-white-rgb-1);
border-radius: var(--size-border-radius-card);
backdrop-filter: blur(10px);
}
@@ -390,7 +394,7 @@ const formatTimeDetail = (time) => {
}
.models-table-container:hover {
- box-shadow: 0 25px 50px rgba(0, 0, 0, 0.35);
+ box-shadow: 0 25px 50px var(--color-black-rgb-35);
}
.table-wrapper {
@@ -401,11 +405,11 @@ const formatTimeDetail = (time) => {
width: 100%;
border-collapse: collapse;
font-size: 16px;
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
.models-table th {
- background: rgba(255, 255, 255, 0.03);
+ background: var(--color-white-rgb-05);
border-bottom: 2px solid var(--color-border-primary);
padding: var(--spacing-xl) var(--spacing-lg);
text-align: left;
@@ -468,7 +472,7 @@ const formatTimeDetail = (time) => {
}
.model-row:hover {
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
transform: translateX(4px);
}
@@ -477,7 +481,7 @@ const formatTimeDetail = (time) => {
}
.model-row.active {
- background: rgba(42, 92, 170, 0.1);
+ background: var(--color-primary-rgb);
}
.model-row.active::before {
@@ -486,7 +490,7 @@ const formatTimeDetail = (time) => {
}
.model-row.recent {
- background: rgba(255, 152, 0, 0.05);
+ background: var(--color-warning-rgb-05);
}
.model-row:last-child td {
@@ -527,7 +531,7 @@ const formatTimeDetail = (time) => {
justify-content: center;
width: 48px;
height: 48px;
- background: linear-gradient(135deg, rgba(42, 92, 170, 0.1) 0%, rgba(77, 148, 255, 0.05) 100%);
+ background: linear-gradient(135deg, var(--color-primary-rgb) 0%, var(--color-primary-light-rgb-05) 100%);
border-radius: var(--size-border-radius);
color: var(--color-primary);
font-size: 20px;
@@ -535,17 +539,17 @@ const formatTimeDetail = (time) => {
}
.model-icon.assembly {
- background: linear-gradient(135deg, rgba(76, 175, 80, 0.1) 0%, rgba(76, 175, 80, 0.05) 100%);
+ background: var(--color-gradient-success);
color: var(--color-success);
}
.model-icon.part {
- background: linear-gradient(135deg, rgba(33, 150, 243, 0.1) 0%, rgba(33, 150, 243, 0.05) 100%);
+ background: var(--color-gradient-info);
color: var(--color-info);
}
.model-icon.drawing {
- background: linear-gradient(135deg, rgba(255, 152, 0, 0.1) 0%, rgba(255, 152, 0, 0.05) 100%);
+ background: linear-gradient(135deg, var(--color-warning-rgb-1) 0%, var(--color-warning-rgb-05) 100%);
color: var(--color-warning);
}
@@ -590,7 +594,7 @@ const formatTimeDetail = (time) => {
}
.model-version {
- background: rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-1);
padding: 2px 6px;
border-radius: 4px;
font-weight: var(--font-weight-medium);
@@ -612,7 +616,7 @@ const formatTimeDetail = (time) => {
justify-content: center;
width: 32px;
height: 32px;
- background: rgba(255, 255, 255, 0.1);
+ background: var(--color-white-rgb-1);
border-radius: var(--size-border-radius);
color: var(--color-text-secondary);
font-size: var(--font-size-base);
@@ -620,17 +624,17 @@ const formatTimeDetail = (time) => {
}
.source-icon.solidworks {
- background: rgba(255, 107, 53, 0.1);
+ background: var(--color-orange-rgb-1);
color: var(--color-text-orange);
}
.source-icon.autocad {
- background: rgba(255, 0, 0, 0.1);
+ background: var(--color-red-rgb-1);
color: var(--color-text-red);
}
.source-icon.creo {
- background: rgba(0, 100, 200, 0.1);
+ background: var(--color-blue-rgb-1);
color: var(--color-text-blue);
}
@@ -699,17 +703,17 @@ const formatTimeDetail = (time) => {
.action-btn.view-btn:hover {
color: var(--color-info);
- background: rgba(33, 150, 243, 0.1);
+ background: var(--color-info-rgb-1);
}
.action-btn.export-btn:hover {
color: var(--color-success);
- background: rgba(76, 175, 80, 0.1);
+ background: var(--color-success-rgb-1);
}
.action-btn.close-btn:hover {
color: var(--color-error);
- background: rgba(244, 67, 54, 0.1);
+ background: var(--color-error-rgb-1);
}
/* 空状态 */
@@ -721,13 +725,13 @@ const formatTimeDetail = (time) => {
padding: var(--spacing-4xl);
color: var(--color-text-tertiary);
text-align: center;
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
.empty-icon {
width: 80px;
height: 80px;
- background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
+ background: linear-gradient(135deg, var(--color-white-rgb-05) 0%, var(--color-white-rgb-05) 100%);
border-radius: 50%;
display: flex;
align-items: center;
diff --git a/src/components/ui/BaseButton.vue b/src/components/ui/BaseButton.vue
index 20a57d1..cc1266d 100644
--- a/src/components/ui/BaseButton.vue
+++ b/src/components/ui/BaseButton.vue
@@ -139,7 +139,7 @@ const handleClick = (event) => {
}
.btn-secondary:hover:not(:disabled) {
- background: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-15);
color: var(--color-text-primary);
border-color: var(--color-border-primary);
transform: translateY(-1px);
@@ -156,8 +156,8 @@ const handleClick = (event) => {
}
.btn-error:hover:not(:disabled) {
- background: rgba(244, 67, 54, 0.2);
- border-color: rgba(244, 67, 54, 0.5);
+ background: var(--color-error-rgb-1);
+ border-color: var(--color-error-rgb-3);
transform: translateY(-1px);
}
diff --git a/src/components/ui/BaseCard.vue b/src/components/ui/BaseCard.vue
index 56510ba..83f5304 100644
--- a/src/components/ui/BaseCard.vue
+++ b/src/components/ui/BaseCard.vue
@@ -71,27 +71,27 @@ const cardClasses = computed(() => {
}
.card-hover:hover {
- background: rgba(42, 42, 42, 0.9);
+ background: var(--color-bg-dark-95);
border-color: var(--color-primary);
transform: translateY(-2px);
box-shadow: var(--color-shadow-hover);
}
.card-glass {
- background: rgba(255, 255, 255, 0.05);
+ background: var(--color-white-rgb-05);
backdrop-filter: blur(10px);
- border: 1px solid rgba(255, 255, 255, 0.1);
+ border: 1px solid var(--color-white-rgb-1);
}
.card-glass:hover {
- background: rgba(255, 255, 255, 0.08);
- border-color: rgba(255, 255, 255, 0.15);
+ background: var(--color-white-rgb-05);
+ border-color: var(--color-white-rgb-15);
}
.card-header {
padding: var(--spacing-2xl);
border-bottom: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
display: flex;
align-items: center;
justify-content: space-between;
@@ -112,7 +112,7 @@ const cardClasses = computed(() => {
.card-footer {
padding: var(--spacing-xl) var(--spacing-2xl);
border-top: 1px solid var(--color-border-primary);
- background: rgba(255, 255, 255, 0.02);
+ background: var(--color-white-rgb-05);
}
/* 内边距变体 */
diff --git a/src/components/ui/BaseInput.vue b/src/components/ui/BaseInput.vue
index 963ce3f..76f442c 100644
--- a/src/components/ui/BaseInput.vue
+++ b/src/components/ui/BaseInput.vue
@@ -178,8 +178,8 @@ const clearInput = () => {
.form-input:focus {
outline: none;
border-color: var(--color-border-active);
- box-shadow: 0 0 0 var(--input-focus-border-width) rgba(42, 92, 170, 0.1);
- background: rgba(255, 255, 255, 0.08);
+ box-shadow: 0 0 0 var(--input-focus-border-width) var(--color-primary-rgb);
+ background: var(--color-white-rgb-05);
}
.form-input::placeholder {
@@ -205,7 +205,7 @@ const clearInput = () => {
.form-input-error:focus {
border-color: var(--color-border-error);
- box-shadow: 0 0 0 var(--input-focus-border-width) rgba(244, 67, 54, 0.1);
+ box-shadow: 0 0 0 var(--input-focus-border-width) var(--color-error-rgb-1);
}
/* 图标样式 */
diff --git a/src/components/ui/CadSoftwareGrid.vue b/src/components/ui/CadSoftwareGrid.vue
index 965589f..589945c 100644
--- a/src/components/ui/CadSoftwareGrid.vue
+++ b/src/components/ui/CadSoftwareGrid.vue
@@ -107,12 +107,12 @@ const testConnection = (software) => {
.software-item:hover {
border-color: var(--color-border-active);
transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(42,92,170,0.2);
+ box-shadow: 0 4px 12px var(--color-primary-rgb-2);
}
.software-item.active {
border-color: var(--color-secondary);
- background-color: rgba(255,107,53,0.1);
+ background-color: var(--color-orange-rgb-1);
}
.software-item.connected {
@@ -170,17 +170,17 @@ const testConnection = (software) => {
width: var(--size-connection-dot);
height: var(--size-connection-dot);
border-radius: 50%;
- border: 1px solid rgba(255,255,255,0.3);
+ border: 1px solid var(--color-white-rgb-3);
}
.connection-dot.connected {
background-color: var(--color-success);
- box-shadow: 0 0 6px rgba(76,175,80,0.5);
+ box-shadow: 0 0 6px var(--color-success-rgb-5);
}
.connection-dot.disconnected {
background-color: var(--color-error);
- box-shadow: 0 0 6px rgba(244,67,54,0.5);
+ box-shadow: 0 0 6px var(--color-error-rgb-3);
}
.connection-test-btn {
diff --git a/src/config/auth.js b/src/config/auth.js
index 43625ab..ebb8d34 100644
--- a/src/config/auth.js
+++ b/src/config/auth.js
@@ -41,6 +41,12 @@ const AUTH_CONFIG = {
TIMEOUTS: {
login: 5000, // 登录超时
validate: 3000 // 验证超时
+ },
+
+ // 验证规则
+ VALIDATION_RULES: {
+ MIN_USERNAME_LENGTH: 2, // 用户名最小长度
+ MIN_PASSWORD_LENGTH: 6 // 密码最小长度
}
}
@@ -78,6 +84,11 @@ export const getAuthTimeouts = () => {
return AUTH_CONFIG.TIMEOUTS
}
+// 获取验证规则
+export const getValidationRules = () => {
+ return AUTH_CONFIG.VALIDATION_RULES
+}
+
// 验证用户凭据(模拟验证)
export const validateCredentials = (username, password) => {
const mockCreds = getMockCredentials()
diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue
index d9b1b89..3399fc7 100644
--- a/src/views/DashboardView.vue
+++ b/src/views/DashboardView.vue
@@ -94,14 +94,79 @@
-
+
-
+
-
-
-
功能开发中
-
该功能正在开发中,敬请期待
+
+
+
+
+ MianyVue是一个专业的工业CAD模型管理平台,致力于为工程师和设计师提供统一的CAD软件集成解决方案。平台通过标准化的API接口连接主流CAD软件,实现跨平台的模型管理、分析和优化功能,显著提升工业设计和制造流程的效率与协作能力。
+
+
+
+
+
+
+
+ 核心能力
+
+
+
+
+
+ 多CAD软件统一管理
+
+
支持Creo、Revit、PDMS、AutoCAD、SolidWorks、CATIA等主流CAD软件,可根据需要扩展更多软件支持
+
+
+
+
+
+ 智能模型分析
+
+
提供层级结构分析、几何复杂度评估、薄壳分析等专业分析功能,帮助优化设计方案
+
+
+
+
+
+ 灵活导出支持
+
+
支持STEP、IGES、STL、IFC等多种工业标准格式,满足不同应用场景的数据交换需求
+
+
+
+
+
+ 实时状态监控
+
+
实时监控各CAD软件连接状态,确保系统稳定运行,提供详细的操作日志和性能指标
+
+
+
+
+
+
+
+
+ 技术特色
+
+
+
+ 基于Vue 3和现代Web技术构建,采用模块化架构设计,支持响应式界面和实时数据交互。平台遵循工业级安全标准,确保设计数据的安全性和可靠性。通过标准化API和微服务架构,实现高度的可扩展性和灵活的定制能力。
+
+
+
+
+
+
+
+
+ 请使用左侧导航菜单开始您的工作
+
+
@@ -120,7 +185,7 @@ import ContentArea from '@/components/layout/ContentArea.vue'
import BaseButton from '@/components/ui/BaseButton.vue'
// 当前页面状态
-const currentPage = ref('connection')
+const currentPage = ref('home')
// 导航点击处理
const handleNavClick = (navItem) => {
@@ -386,4 +451,148 @@ const openSettings = () => {
background: var(--color-white-rgb-15);
color: var(--color-text-primary);
}
+
+/* 欢迎页面样式 */
+.welcome-page {
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+ padding: 20px 0;
+ max-width: 800px;
+ margin: 0 auto;
+ line-height: 1.6;
+}
+
+.project-description {
+ text-align: center;
+ margin-bottom: 20px;
+}
+
+.project-description p {
+ font-size: 16px;
+ color: var(--color-text-secondary);
+ line-height: 1.8;
+ margin: 0;
+ padding: 0 20px;
+}
+
+.section-title {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-text-primary);
+ margin: 0 0 20px 0;
+ border-bottom: 2px solid var(--color-primary-rgb);
+ padding-bottom: 8px;
+}
+
+.section-title i {
+ color: var(--color-primary);
+ font-size: 20px;
+}
+
+.feature-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 20px;
+}
+
+.feature-item {
+ background: var(--color-white-rgb-05);
+ border: 1px solid var(--color-white-rgb-1);
+ border-radius: 8px;
+ padding: 20px;
+ transition: all 0.3s ease;
+}
+
+.feature-item:hover {
+ background: var(--color-white-rgb-1);
+ border-color: var(--color-white-rgb-2);
+ transform: translateY(-2px);
+}
+
+.feature-item h4 {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--color-text-primary);
+ margin: 0 0 12px 0;
+}
+
+.feature-item h4 i {
+ color: var(--color-primary);
+ font-size: 18px;
+ width: 20px;
+ text-align: center;
+}
+
+.feature-item p {
+ font-size: 14px;
+ color: var(--color-text-secondary);
+ line-height: 1.6;
+ margin: 0;
+}
+
+.tech-description p {
+ font-size: 15px;
+ color: var(--color-text-secondary);
+ line-height: 1.7;
+ margin: 0;
+ padding: 0 10px;
+ text-align: justify;
+}
+
+.guide-section {
+ text-align: center;
+ margin-top: 20px;
+ padding-top: 20px;
+ border-top: 1px solid var(--color-white-rgb-1);
+}
+
+.guide-text {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ font-size: 16px;
+ color: var(--color-text-tertiary);
+ background: var(--color-white-rgb-05);
+ padding: 12px 20px;
+ border-radius: 6px;
+ border: 1px solid var(--color-white-rgb-1);
+}
+
+.guide-text i {
+ color: var(--color-primary);
+ font-size: 18px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+ .welcome-page {
+ padding: 15px;
+ gap: 24px;
+ }
+
+ .feature-list {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ }
+
+ .project-description p {
+ font-size: 15px;
+ padding: 0 10px;
+ }
+
+ .section-title {
+ font-size: 16px;
+ }
+
+ .feature-item {
+ padding: 16px;
+ }
+}
\ No newline at end of file
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index 22c925e..d627560 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -128,10 +128,14 @@
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
+import { getValidationRules } from '@/config/auth'
const router = useRouter()
const authStore = useAuthStore()
+// 获取验证规则配置
+const validationRules = getValidationRules()
+
// 表单数据
const formData = ref({
username: '',
@@ -169,8 +173,8 @@ const validateField = (field) => {
case 'username':
if (!formData.value.username.trim()) {
errors.value.username = '请输入用户名'
- } else if (formData.value.username.length < 2) {
- errors.value.username = '用户名至少2个字符'
+ } else if (formData.value.username.length < validationRules.MIN_USERNAME_LENGTH) {
+ errors.value.username = `用户名至少${validationRules.MIN_USERNAME_LENGTH}个字符`
} else {
errors.value.username = ''
}
@@ -179,8 +183,8 @@ const validateField = (field) => {
case 'password':
if (!formData.value.password.trim()) {
errors.value.password = '请输入密码'
- } else if (formData.value.password.length < 6) {
- errors.value.password = '密码至少6个字符'
+ } else if (formData.value.password.length < validationRules.MIN_PASSWORD_LENGTH) {
+ errors.value.password = `密码至少${validationRules.MIN_PASSWORD_LENGTH}个字符`
} else {
errors.value.password = ''
}