463 lines
8.7 KiB
Markdown
463 lines
8.7 KiB
Markdown
---
|
||
name: design-system
|
||
description: "比赛管理系统设计规范。当用户提出页面开发需求时自动应用。主色: #0958d9 蓝色主题。包含: 颜色系统、间距、圆角、阴影、字体、组件规范(按钮、卡片、表单、标签)、页面布局、动画效果。适用: 新增页面、修改样式、组件开发、UI调整。"
|
||
---
|
||
|
||
# 比赛管理系统 - 设计规范 Skill
|
||
|
||
当用户提出页面开发、UI修改、组件创建等需求时,**必须遵循以下设计规范**。
|
||
|
||
---
|
||
|
||
## 快速开始
|
||
|
||
每个新页面的 `<style scoped lang="scss">` 开头必须包含以下变量:
|
||
|
||
```scss
|
||
// ==========================================
|
||
// 项目统一设计变量 - 必须复制
|
||
// ==========================================
|
||
$primary: #1890ff;
|
||
$primary-dark: #0958d9;
|
||
$primary-light: #40a9ff;
|
||
$secondary: #4096ff;
|
||
$success: #52c41a;
|
||
$warning: #faad14;
|
||
$error: #ff4d4f;
|
||
|
||
$background: #f5f7fa;
|
||
$surface: #ffffff;
|
||
|
||
$text: rgba(0, 0, 0, 0.85);
|
||
$text-secondary: rgba(0, 0, 0, 0.65);
|
||
$text-muted: rgba(0, 0, 0, 0.45);
|
||
|
||
$border: #d9d9d9;
|
||
$border-light: #e8e8e8;
|
||
|
||
$gradient-primary: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
|
||
```
|
||
|
||
---
|
||
|
||
## 色彩系统
|
||
|
||
### 主色(蓝色主题)
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `$primary` | `#1890ff` | 主色、按钮、链接 |
|
||
| `$primary-dark` | `#0958d9` | 渐变深色、激活态 |
|
||
| `$primary-light` | `#40a9ff` | 悬停态、浅色 |
|
||
| `$secondary` | `#4096ff` | 辅助蓝 |
|
||
|
||
### 功能色
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `$success` | `#52c41a` | 成功状态 |
|
||
| `$warning` | `#faad14` | 警告状态 |
|
||
| `$error` | `#ff4d4f` | 错误状态 |
|
||
|
||
### 中性色
|
||
|
||
| 变量 | 色值 | 用途 |
|
||
|------|------|------|
|
||
| `$background` | `#f5f5f5` | 页面背景 |
|
||
| `$surface` | `#ffffff` | 卡片/容器背景 |
|
||
| `$text` | `rgba(0,0,0,0.85)` | 主文本 |
|
||
| `$text-secondary` | `rgba(0,0,0,0.65)` | 次要文本 |
|
||
| `$text-muted` | `rgba(0,0,0,0.45)` | 弱化文本 |
|
||
| `$border-light` | `#e8e8e8` | 边框 |
|
||
|
||
---
|
||
|
||
## 间距规范
|
||
|
||
基于 **8px** 基准:
|
||
|
||
| 尺寸 | 值 | 场景 |
|
||
|------|------|------|
|
||
| xs | 4px | 图标间距 |
|
||
| sm | 8px | 元素内间距 |
|
||
| md | 12px | 卡片内元素 |
|
||
| base | 16px | 最常用 |
|
||
| lg | 20px | 区块间距 |
|
||
| xl | 24px | 大间距 |
|
||
| 2xl | 32px | 模块分隔 |
|
||
|
||
---
|
||
|
||
## 圆角规范
|
||
|
||
| 尺寸 | 值 | 场景 |
|
||
|------|------|------|
|
||
| sm | 4px | 小元素 |
|
||
| base | 6px | 默认 |
|
||
| md | 8px | 卡片 |
|
||
| lg | 10px | 返回按钮 |
|
||
| xl | 12px | 大卡片 |
|
||
| pill | 20px | 标签 |
|
||
| full | 50% | 头像 |
|
||
|
||
---
|
||
|
||
## 阴影规范
|
||
|
||
| 等级 | 定义 | 场景 |
|
||
|------|------|------|
|
||
| sm | `0 1px 2px rgba(0,0,0,0.03)` | 轻微 |
|
||
| base | `0 2px 8px rgba(0,0,0,0.06)` | 卡片默认 |
|
||
| md | `0 4px 12px rgba(0,0,0,0.08)` | 悬停 |
|
||
| lg | `0 8px 24px rgba(0,0,0,0.12)` | 弹窗 |
|
||
|
||
---
|
||
|
||
## 字体规范
|
||
|
||
| 层级 | 大小 | 权重 | 场景 |
|
||
|------|------|------|------|
|
||
| h1 | 36px | 700 | 大标题 |
|
||
| h2 | 26px | 700 | 区块标题 |
|
||
| h3 | 22px | 600 | 卡片标题 |
|
||
| h4 | 18px | 600 | 小标题 |
|
||
| body | 14px | 400 | 正文 |
|
||
| small | 12px | 400 | 标签 |
|
||
|
||
---
|
||
|
||
## 组件规范
|
||
|
||
### 返回按钮(统一样式)
|
||
|
||
```scss
|
||
.back-btn {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 10px !important;
|
||
border: 1px solid rgba($primary, 0.3) !important;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease !important;
|
||
|
||
&:hover {
|
||
background: rgba($primary, 0.1) !important;
|
||
border-color: $primary !important;
|
||
transform: translateY(-1px);
|
||
}
|
||
}
|
||
```
|
||
|
||
模板代码:
|
||
```vue
|
||
<a-button type="text" class="back-btn" @click="handleBack">
|
||
<template #icon><ArrowLeftOutlined /></template>
|
||
</a-button>
|
||
```
|
||
|
||
### 主按钮(渐变样式)
|
||
|
||
```scss
|
||
.primary-btn,
|
||
.gradient-btn {
|
||
background: linear-gradient(135deg, $primary 0%, $primary-dark 100%) !important;
|
||
border: none !important;
|
||
color: #fff !important;
|
||
font-weight: 500 !important;
|
||
border-radius: 20px !important;
|
||
padding: 6px 16px !important;
|
||
transition: all 0.3s ease !important;
|
||
box-shadow: 0 2px 8px rgba($primary, 0.3);
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 20px rgba($primary, 0.4);
|
||
}
|
||
}
|
||
|
||
// 用于 hero 区域的大按钮
|
||
.action-btn.primary {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 12px 28px;
|
||
border-radius: 24px;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
background: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
|
||
color: #fff;
|
||
border: none;
|
||
cursor: pointer;
|
||
box-shadow: 0 4px 15px rgba($primary, 0.4);
|
||
transition: all 0.3s;
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 20px rgba($primary, 0.5);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 卡片
|
||
|
||
```scss
|
||
.card {
|
||
background: $surface;
|
||
border: 1px solid $border-light;
|
||
border-radius: 8px;
|
||
padding: 16px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||
transition: all 0.3s ease;
|
||
|
||
&:hover {
|
||
border-color: rgba($primary, 0.3);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||
transform: translateY(-4px);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 标签
|
||
|
||
```scss
|
||
.tag {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 4px 12px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
|
||
&.tag-success {
|
||
background: rgba($success, 0.1);
|
||
color: $success;
|
||
border: 1px solid rgba($success, 0.3);
|
||
}
|
||
|
||
&.tag-primary {
|
||
background: rgba($primary, 0.1);
|
||
color: $primary;
|
||
border: 1px solid rgba($primary, 0.3);
|
||
}
|
||
|
||
&.tag-error {
|
||
background: rgba($error, 0.1);
|
||
color: $error;
|
||
border: 1px solid rgba($error, 0.3);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 面板/浮层
|
||
|
||
```scss
|
||
.panel {
|
||
background: rgba($surface, 0.85);
|
||
backdrop-filter: blur(20px);
|
||
border: 1px solid rgba($primary, 0.2);
|
||
border-radius: 12px;
|
||
|
||
.panel-header {
|
||
padding: 14px 16px;
|
||
background: rgba($primary, 0.05);
|
||
border-bottom: 1px solid rgba($primary, 0.1);
|
||
}
|
||
|
||
.panel-body {
|
||
padding: 16px;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 页面布局规范
|
||
|
||
### 页面头部(64px 高)
|
||
|
||
```scss
|
||
.page-header {
|
||
height: 64px;
|
||
padding: 0 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
background: $surface;
|
||
border-bottom: 1px solid #e8e8e8;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||
position: relative;
|
||
z-index: 10;
|
||
|
||
.header-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16px;
|
||
}
|
||
|
||
.title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
background: $gradient-primary;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 全屏页面容器
|
||
|
||
```scss
|
||
.fullscreen-page {
|
||
min-height: 100vh;
|
||
background: $background;
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.page-content {
|
||
flex: 1;
|
||
padding: 24px;
|
||
overflow: auto;
|
||
}
|
||
```
|
||
|
||
### 卡片网格
|
||
|
||
```scss
|
||
.card-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
|
||
gap: 20px;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 动画规范
|
||
|
||
### 过渡时间
|
||
|
||
- 标准过渡:`0.3s ease`
|
||
- 所有交互元素必须添加过渡
|
||
|
||
### 悬停效果
|
||
|
||
```scss
|
||
// 卡片悬停
|
||
transform: translateY(-4px);
|
||
|
||
// 按钮悬停
|
||
transform: translateY(-2px);
|
||
|
||
// 小元素悬停
|
||
transform: translateY(-1px);
|
||
```
|
||
|
||
### 常用动画
|
||
|
||
```scss
|
||
// 脉冲
|
||
@keyframes pulse {
|
||
0%, 100% { opacity: 1; transform: scale(1); }
|
||
50% { opacity: 0.5; transform: scale(0.8); }
|
||
}
|
||
|
||
// 旋转
|
||
@keyframes spin {
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 加载/错误状态
|
||
|
||
### 加载遮罩
|
||
|
||
```scss
|
||
.loading-overlay {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: $background;
|
||
z-index: 10;
|
||
}
|
||
```
|
||
|
||
### 错误卡片
|
||
|
||
```scss
|
||
.error-card {
|
||
text-align: center;
|
||
padding: 40px;
|
||
background: $surface;
|
||
border: 1px solid #e8e8e8;
|
||
border-radius: 16px;
|
||
|
||
.error-icon {
|
||
width: 60px;
|
||
height: 60px;
|
||
margin: 0 auto 20px;
|
||
background: $error;
|
||
border-radius: 50%;
|
||
color: #fff;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 滚动条
|
||
|
||
```scss
|
||
&::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
&::-webkit-scrollbar-track {
|
||
background: rgba($primary, 0.05);
|
||
}
|
||
&::-webkit-scrollbar-thumb {
|
||
background: rgba($primary, 0.3);
|
||
border-radius: 3px;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 响应式断点
|
||
|
||
```scss
|
||
$breakpoint-sm: 640px;
|
||
$breakpoint-md: 768px;
|
||
$breakpoint-lg: 1024px;
|
||
$breakpoint-xl: 1280px;
|
||
```
|
||
|
||
---
|
||
|
||
## 开发检查清单
|
||
|
||
新增页面必须确认:
|
||
|
||
- [ ] 复制了颜色变量到 style 开头
|
||
- [ ] 返回按钮使用 40x40px + 10px 圆角
|
||
- [ ] 卡片悬停有 `translateY(-4px)` 效果
|
||
- [ ] 页面头部高度 64px
|
||
- [ ] 所有过渡动画 0.3s
|
||
- [ ] 使用 `$gradient-primary` 作为主渐变
|
||
- [ ] 加载状态使用蓝色系
|
||
|
||
---
|
||
|
||
## 参考页面
|
||
|
||
- `frontend/src/views/workbench/ai-3d/Index.vue` - 3D Lab 主页
|
||
- `frontend/src/views/workbench/ai-3d/Generate.vue` - 生成页
|
||
- `frontend/src/views/model/ModelViewer.vue` - 模型预览页
|