2026-01-14 14:29:16 +08:00
|
|
|
|
---
|
|
|
|
|
|
name: design-system
|
|
|
|
|
|
description: "比赛管理系统设计规范。当用户提出页面开发需求时自动应用。主色: #0958d9 蓝色主题。包含: 颜色系统、间距、圆角、阴影、字体、组件规范(按钮、卡片、表单、标签)、页面布局、动画效果。适用: 新增页面、修改样式、组件开发、UI调整。"
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 比赛管理系统 - 设计规范 Skill
|
|
|
|
|
|
|
|
|
|
|
|
当用户提出页面开发、UI修改、组件创建等需求时,**必须遵循以下设计规范**。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 快速开始
|
|
|
|
|
|
|
|
|
|
|
|
每个新页面的 `<style scoped lang="scss">` 开头必须包含以下变量:
|
|
|
|
|
|
|
|
|
|
|
|
```scss
|
|
|
|
|
|
// ==========================================
|
|
|
|
|
|
// 项目统一设计变量 - 必须复制
|
|
|
|
|
|
// ==========================================
|
2026-01-16 14:48:14 +08:00
|
|
|
|
$primary: #1890ff;
|
|
|
|
|
|
$primary-dark: #0958d9;
|
|
|
|
|
|
$primary-light: #40a9ff;
|
2026-01-14 14:29:16 +08:00
|
|
|
|
$secondary: #4096ff;
|
|
|
|
|
|
$success: #52c41a;
|
|
|
|
|
|
$warning: #faad14;
|
|
|
|
|
|
$error: #ff4d4f;
|
|
|
|
|
|
|
2026-01-16 14:48:14 +08:00
|
|
|
|
$background: #f5f7fa;
|
2026-01-14 14:29:16 +08:00
|
|
|
|
$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;
|
|
|
|
|
|
|
2026-01-16 14:48:14 +08:00
|
|
|
|
$gradient-primary: linear-gradient(135deg, $primary 0%, $primary-dark 100%);
|
2026-01-14 14:29:16 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 色彩系统
|
|
|
|
|
|
|
|
|
|
|
|
### 主色(蓝色主题)
|
|
|
|
|
|
|
|
|
|
|
|
| 变量 | 色值 | 用途 |
|
|
|
|
|
|
|------|------|------|
|
2026-01-16 14:48:14 +08:00
|
|
|
|
| `$primary` | `#1890ff` | 主色、按钮、链接 |
|
|
|
|
|
|
| `$primary-dark` | `#0958d9` | 渐变深色、激活态 |
|
|
|
|
|
|
| `$primary-light` | `#40a9ff` | 悬停态、浅色 |
|
2026-01-14 14:29:16 +08:00
|
|
|
|
| `$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>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-01-16 14:48:14 +08:00
|
|
|
|
### 主按钮(渐变样式)
|
2026-01-14 14:29:16 +08:00
|
|
|
|
|
|
|
|
|
|
```scss
|
2026-01-16 14:48:14 +08:00
|
|
|
|
.primary-btn,
|
|
|
|
|
|
.gradient-btn {
|
|
|
|
|
|
background: linear-gradient(135deg, $primary 0%, $primary-dark 100%) !important;
|
2026-01-14 14:29:16 +08:00
|
|
|
|
border: none !important;
|
|
|
|
|
|
color: #fff !important;
|
|
|
|
|
|
font-weight: 500 !important;
|
2026-01-16 14:48:14 +08:00
|
|
|
|
border-radius: 20px !important;
|
|
|
|
|
|
padding: 6px 16px !important;
|
2026-01-14 14:29:16 +08:00
|
|
|
|
transition: all 0.3s ease !important;
|
2026-01-16 14:48:14 +08:00
|
|
|
|
box-shadow: 0 2px 8px rgba($primary, 0.3);
|
2026-01-14 14:29:16 +08:00
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
transform: translateY(-2px);
|
2026-01-16 14:48:14 +08:00
|
|
|
|
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);
|
2026-01-14 14:29:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 卡片
|
|
|
|
|
|
|
|
|
|
|
|
```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` - 模型预览页
|