feat: 初始化项目脚手架
This commit is contained in:
685
doc/design/01-前端架构设计.md
Normal file
685
doc/design/01-前端架构设计.md
Normal file
@@ -0,0 +1,685 @@
|
||||
# GameGroup 前端架构设计文档
|
||||
|
||||
**项目名称**: GameGroup 前端系统
|
||||
**文档版本**: v1.0
|
||||
**更新时间**: 2026-01-28
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [1. 项目概述](#1-项目概述)
|
||||
- [2. 技术栈选型](#2-技术栈选型)
|
||||
- [3. 项目架构](#3-项目架构)
|
||||
- [4. 目录结构](#4-目录结构)
|
||||
- [5. 核心设计原则](#5-核心设计原则)
|
||||
- [6. 状态管理](#6-状态管理)
|
||||
- [7. 路由设计](#7-路由设计)
|
||||
- [8. API请求层](#8-api请求层)
|
||||
- [9. 性能优化](#9-性能优化)
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
GameGroup 是一个游戏社群管理平台,为玩家提供小组管理、游戏预约、积分系统、竞猜等功能。前端项目采用现代化的技术栈,注重用户体验和性能优化。
|
||||
|
||||
### 核心功能模块
|
||||
|
||||
- **认证模块**: 用户注册、登录、令牌刷新
|
||||
- **用户中心**: 个人资料管理、设置
|
||||
- **小组管理**: 创建/加入小组、成员管理、权限控制
|
||||
- **游戏库**: 游戏浏览、搜索、筛选
|
||||
- **预约系统**: 创建预约、加入/退出预约、时间管理
|
||||
- **账目管理**: 账目记录、统计分析
|
||||
- **排班助手**: 空闲时间提交、共同时间查找
|
||||
- **荣誉墙**: 荣誉展示、时间轴
|
||||
- **资产管理**: 资产借用/归还、流转记录
|
||||
- **积分系统**: 积分查询、排行榜
|
||||
- **竞猜系统**: 创建竞猜、参与竞猜、结算
|
||||
|
||||
---
|
||||
|
||||
## 2. 技术栈选型
|
||||
|
||||
### 核心框架
|
||||
|
||||
```json
|
||||
{
|
||||
"framework": "Vue 3",
|
||||
"buildTool": "Vite",
|
||||
"language": "TypeScript",
|
||||
"router": "Vue Router 4",
|
||||
"stateManagement": "Pinia",
|
||||
"uiFramework": "Element Plus / Ant Design Vue",
|
||||
"cssFramework": "Tailwind CSS / UnoCSS",
|
||||
"http": "Axios"
|
||||
}
|
||||
```
|
||||
|
||||
### 选型理由
|
||||
|
||||
#### Vue 3 + TypeScript
|
||||
- **组合式 API**: 更好的逻辑复用和代码组织
|
||||
- **类型安全**: TypeScript提供完整的类型推导和检查
|
||||
- **性能提升**: 更小的包体积、更快的渲染
|
||||
- **生态成熟**: 丰富的插件和工具支持
|
||||
|
||||
#### Vite
|
||||
- **极速开发**: 基于ESM的即时热更新
|
||||
- **快速构建**: Rollup打包,生产环境优化
|
||||
- **现代化**: 原生支持ES模块、TypeScript、JSX
|
||||
|
||||
#### Pinia
|
||||
- **Vue 3官方推荐**: 替代Vuex的下一代状态管理
|
||||
- **类型友好**: 完整的TypeScript支持
|
||||
- **轻量简洁**: API设计简洁,学习成本低
|
||||
- **Devtools**: 优秀的开发者工具集成
|
||||
|
||||
#### Vue Router 4
|
||||
- **官方路由**: Vue生态标准路由方案
|
||||
- **动态路由**: 支持路由级代码分割
|
||||
- **导航守卫**: 完善的权限控制
|
||||
|
||||
---
|
||||
|
||||
## 3. 项目架构
|
||||
|
||||
### 3.1 分层架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Presentation Layer │
|
||||
│ (Components / Views / Layouts) │
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ Business Logic Layer │
|
||||
│ (Composables / Stores / Hooks) │
|
||||
└─────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────┐
|
||||
│ Data Access Layer │
|
||||
│ (API Services / Local Storage) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 模块化设计
|
||||
|
||||
每个功能模块包含:
|
||||
- **Views**: 页面级组件
|
||||
- **Components**: 模块内组件
|
||||
- **Composables**: 业务逻辑复用
|
||||
- **Stores**: 状态管理
|
||||
- **API**: 接口请求
|
||||
- **Types**: TypeScript类型定义
|
||||
- **Utils**: 工具函数
|
||||
|
||||
---
|
||||
|
||||
## 4. 目录结构
|
||||
|
||||
```
|
||||
GameGroupFE/
|
||||
├── public/ # 静态资源
|
||||
│ ├── favicon.ico
|
||||
│ └── ...
|
||||
├── src/
|
||||
│ ├── assets/ # 资源文件
|
||||
│ │ ├── images/ # 图片
|
||||
│ │ ├── icons/ # 图标
|
||||
│ │ └── styles/ # 全局样式
|
||||
│ │ ├── variables.scss # 样式变量
|
||||
│ │ ├── mixins.scss # 样式混入
|
||||
│ │ └── global.scss # 全局样式
|
||||
│ ├── components/ # 公共组件
|
||||
│ │ ├── common/ # 通用组件
|
||||
│ │ │ ├── Button/
|
||||
│ │ │ ├── Input/
|
||||
│ │ │ ├── Modal/
|
||||
│ │ │ └── Loading/
|
||||
│ │ ├── business/ # 业务组件
|
||||
│ │ │ ├── UserCard/
|
||||
│ │ │ ├── GroupCard/
|
||||
│ │ │ └── GameCard/
|
||||
│ │ └── layout/ # 布局组件
|
||||
│ │ ├── Header/
|
||||
│ │ ├── Sidebar/
|
||||
│ │ └── Footer/
|
||||
│ ├── composables/ # 组合式函数
|
||||
│ │ ├── useAuth.ts # 认证相关
|
||||
│ │ ├── useRequest.ts # 请求封装
|
||||
│ │ ├── usePagination.ts # 分页逻辑
|
||||
│ │ └── useWebSocket.ts # WebSocket
|
||||
│ ├── stores/ # Pinia状态管理
|
||||
│ │ ├── auth.ts # 认证状态
|
||||
│ │ ├── user.ts # 用户状态
|
||||
│ │ ├── group.ts # 小组状态
|
||||
│ │ └── app.ts # 应用状态
|
||||
│ ├── api/ # API接口
|
||||
│ │ ├── index.ts # Axios配置
|
||||
│ │ ├── auth.ts # 认证接口
|
||||
│ │ ├── user.ts # 用户接口
|
||||
│ │ ├── group.ts # 小组接口
|
||||
│ │ └── ...
|
||||
│ ├── router/ # 路由配置
|
||||
│ │ ├── index.ts # 路由入口
|
||||
│ │ ├── routes/ # 路由模块
|
||||
│ │ └── guards.ts # 路由守卫
|
||||
│ ├── views/ # 页面视图
|
||||
│ │ ├── auth/ # 认证相关页面
|
||||
│ │ │ ├── Login.vue
|
||||
│ │ │ └── Register.vue
|
||||
│ │ ├── home/ # 首页
|
||||
│ │ │ └── index.vue
|
||||
│ │ ├── user/ # 用户中心
|
||||
│ │ │ ├── Profile.vue
|
||||
│ │ │ └── Settings.vue
|
||||
│ │ ├── group/ # 小组管理
|
||||
│ │ │ ├── List.vue
|
||||
│ │ │ ├── Detail.vue
|
||||
│ │ │ └── Create.vue
|
||||
│ │ ├── game/ # 游戏库
|
||||
│ │ ├── appointment/ # 预约管理
|
||||
│ │ └── ...
|
||||
│ ├── types/ # TypeScript类型定义
|
||||
│ │ ├── api.ts # API响应类型
|
||||
│ │ ├── user.ts # 用户类型
|
||||
│ │ ├── group.ts # 小组类型
|
||||
│ │ └── ...
|
||||
│ ├── utils/ # 工具函数
|
||||
│ │ ├── request.ts # 请求工具
|
||||
│ │ ├── storage.ts # 存储工具
|
||||
│ │ ├── format.ts # 格式化工具
|
||||
│ │ └── validate.ts # 验证工具
|
||||
│ ├── constants/ # 常量定义
|
||||
│ │ ├── enums.ts # 枚举
|
||||
│ │ └── config.ts # 配置
|
||||
│ ├── directives/ # 自定义指令
|
||||
│ │ └── permission.ts
|
||||
│ ├── App.vue # 根组件
|
||||
│ └── main.ts # 应用入口
|
||||
├── tests/ # 测试文件
|
||||
│ ├── unit/ # 单元测试
|
||||
│ └── e2e/ # E2E测试
|
||||
├── .env.development # 开发环境变量
|
||||
├── .env.production # 生产环境变量
|
||||
├── .eslintrc.cjs # ESLint配置
|
||||
├── .prettierrc # Prettier配置
|
||||
├── tsconfig.json # TypeScript配置
|
||||
├── vite.config.ts # Vite配置
|
||||
├── tailwind.config.js # Tailwind配置
|
||||
└── package.json # 项目配置
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 核心设计原则
|
||||
|
||||
### 5.1 组件设计原则
|
||||
|
||||
#### 单一职责原则
|
||||
每个组件只负责一个功能,保持组件的独立性和可复用性。
|
||||
|
||||
#### 组合优于继承
|
||||
使用组合式API和props/events进行组件通信,避免复杂的继承关系。
|
||||
|
||||
#### 容器组件与展示组件分离
|
||||
- **容器组件**: 处理业务逻辑和状态管理
|
||||
- **展示组件**: 纯UI渲染,通过props接收数据
|
||||
|
||||
### 5.2 代码规范
|
||||
|
||||
#### 命名规范
|
||||
- **组件**: PascalCase (UserCard.vue)
|
||||
- **文件**: kebab-case (user-profile.ts)
|
||||
- **变量/函数**: camelCase (getUserInfo)
|
||||
- **常量**: UPPER_SNAKE_CASE (API_BASE_URL)
|
||||
- **类型/接口**: PascalCase (UserProfile)
|
||||
|
||||
#### 文件组织
|
||||
- 一个文件只导出一个主要内容
|
||||
- 相关文件放在同一目录
|
||||
- 使用index.ts统一导出
|
||||
|
||||
#### 注释规范
|
||||
```typescript
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param userId - 用户ID
|
||||
* @returns 用户信息对象
|
||||
*/
|
||||
async function getUserInfo(userId: string): Promise<User> {
|
||||
// 实现
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 状态管理
|
||||
|
||||
### 6.1 Pinia Store设计
|
||||
|
||||
#### 模块化Store
|
||||
每个业务模块创建独立的Store:
|
||||
|
||||
```typescript
|
||||
// stores/user.ts
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
// State
|
||||
const userInfo = ref<UserInfo | null>(null)
|
||||
const isLoading = ref(false)
|
||||
|
||||
// Getters
|
||||
const isLoggedIn = computed(() => !!userInfo.value)
|
||||
|
||||
// Actions
|
||||
async function fetchUserInfo() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const data = await userApi.getProfile()
|
||||
userInfo.value = data
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
isLoading,
|
||||
isLoggedIn,
|
||||
fetchUserInfo
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 全局Store
|
||||
应用级别的状态:
|
||||
|
||||
```typescript
|
||||
// stores/app.ts
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
const theme = ref<Theme>('light')
|
||||
const language = ref<Language>('zh-CN')
|
||||
const sidebarCollapsed = ref(false)
|
||||
|
||||
function toggleTheme() {
|
||||
theme.value = theme.value === 'light' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
return {
|
||||
theme,
|
||||
language,
|
||||
sidebarCollapsed,
|
||||
toggleTheme
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 6.2 持久化策略
|
||||
|
||||
使用`pinia-plugin-persistedstate`实现状态持久化:
|
||||
|
||||
```typescript
|
||||
// pinia.ts
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
|
||||
export default pinia
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 路由设计
|
||||
|
||||
### 7.1 路由结构
|
||||
|
||||
```typescript
|
||||
// router/index.ts
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: () => import('@/views/auth/Login.vue'),
|
||||
meta: { requiresAuth: false }
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/components/layout/MainLayout.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'Home',
|
||||
component: () => import('@/views/home/index.vue')
|
||||
},
|
||||
{
|
||||
path: 'groups',
|
||||
name: 'GroupList',
|
||||
component: () => import('@/views/group/List.vue')
|
||||
},
|
||||
{
|
||||
path: 'groups/:id',
|
||||
name: 'GroupDetail',
|
||||
component: () => import('@/views/group/Detail.vue')
|
||||
},
|
||||
// 更多路由...
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 7.2 路由守卫
|
||||
|
||||
```typescript
|
||||
// router/guards.ts
|
||||
router.beforeEach((to, from, next) => {
|
||||
const authStore = useAuthStore()
|
||||
const requiresAuth = to.meta.requiresAuth !== false
|
||||
|
||||
if (requiresAuth && !authStore.isLoggedIn) {
|
||||
// 未登录,跳转到登录页
|
||||
next({
|
||||
name: 'Login',
|
||||
query: { redirect: to.fullPath }
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. API请求层
|
||||
|
||||
### 8.1 Axios封装
|
||||
|
||||
```typescript
|
||||
// api/index.ts
|
||||
import axios from 'axios'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||
timeout: 15000
|
||||
})
|
||||
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
const authStore = useAuthStore()
|
||||
if (authStore.token) {
|
||||
config.headers.Authorization = `Bearer ${authStore.token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
const { code, message, data } = response.data
|
||||
|
||||
if (code === 0) {
|
||||
return data
|
||||
} else {
|
||||
ElMessage.error(message || '请求失败')
|
||||
return Promise.reject(new Error(message))
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
// Token过期,刷新Token或跳转登录
|
||||
const authStore = useAuthStore()
|
||||
authStore.logout()
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default service
|
||||
```
|
||||
|
||||
### 8.2 API模块化
|
||||
|
||||
```typescript
|
||||
// api/user.ts
|
||||
import request from './index'
|
||||
|
||||
export const userApi = {
|
||||
// 获取用户信息
|
||||
getProfile() {
|
||||
return request.get<UserInfo>('/users/me')
|
||||
},
|
||||
|
||||
// 更新用户信息
|
||||
updateProfile(data: UpdateProfileDto) {
|
||||
return request.put<UserInfo>('/users/me', data)
|
||||
},
|
||||
|
||||
// 修改密码
|
||||
changePassword(data: ChangePasswordDto) {
|
||||
return request.put('/users/me/password', data)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 性能优化
|
||||
|
||||
### 9.1 代码分割
|
||||
|
||||
#### 路由级代码分割
|
||||
使用动态import实现路由懒加载:
|
||||
|
||||
```typescript
|
||||
{
|
||||
path: '/groups',
|
||||
component: () => import('@/views/group/List.vue')
|
||||
}
|
||||
```
|
||||
|
||||
#### 组件级代码分割
|
||||
```vue
|
||||
<script setup>
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
const HeavyComponent = defineAsyncComponent(() =>
|
||||
import('./HeavyComponent.vue')
|
||||
)
|
||||
</script>
|
||||
```
|
||||
|
||||
### 9.2 资源优化
|
||||
|
||||
#### 图片优化
|
||||
- 使用WebP格式
|
||||
- 实现懒加载
|
||||
- 响应式图片
|
||||
|
||||
#### 依赖优化
|
||||
- Tree-shaking
|
||||
- 按需引入组件库
|
||||
- 使用轻量级替代方案
|
||||
|
||||
### 9.3 渲染优化
|
||||
|
||||
#### 虚拟滚动
|
||||
长列表使用虚拟滚动:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<VirtualList
|
||||
:items="largeList"
|
||||
:item-height="50"
|
||||
:visible-height="600"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 防抖与节流
|
||||
```typescript
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
|
||||
const search = useDebounceFn((keyword: string) => {
|
||||
// 执行搜索
|
||||
}, 300)
|
||||
```
|
||||
|
||||
### 9.4 缓存策略
|
||||
|
||||
#### 接口缓存
|
||||
```typescript
|
||||
// api/cache.ts
|
||||
const cache = new Map()
|
||||
|
||||
export async function cachedFetch<T>(
|
||||
key: string,
|
||||
fetcher: () => Promise<T>,
|
||||
ttl = 60000
|
||||
): Promise<T> {
|
||||
const cached = cache.get(key)
|
||||
if (cached && Date.now() - cached.time < ttl) {
|
||||
return cached.data
|
||||
}
|
||||
|
||||
const data = await fetcher()
|
||||
cache.set(key, { data, time: Date.now() })
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
#### 组件缓存
|
||||
```vue
|
||||
<KeepAlive :include="['GroupList', 'GameList']">
|
||||
<RouterView />
|
||||
</KeepAlive>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 开发工具链
|
||||
|
||||
### 10.1 代码质量
|
||||
|
||||
- **ESLint**: 代码规范检查
|
||||
- **Prettier**: 代码格式化
|
||||
- **Stylelint**: 样式规范检查
|
||||
- **TypeScript**: 类型检查
|
||||
|
||||
### 10.2 Git规范
|
||||
|
||||
- **Husky**: Git hooks
|
||||
- **lint-staged**: 暂存文件检查
|
||||
- **Commitlint**: 提交信息规范
|
||||
|
||||
### 10.3 CI/CD
|
||||
|
||||
- **GitHub Actions**: 自动化部署
|
||||
- **Vercel/Netlify**: 前端托管
|
||||
|
||||
---
|
||||
|
||||
## 11. 测试策略
|
||||
|
||||
### 11.1 单元测试
|
||||
|
||||
使用Vitest进行单元测试:
|
||||
|
||||
```typescript
|
||||
// tests/utils/format.test.ts
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { formatDate } from '@/utils/format'
|
||||
|
||||
describe('formatDate', () => {
|
||||
it('should format date correctly', () => {
|
||||
const date = new Date('2026-01-28')
|
||||
expect(formatDate(date)).toBe('2026-01-28')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 11.2 组件测试
|
||||
|
||||
使用Vue Test Utils:
|
||||
|
||||
```typescript
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Button from '@/components/common/Button/Button.vue'
|
||||
|
||||
describe('Button', () => {
|
||||
it('renders text', () => {
|
||||
const wrapper = mount(Button, {
|
||||
slots: { default: 'Click me' }
|
||||
})
|
||||
expect(wrapper.text()).toBe('Click me')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 部署方案
|
||||
|
||||
### 12.1 构建配置
|
||||
|
||||
```typescript
|
||||
// vite.config.ts
|
||||
export default defineConfig({
|
||||
build: {
|
||||
target: 'es2015',
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
sourcemap: false,
|
||||
minify: 'terser',
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true,
|
||||
drop_debugger: true
|
||||
}
|
||||
},
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
'vendor': ['vue', 'vue-router', 'pinia'],
|
||||
'ui': ['element-plus']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 12.2 环境变量
|
||||
|
||||
```bash
|
||||
# .env.development
|
||||
VITE_API_BASE_URL=http://localhost:3000/api
|
||||
|
||||
# .env.production
|
||||
VITE_API_BASE_URL=https://api.gamegroup.com/api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. 总结
|
||||
|
||||
本架构设计遵循以下原则:
|
||||
- ✅ 模块化: 清晰的模块划分,职责明确
|
||||
- ✅ 可维护性: 规范的代码组织,易于维护
|
||||
- ✅ 可扩展性: 灵活的架构设计,便于扩展
|
||||
- ✅ 性能优化: 多层次的优化策略
|
||||
- ✅ 开发体验: 完善的工具链支持
|
||||
|
||||
---
|
||||
|
||||
**文档维护**: 本文档应随项目演进持续更新
|
||||
**最后更新**: 2026-01-28
|
||||
867
doc/design/02-UI-UX设计规范.md
Normal file
867
doc/design/02-UI-UX设计规范.md
Normal file
@@ -0,0 +1,867 @@
|
||||
# GameGroup UI/UX 设计规范
|
||||
|
||||
**项目名称**: GameGroup 前端系统
|
||||
**文档版本**: v1.0
|
||||
**更新时间**: 2026-01-28
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [1. 设计理念](#1-设计理念)
|
||||
- [2. 视觉风格](#2-视觉风格)
|
||||
- [3. 色彩系统](#3-色彩系统)
|
||||
- [4. 字体系统](#4-字体系统)
|
||||
- [5. 间距系统](#5-间距系统)
|
||||
- [6. 组件规范](#6-组件规范)
|
||||
- [7. 动效规范](#7-动效规范)
|
||||
- [8. 响应式设计](#8-响应式设计)
|
||||
- [9. 无障碍设计](#9-无障碍设计)
|
||||
- [10. 设计资源](#10-设计资源)
|
||||
|
||||
---
|
||||
|
||||
## 1. 设计理念
|
||||
|
||||
### 1.1 核心价值
|
||||
|
||||
**活力与专业并重**
|
||||
- GameGroup作为游戏社群平台,既要体现游戏的活力与趣味性,又要保持管理工具的专业性与可靠性
|
||||
- 设计风格融合游戏化元素与现代UI设计,创造独特的视觉语言
|
||||
|
||||
**用户为中心**
|
||||
- 简洁直观的操作流程
|
||||
- 清晰的信息层级
|
||||
- 即时的反馈机制
|
||||
- 一致的交互体验
|
||||
|
||||
**性能优先**
|
||||
- 快速加载
|
||||
- 流畅动画
|
||||
- 高效交互
|
||||
|
||||
### 1.2 设计关键词
|
||||
|
||||
- **活力**: 充满动感,富有生命力
|
||||
- **简洁**: 去除冗余,聚焦核心
|
||||
- **直观**: 一目了然,易于理解
|
||||
- **有趣**: 愉悦体验,富有惊喜
|
||||
|
||||
---
|
||||
|
||||
## 2. 视觉风格
|
||||
|
||||
### 2.1 风格定位
|
||||
|
||||
**游戏化现代风格**
|
||||
|
||||
融合以下设计元素:
|
||||
- **游戏UI影响**: 动态卡片、徽章系统、进度条、成就展示
|
||||
- **现代扁平化**: 清晰的视觉层次,适度的阴影和渐变
|
||||
- **微交互动画**: 悬停效果、过渡动画、状态反馈
|
||||
- **高对比度**: 确保可读性和视觉冲击力
|
||||
|
||||
### 2.2 设计原则
|
||||
|
||||
#### 层次分明
|
||||
- 使用卡片容器分割内容
|
||||
- 利用阴影和z轴创建深度
|
||||
- 明确的视觉层级引导
|
||||
|
||||
#### 留白充足
|
||||
- 组件之间保持合理间距
|
||||
- 避免信息过载
|
||||
- 提升阅读舒适度
|
||||
|
||||
#### 一致性
|
||||
- 统一的视觉语言
|
||||
- 可预测的交互模式
|
||||
- 规范的设计系统
|
||||
|
||||
---
|
||||
|
||||
## 3. 色彩系统
|
||||
|
||||
### 3.1 主色调 (Primary Colors)
|
||||
|
||||
```css
|
||||
/* 主色 - 游戏紫 */
|
||||
--color-primary-50: #f5f3ff;
|
||||
--color-primary-100: #ede9fe;
|
||||
--color-primary-200: #ddd6fe;
|
||||
--color-primary-300: #c4b5fd;
|
||||
--color-primary-400: #a78bfa;
|
||||
--color-primary-500: #8b5cf6; /* 主色 */
|
||||
--color-primary-600: #7c3aed;
|
||||
--color-primary-700: #6d28d9;
|
||||
--color-primary-800: #5b21b6;
|
||||
--color-primary-900: #4c1d95;
|
||||
|
||||
/* 强调色 - 活力橙 */
|
||||
--color-accent-50: #fff7ed;
|
||||
--color-accent-100: #ffedd5;
|
||||
--color-accent-200: #fed7aa;
|
||||
--color-accent-300: #fdba74;
|
||||
--color-accent-400: #fb923c;
|
||||
--color-accent-500: #f97316; /* 强调色 */
|
||||
--color-accent-600: #ea580c;
|
||||
--color-accent-700: #c2410c;
|
||||
--color-accent-800: #9a3412;
|
||||
--color-accent-900: #7c2d12;
|
||||
```
|
||||
|
||||
### 3.2 中性色 (Neutral Colors)
|
||||
|
||||
```css
|
||||
/* 深色模式 */
|
||||
--color-gray-50: #f9fafb;
|
||||
--color-gray-100: #f3f4f6;
|
||||
--color-gray-200: #e5e7eb;
|
||||
--color-gray-300: #d1d5db;
|
||||
--color-gray-400: #9ca3af;
|
||||
--color-gray-500: #6b7280;
|
||||
--color-gray-600: #4b5563;
|
||||
--color-gray-700: #374151;
|
||||
--color-gray-800: #1f2937;
|
||||
--color-gray-900: #111827;
|
||||
|
||||
/* 浅色模式 */
|
||||
--color-text-primary: #1f2937;
|
||||
--color-text-secondary: #6b7280;
|
||||
--color-text-tertiary: #9ca3af;
|
||||
--color-bg-primary: #ffffff;
|
||||
--color-bg-secondary: #f9fafb;
|
||||
--color-bg-tertiary: #f3f4f6;
|
||||
--color-border: #e5e7eb;
|
||||
```
|
||||
|
||||
### 3.3 功能色 (Semantic Colors)
|
||||
|
||||
```css
|
||||
/* 成功 - 绿色 */
|
||||
--color-success-50: #f0fdf4;
|
||||
--color-success-100: #dcfce7;
|
||||
--color-success-500: #22c55e;
|
||||
--color-success-700: #15803d;
|
||||
|
||||
/* 警告 - 黄色 */
|
||||
--color-warning-50: #fffbeb;
|
||||
--color-warning-100: #fef3c7;
|
||||
--color-warning-500: #eab308;
|
||||
--color-warning-700: #a16207;
|
||||
|
||||
/* 错误 - 红色 */
|
||||
--color-error-50: #fef2f2;
|
||||
--color-error-100: #fee2e2;
|
||||
--color-error-500: #ef4444;
|
||||
--color-error-700: #b91c1c;
|
||||
|
||||
/* 信息 - 蓝色 */
|
||||
--color-info-50: #eff6ff;
|
||||
--color-info-100: #dbeafe;
|
||||
--color-info-500: #3b82f6;
|
||||
--color-info-700: #1d4ed8;
|
||||
```
|
||||
|
||||
### 3.4 游戏主题色
|
||||
|
||||
用于游戏相关的特殊标识和游戏化元素:
|
||||
|
||||
```css
|
||||
/* 游戏类型颜色 */
|
||||
--game-moba: #8b5cf6; /* MOBA - 紫色 */
|
||||
--game-fps: #ef4444; /* FPS - 红色 */
|
||||
--game-rpg: #22c55e; /* RPG - 绿色 */
|
||||
--game-strategy: #3b82f6; /* 策略 - 蓝色 */
|
||||
--game-racing: #f97316; /* 竞速 - 橙色 */
|
||||
--game-sports: #eab308; /* 体育 - 黄色 */
|
||||
--game-card: #ec4899; /* 卡牌 - 粉色 */
|
||||
--game-puzzle: #06b6d4; /* 益智 - 青色 */
|
||||
```
|
||||
|
||||
### 3.5 使用规范
|
||||
|
||||
#### 色彩搭配原则
|
||||
- **主色占比**: 60% - 用于主要操作、品牌标识
|
||||
- **中性色占比**: 30% - 用于背景、文本
|
||||
- **强调色占比**: 10% - 用于重点突出、引导注意
|
||||
|
||||
#### 对比度要求
|
||||
- 文本与背景对比度 ≥ 4.5:1 (WCAG AA标准)
|
||||
- 重要元素对比度 ≥ 7:1 (WCAG AAA标准)
|
||||
|
||||
---
|
||||
|
||||
## 4. 字体系统
|
||||
|
||||
### 4.1 字体家族
|
||||
|
||||
```css
|
||||
/* 主字体 - 思源黑体 (中文) + Inter (英文/数字) */
|
||||
--font-family-base: "Source Han Sans CN", "Inter", -apple-system,
|
||||
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif;
|
||||
|
||||
/* 代码字体 */
|
||||
--font-family-mono: "JetBrains Mono", "Fira Code", "Courier New",
|
||||
monospace;
|
||||
|
||||
/* 数字字体 - 用于数据显示 */
|
||||
--font-family-number: "Inter", "Roboto Mono", monospace;
|
||||
```
|
||||
|
||||
### 4.2 字体大小
|
||||
|
||||
```css
|
||||
/* 标题 */
|
||||
--font-size-h1: 2.5rem; /* 40px */
|
||||
--font-size-h2: 2rem; /* 32px */
|
||||
--font-size-h3: 1.5rem; /* 24px */
|
||||
--font-size-h4: 1.25rem; /* 20px */
|
||||
--font-size-h5: 1.125rem; /* 18px */
|
||||
--font-size-h6: 1rem; /* 16px */
|
||||
|
||||
/* 正文 */
|
||||
--font-size-large: 1rem; /* 16px */
|
||||
--font-size-base: 0.875rem; /* 14px */
|
||||
--font-size-small: 0.75rem; /* 12px */
|
||||
--font-size-xs: 0.625rem; /* 10px */
|
||||
```
|
||||
|
||||
### 4.3 字重
|
||||
|
||||
```css
|
||||
--font-weight-light: 300;
|
||||
--font-weight-normal: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-semibold: 600;
|
||||
--font-weight-bold: 700;
|
||||
```
|
||||
|
||||
### 4.4 行高
|
||||
|
||||
```css
|
||||
--line-height-tight: 1.25;
|
||||
--line-height-normal: 1.5;
|
||||
--line-height-relaxed: 1.75;
|
||||
```
|
||||
|
||||
### 4.5 使用规范
|
||||
|
||||
| 元素 | 字体大小 | 字重 | 行高 |
|
||||
|------|---------|------|------|
|
||||
| 页面标题 | H1 (40px) | Bold (700) | 1.25 |
|
||||
| 区块标题 | H2 (32px) | Semibold (600) | 1.25 |
|
||||
| 卡片标题 | H4 (20px) | Semibold (600) | 1.5 |
|
||||
| 正文内容 | Base (14px) | Normal (400) | 1.5 |
|
||||
| 辅助文字 | Small (12px) | Normal (400) | 1.5 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 间距系统
|
||||
|
||||
### 5.1 间距尺度
|
||||
|
||||
采用4px基准的间距系统:
|
||||
|
||||
```css
|
||||
--spacing-0: 0;
|
||||
--spacing-1: 0.25rem; /* 4px */
|
||||
--spacing-2: 0.5rem; /* 8px */
|
||||
--spacing-3: 0.75rem; /* 12px */
|
||||
--spacing-4: 1rem; /* 16px */
|
||||
--spacing-5: 1.25rem; /* 20px */
|
||||
--spacing-6: 1.5rem; /* 24px */
|
||||
--spacing-8: 2rem; /* 32px */
|
||||
--spacing-10: 2.5rem; /* 40px */
|
||||
--spacing-12: 3rem; /* 48px */
|
||||
--spacing-16: 4rem; /* 64px */
|
||||
--spacing-20: 5rem; /* 80px */
|
||||
```
|
||||
|
||||
### 5.2 使用场景
|
||||
|
||||
| 场景 | 间距值 | 用途 |
|
||||
|------|--------|------|
|
||||
| 组件内边距 | spacing-4 (16px) | 按钮内边距、卡片内边距 |
|
||||
| 组件间距 | spacing-6 (24px) | 卡片之间的间距 |
|
||||
| 区块间距 | spacing-8 (32px) | 页面区块之间的间距 |
|
||||
| 页面边距 | spacing-6 (24px) | 内容与页面边缘的间距 |
|
||||
| 紧凑间距 | spacing-2 (8px) | 标签、徽章等小元素 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 组件规范
|
||||
|
||||
### 6.1 按钮 (Button)
|
||||
|
||||
#### 主要按钮 (Primary)
|
||||
```css
|
||||
/* 样式 */
|
||||
background: var(--color-primary-500);
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
|
||||
/* 悬停 */
|
||||
background: var(--color-primary-600);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3);
|
||||
|
||||
/* 点击 */
|
||||
transform: translateY(0);
|
||||
```
|
||||
|
||||
#### 次要按钮 (Secondary)
|
||||
```css
|
||||
background: transparent;
|
||||
color: var(--color-primary-500);
|
||||
border: 2px solid var(--color-primary-500);
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
font-weight: 600;
|
||||
```
|
||||
|
||||
#### 文字按钮 (Text)
|
||||
```css
|
||||
background: transparent;
|
||||
color: var(--color-primary-500);
|
||||
padding: 8px 12px;
|
||||
font-weight: 500;
|
||||
|
||||
/* 悬停 */
|
||||
background: var(--color-primary-50);
|
||||
```
|
||||
|
||||
#### 尺寸规范
|
||||
- **Large**: 48px高度, 16px字体
|
||||
- **Medium**: 40px高度, 14px字体 (默认)
|
||||
- **Small**: 32px高度, 12px字体
|
||||
|
||||
### 6.2 卡片 (Card)
|
||||
|
||||
```css
|
||||
/* 基础卡片 */
|
||||
background: var(--color-bg-primary);
|
||||
border-radius: 12px;
|
||||
padding: var(--spacing-6);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s;
|
||||
|
||||
/* 悬停效果 */
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
```
|
||||
|
||||
#### 卡片类型
|
||||
- **基础卡片**: 标准卡片样式
|
||||
- **可点击卡片**: 带悬停效果
|
||||
- **游戏卡片**: 带封面图和标签
|
||||
|
||||
### 6.3 输入框 (Input)
|
||||
|
||||
```css
|
||||
/* 样式 */
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: 8px;
|
||||
padding: 10px 14px;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
|
||||
/* 聚焦状态 */
|
||||
border-color: var(--color-primary-500);
|
||||
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
|
||||
outline: none;
|
||||
|
||||
/* 错误状态 */
|
||||
border-color: var(--color-error-500);
|
||||
```
|
||||
|
||||
### 6.4 徽章 (Badge)
|
||||
|
||||
```css
|
||||
/* 基础样式 */
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px 10px;
|
||||
border-radius: 9999px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
|
||||
/* 类型 */
|
||||
.badge-primary { background: var(--color-primary-100); color: var(--color-primary-700); }
|
||||
.badge-success { background: var(--color-success-100); color: var(--color-success-700); }
|
||||
.badge-warning { background: var(--color-warning-100); color: var(--color-warning-700); }
|
||||
.badge-error { background: var(--color-error-100); color: var(--color-error-700); }
|
||||
```
|
||||
|
||||
### 6.5 头像 (Avatar)
|
||||
|
||||
```css
|
||||
/* 尺寸 */
|
||||
.avatar-xs { width: 24px; height: 24px; }
|
||||
.avatar-sm { width: 32px; height: 32px; }
|
||||
.avatar-md { width: 40px; height: 40px; }
|
||||
.avatar-lg { width: 56px; height: 56px; }
|
||||
.avatar-xl { width: 80px; height: 80px; }
|
||||
|
||||
/* 样式 */
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--color-border);
|
||||
```
|
||||
|
||||
### 6.6 进度条 (Progress)
|
||||
|
||||
```css
|
||||
/* 容器 */
|
||||
height: 8px;
|
||||
background: var(--color-bg-tertiary);
|
||||
border-radius: 9999px;
|
||||
overflow: hidden;
|
||||
|
||||
/* 进度 */
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, var(--color-primary-400), var(--color-primary-600));
|
||||
border-radius: 9999px;
|
||||
transition: width 0.3s;
|
||||
```
|
||||
|
||||
### 6.7 标签 (Tag)
|
||||
|
||||
用于游戏标签、技能标签等:
|
||||
|
||||
```css
|
||||
/* 样式 */
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
background: var(--color-bg-tertiary);
|
||||
color: var(--color-text-secondary);
|
||||
gap: 4px;
|
||||
|
||||
/* 游戏类型标签 - 不同颜色 */
|
||||
.tag-moba { background: var(--game-moba); color: white; }
|
||||
.tag-fps { background: var(--game-fps); color: white; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 动效规范
|
||||
|
||||
### 7.1 动画时长
|
||||
|
||||
```css
|
||||
--duration-fast: 150ms;
|
||||
--duration-base: 200ms;
|
||||
--duration-slow: 300ms;
|
||||
--duration-slower: 500ms;
|
||||
```
|
||||
|
||||
### 7.2 缓动函数
|
||||
|
||||
```css
|
||||
/* 标准 */
|
||||
--ease-default: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
/* 进入 */
|
||||
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||||
|
||||
/* 离开 */
|
||||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||
|
||||
/* 弹性 */
|
||||
--ease-elastic: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
```
|
||||
|
||||
### 7.3 常用动效
|
||||
|
||||
#### 淡入淡出 (Fade)
|
||||
```css
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
```
|
||||
|
||||
#### 滑动 (Slide)
|
||||
```css
|
||||
@keyframes slideInUp {
|
||||
from {
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 缩放 (Scale)
|
||||
```css
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
transform: scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 骨架屏加载 (Skeleton)
|
||||
```css
|
||||
@keyframes skeleton-loading {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
.skeleton {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
var(--color-bg-tertiary) 25%,
|
||||
var(--color-bg-secondary) 50%,
|
||||
var(--color-bg-tertiary) 75%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
}
|
||||
```
|
||||
|
||||
### 7.4 微交互
|
||||
|
||||
#### 按钮点击
|
||||
```css
|
||||
button:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
```
|
||||
|
||||
#### 卡片悬停
|
||||
```css
|
||||
.card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
```
|
||||
|
||||
#### 链接下划线动画
|
||||
```css
|
||||
.link {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.link::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--color-primary-500);
|
||||
transition: width var(--duration-base);
|
||||
}
|
||||
|
||||
.link:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 响应式设计
|
||||
|
||||
### 8.1 断点系统
|
||||
|
||||
```css
|
||||
/* 断点 */
|
||||
--breakpoint-xs: 0px; /* 手机竖屏 */
|
||||
--breakpoint-sm: 640px; /* 手机横屏 */
|
||||
--breakpoint-md: 768px; /* 平板竖屏 */
|
||||
--breakpoint-lg: 1024px; /* 平板横屏 / 小笔记本 */
|
||||
--breakpoint-xl: 1280px; /* 桌面 */
|
||||
--breakpoint-2xl: 1536px; /* 大屏幕 */
|
||||
```
|
||||
|
||||
### 8.2 响应式策略
|
||||
|
||||
#### 移动优先
|
||||
从最小屏幕开始设计,逐步增强:
|
||||
|
||||
```css
|
||||
/* 移动端 (默认) */
|
||||
.container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
/* 平板及以上 */
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面 */
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
padding: 32px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 隐藏元素
|
||||
```css
|
||||
/* 移动端隐藏 */
|
||||
.hidden-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.hidden-mobile {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面端隐藏 */
|
||||
.hidden-desktop {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.hidden-desktop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 布局适配
|
||||
|
||||
#### 导航栏
|
||||
- **移动端**: 底部导航栏或汉堡菜单
|
||||
- **平板**: 侧边栏
|
||||
- **桌面**: 顶部导航 + 侧边栏
|
||||
|
||||
#### 网格系统
|
||||
```css
|
||||
/* 移动: 1列 */
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* 平板: 2列 */
|
||||
@media (min-width: 768px) {
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面: 3-4列 */
|
||||
@media (min-width: 1024px) {
|
||||
.grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 无障碍设计
|
||||
|
||||
### 9.1 键盘导航
|
||||
|
||||
- **Tab顺序**: 逻辑清晰的焦点顺序
|
||||
- **焦点可见**: 明确的焦点样式
|
||||
- **快捷键**: 支持常用操作快捷键
|
||||
|
||||
```css
|
||||
/* 焦点样式 */
|
||||
*:focus-visible {
|
||||
outline: 2px solid var(--color-primary-500);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
```
|
||||
|
||||
### 9.2 屏幕阅读器
|
||||
|
||||
```html
|
||||
<!-- 语义化HTML -->
|
||||
<button aria-label="关闭对话框">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
<!-- 图标 + 文字 -->
|
||||
<button>
|
||||
<svg aria-hidden="true">...</svg>
|
||||
<span>保存</span>
|
||||
</button>
|
||||
```
|
||||
|
||||
### 9.3 色盲友好
|
||||
|
||||
不仅依赖颜色传达信息:
|
||||
- 使用图标 + 颜色
|
||||
- 添加文字说明
|
||||
- 提供高对比度模式
|
||||
|
||||
---
|
||||
|
||||
## 10. 设计资源
|
||||
|
||||
### 10.1 设计工具
|
||||
|
||||
- **Figma**: 主要设计工具
|
||||
- **Iconify**: 图标库
|
||||
- **Coolors**: 配色方案生成
|
||||
- **Type Scale**: 字体比例计算
|
||||
|
||||
### 10.2 图标系统
|
||||
|
||||
推荐使用以下图标库:
|
||||
- **Heroicons**: 简洁现代
|
||||
- **Lucide Icons**: 统一风格
|
||||
- **Phosphor Icons**: 丰富选择
|
||||
|
||||
图标尺寸:
|
||||
- **XS**: 16px
|
||||
- **SM**: 20px
|
||||
- **MD**: 24px (默认)
|
||||
- **LG**: 32px
|
||||
- **XL**: 48px
|
||||
|
||||
### 10.3 图片规范
|
||||
|
||||
#### 头像
|
||||
- **尺寸**: 200x200px最小
|
||||
- **格式**: JPG/WebP
|
||||
- **质量**: 80%以上
|
||||
|
||||
#### 游戏封面
|
||||
- **尺寸**: 16:9比例
|
||||
- **最小宽度**: 640px
|
||||
- **格式**: WebP优先
|
||||
|
||||
#### 截图
|
||||
- **尺寸**: 原始分辨率
|
||||
- **格式**: WebP/PNG
|
||||
- **压缩**: 无损或有损80%
|
||||
|
||||
---
|
||||
|
||||
## 11. 组件示例
|
||||
|
||||
### 11.1 用户卡片
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="user-card">
|
||||
<div class="user-card__avatar">
|
||||
<img :src="user.avatar" :alt="user.username" />
|
||||
</div>
|
||||
<div class="user-card__info">
|
||||
<h4 class="user-card__name">{{ user.nickname || user.username }}</h4>
|
||||
<p class="user-card__role">{{ roleText }}</p>
|
||||
<div class="user-card__badges">
|
||||
<Badge v-if="user.isMember" type="primary">会员</Badge>
|
||||
<Badge v-if="isOnline" type="success">在线</Badge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.user-card {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.user-card:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.user-card__avatar img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.user-card__role {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-secondary);
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 11.2 游戏卡片
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="game-card" @click="handleClick">
|
||||
<div class="game-card__cover">
|
||||
<img :src="game.coverUrl" :alt="game.name" />
|
||||
<div class="game-card__overlay">
|
||||
<Button type="primary" size="small">查看详情</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="game-card__content">
|
||||
<div class="game-card__tags">
|
||||
<Tag
|
||||
v-for="tag in game.tags"
|
||||
:key="tag"
|
||||
:type="getGameTagType(tag)"
|
||||
>
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<h4 class="game-card__title">{{ game.name }}</h4>
|
||||
<p class="game-card__players">
|
||||
{{ game.minPlayers }}-{{ game.maxPlayers }}人
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 总结
|
||||
|
||||
本设计规范确保:
|
||||
- ✅ **视觉一致性**: 统一的设计语言
|
||||
- ✅ **开发效率**: 规范化的组件库
|
||||
- ✅ **用户体验**: 直观友好的交互
|
||||
- ✅ **品牌识别**: 独特的视觉风格
|
||||
- ✅ **可维护性**: 系统化的设计系统
|
||||
|
||||
---
|
||||
|
||||
**文档维护**: 随产品迭代持续更新
|
||||
**最后更新**: 2026-01-28
|
||||
**设计负责**: Frontend Team
|
||||
1099
doc/design/03-组件设计文档.md
Normal file
1099
doc/design/03-组件设计文档.md
Normal file
File diff suppressed because it is too large
Load Diff
826
doc/design/04-页面设计文档.md
Normal file
826
doc/design/04-页面设计文档.md
Normal file
@@ -0,0 +1,826 @@
|
||||
# GameGroup 页面设计文档
|
||||
|
||||
**项目名称**: GameGroup 前端系统
|
||||
**文档版本**: v1.0
|
||||
**更新时间**: 2026-01-28
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
- [1. 页面架构](#1-页面架构)
|
||||
- [2. 认证页面](#2-认证页面)
|
||||
- [3. 首页](#3-首页)
|
||||
- [4. 用户中心](#4-用户中心)
|
||||
- [5. 小组管理](#5-小组管理)
|
||||
- [6. 游戏库](#6-游戏库)
|
||||
- [7. 预约管理](#7-预约管理)
|
||||
- [8. 积分排行](#8-积分排行)
|
||||
- [9. 荣誉墙](#9-荣誉墙)
|
||||
|
||||
---
|
||||
|
||||
## 1. 页面架构
|
||||
|
||||
### 1.1 页面层级
|
||||
|
||||
```
|
||||
页面层级
|
||||
├── 公共页面 (Public)
|
||||
│ ├── 登录页 (/login)
|
||||
│ ├── 注册页 (/register)
|
||||
│ └── 找回密码 (/forgot-password)
|
||||
│
|
||||
├── 主应用页面 (App)
|
||||
│ ├── 首页 (/)
|
||||
│ ├── 用户中心 (/user)
|
||||
│ │ ├── 个人资料 (/user/profile)
|
||||
│ │ └── 设置 (/user/settings)
|
||||
│ ├── 小组管理 (/groups)
|
||||
│ │ ├── 小组列表 (/groups)
|
||||
│ │ ├── 小组详情 (/groups/:id)
|
||||
│ │ └── 创建小组 (/groups/create)
|
||||
│ ├── 游戏库 (/games)
|
||||
│ │ ├── 游戏列表 (/games)
|
||||
│ │ └── 游戏详情 (/games/:id)
|
||||
│ ├── 预约管理 (/appointments)
|
||||
│ │ ├── 预约列表 (/appointments)
|
||||
│ │ └── 预约详情 (/appointments/:id)
|
||||
│ ├── 积分系统 (/points)
|
||||
│ │ ├── 我的积分 (/points/me)
|
||||
│ │ └── 排行榜 (/points/ranking)
|
||||
│ └── 荣誉墙 (/honors)
|
||||
│
|
||||
└── 管理页面 (Admin)
|
||||
├── 黑名单管理 (/admin/blacklist)
|
||||
└── 系统设置 (/admin/settings)
|
||||
```
|
||||
|
||||
### 1.2 布局模式
|
||||
|
||||
#### 主布局 (MainLayout)
|
||||
适用于大部分应用页面,包含:
|
||||
- 顶部导航栏
|
||||
- 侧边栏菜单
|
||||
- 主内容区域
|
||||
- 底部信息栏
|
||||
|
||||
#### 认证布局 (AuthLayout)
|
||||
适用于登录、注册页面:
|
||||
- 居中的表单卡片
|
||||
- 简洁的背景
|
||||
- 无导航栏
|
||||
|
||||
#### 空白布局 (EmptyLayout)
|
||||
适用于特殊页面:
|
||||
- 无导航
|
||||
- 无侧边栏
|
||||
- 全屏内容
|
||||
|
||||
---
|
||||
|
||||
## 2. 认证页面
|
||||
|
||||
### 2.1 登录页 (/login)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ [Logo + GameGroup] │
|
||||
│ │
|
||||
│ ┌───────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ 登录表单 │ │
|
||||
│ │ │ │
|
||||
│ │ [账号] │ │
|
||||
│ │ [密码] │ │
|
||||
│ │ [登录按钮] │ │
|
||||
│ │ │ │
|
||||
│ │ 忘记密码? │ │
|
||||
│ │ 还没有账号?注册 │ │
|
||||
│ │ │ │
|
||||
│ └───────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 设计要点
|
||||
|
||||
- **视觉焦点**: 居中的表单卡片,阴影突出
|
||||
- **背景**: 使用渐变色或游戏主题图片
|
||||
- **动画**: 表单淡入动画
|
||||
- **交互**: 输入框焦点动画,按钮悬停效果
|
||||
|
||||
#### 表单字段
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 账号 | text | 是 | 用户名/邮箱/手机号 |
|
||||
| 密码 | password | 是 | 密码,支持显示切换 |
|
||||
| 记住我 | checkbox | 否 | 记住登录状态 |
|
||||
|
||||
#### 交互流程
|
||||
|
||||
1. 用户输入账号密码
|
||||
2. 点击登录或按Enter键
|
||||
3. 显示加载状态
|
||||
4. 登录成功 → 跳转到首页
|
||||
5. 登录失败 → 显示错误提示
|
||||
|
||||
---
|
||||
|
||||
### 2.2 注册页 (/register)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
与登录页类似,但表单字段更多。
|
||||
|
||||
#### 表单字段
|
||||
|
||||
| 字段 | 类型 | 必填 | 验证规则 |
|
||||
|------|------|------|----------|
|
||||
| 用户名 | text | 是 | 3-20字符,字母数字下划线 |
|
||||
| 邮箱 | email | 否 | 有效邮箱格式 |
|
||||
| 手机号 | tel | 否 | 11位手机号 |
|
||||
| 密码 | password | 是 | 6-20字符 |
|
||||
| 确认密码 | password | 是 | 与密码一致 |
|
||||
|
||||
#### 验证逻辑
|
||||
|
||||
- 实时验证: 失焦时验证单个字段
|
||||
- 提交验证: 提交时验证所有字段
|
||||
- 异步验证: 用户名唯一性检查
|
||||
|
||||
---
|
||||
|
||||
## 3. 首页
|
||||
|
||||
### 3.1 首页布局 (/)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [Logo] [导航菜单] [搜索] [用户] │
|
||||
├──────┬──────────────────────────────────────┤
|
||||
│ │ ┌────────────────────────────────┐ │
|
||||
│ │ │ 欢迎,XXX │ │
|
||||
│ 侧 │ │ 今日有3个预约待参加 │ │
|
||||
│ 边 │ └────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ 栏 │ ┌──────────┐ ┌──────────────────┐ │
|
||||
│ │ │我的小组 │ │ 即将开始的活动 │ │
|
||||
│ │ │ (5) │ │ • 王者荣耀今晚...│ │
|
||||
│ │ │ │ │ • 周末桌游局 │ │
|
||||
│ │ │[查看全部]│ │ • FPS竞技训练 │ │
|
||||
│ │ └──────────┘ └──────────────────┘ │
|
||||
│ │ │
|
||||
│ │ ┌────────────────────────────────┐ │
|
||||
│ │ │ 热门游戏 │ │
|
||||
│ │ │ [游戏卡片1][游戏卡片2]... │ │
|
||||
│ │ └────────────────────────────────┘ │
|
||||
│ │ │
|
||||
└──────┴──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 首页内容区块
|
||||
|
||||
#### 欢迎卡片
|
||||
- 显示用户名
|
||||
- 显示今日待参加的预约数量
|
||||
- 快速跳转按钮
|
||||
|
||||
#### 我的小组
|
||||
- 显示小组数量
|
||||
- 显示3个最近活跃的小组卡片
|
||||
- "查看全部"链接
|
||||
|
||||
#### 即将开始的活动
|
||||
- 时间倒计时
|
||||
- 活动卡片列表
|
||||
- 快速加入按钮
|
||||
|
||||
#### 热门游戏
|
||||
- 横向滚动或网格布局
|
||||
- 游戏卡片展示
|
||||
- 点击跳转游戏详情
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户中心
|
||||
|
||||
### 4.1 个人资料 (/user/profile)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [返回] 个人资料 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ [头像上传] │ │
|
||||
│ │ │ │
|
||||
│ │ 用户名: john_doe │ │
|
||||
│ │ 昵称: [编辑] │ │
|
||||
│ │ 邮箱: jo***@example.com │ │
|
||||
│ │ 手机: 138****8000 │ │
|
||||
│ │ │ │
|
||||
│ │ 会员状态: 是 [到期时间: 2026-12-31] │ │
|
||||
│ │ 注册时间: 2025-01-01 │ │
|
||||
│ │ 最后登录: 2026-01-28 10:00 │ │
|
||||
│ │ │ │
|
||||
│ │ [编辑资料] [修改密码] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 我的小组 (5) │ │
|
||||
│ │ [小组卡片列表] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 我的积分 │ │
|
||||
│ │ [小组选择] 当前积分: 1,250 │ │
|
||||
│ │ [积分历史] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 功能模块
|
||||
|
||||
1. **基本信息展示**
|
||||
- 头像、用户名、昵称
|
||||
- 邮箱、手机号(脱敏)
|
||||
- 会员状态、注册时间、最后登录
|
||||
|
||||
2. **编辑资料**
|
||||
- 弹窗表单
|
||||
- 头像上传
|
||||
- 昵称修改
|
||||
- 邮箱/手机号修改
|
||||
|
||||
3. **我的小组**
|
||||
- 卡片列表展示
|
||||
- 显示小组角色
|
||||
- 快速跳转
|
||||
|
||||
4. **我的积分**
|
||||
- 下拉选择小组
|
||||
- 显示当前积分
|
||||
- 积分历史入口
|
||||
|
||||
---
|
||||
|
||||
### 4.2 设置 (/user/settings)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [返回] 设置 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 通知设置 │ │
|
||||
│ │ [ ] 预约提醒 │ │
|
||||
│ │ [ ] 活动开始提醒 (提前15分钟) │ │
|
||||
│ │ [ ] 小组通知 │ │
|
||||
│ │ [ ] 积分变动通知 │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 隐私设置 │ │
|
||||
│ │ [ ] 显示在线状态 │ │
|
||||
│ │ [ ] 允许陌生人查看我的小组 │ │
|
||||
│ │ [ ] 允许陌生人查看我的积分 │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 外观设置 │ │
|
||||
│ │ 主题: [●]浅色 [ ]深色 [ ]跟随系统 │ │
|
||||
│ │ 语言: [简体中文 ▼] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 账号安全 │ │
|
||||
│ │ [修改密码] │ │
|
||||
│ │ [绑定手机] │ │
|
||||
│ │ [绑定邮箱] │ │
|
||||
│ │ [退出登录] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 小组管理
|
||||
|
||||
### 5.1 小组列表 (/groups)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 小组管理 [+ 创建小组] [搜索框] │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [全部] [我创建的] [我加入的] │
|
||||
│ │
|
||||
│ ┌────────┐ ┌────────┐ ┌────────┐ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │小组卡片│ │小组卡片│ │小组卡片│ ... │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ └────────┘ └────────┘ └────────┘ │
|
||||
│ │
|
||||
│ ┌────────┐ ┌────────┐ ┌────────┐ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │小组卡片│ │小组卡片│ │小组卡片│ ... │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ └────────┘ └────────┘ └────────┘ │
|
||||
│ │
|
||||
│ [加载更多] 或 [分页器] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 功能特性
|
||||
|
||||
- **筛选标签**: 全部/我创建的/我加入的
|
||||
- **搜索**: 支持按小组名称搜索
|
||||
- **排序**: 最新创建/成员最多/最活跃
|
||||
- **卡片展示**: 头像、名称、成员数、角色
|
||||
- **加载更多**: 无限滚动或分页
|
||||
|
||||
---
|
||||
|
||||
### 5.2 小组详情 (/groups/:id)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] 王者荣耀固定队 [编辑] [更多] │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ [小组头像] 王者荣耀固定队 │ │
|
||||
│ │ 每晚8点开黑,欢迎加入 │ │
|
||||
│ │ 成员: 25/50 │ │
|
||||
│ │ [公告]本周六团建活动! │ │
|
||||
│ │ │ │
|
||||
│ │ [预约列表] [成员列表] [荣誉墙] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 即将开始的预约 │ │
|
||||
│ │ ┌─────────────────────────────────┐ │ │
|
||||
│ │ │ [游戏] 今晚开黑 │ │ │
|
||||
│ │ │ 今天 20:00-23:00 │ │ │
|
||||
│ │ │ 参与: 4/5 [加入] │ │ │
|
||||
│ │ └─────────────────────────────────┘ │ │
|
||||
│ │ ┌─────────────────────────────────┐ │ │
|
||||
│ │ │ [游戏] 周末排位赛 │ │ │
|
||||
│ │ │ 周六 14:00-18:00 │ │ │
|
||||
│ │ │ 参与: 8/10 [加入] │ │ │
|
||||
│ │ └─────────────────────────────────┘ │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 小组成员 (25) [管理成员] │ │
|
||||
│ │ [头像列表] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 小组积分排行 │ │
|
||||
│ │ 1. 用户A - 2,500积分 │ │
|
||||
│ │ 2. 用户B - 2,100积分 │ │
|
||||
│ │ 3. 用户C - 1,800积分 │ │
|
||||
│ │ ... │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [+ 创建预约] [查看全部预约] │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 功能模块
|
||||
|
||||
1. **小组基本信息**
|
||||
- 头像、名称、描述
|
||||
- 成员数/最大成员数
|
||||
- 公告
|
||||
- 角色(组长/管理员/成员)
|
||||
|
||||
2. **Tab切换**
|
||||
- 预约列表
|
||||
- 成员列表
|
||||
- 荣誉墙
|
||||
- 账目记录
|
||||
- 资产管理
|
||||
|
||||
3. **即将开始的预约**
|
||||
- 时间倒计时
|
||||
- 参与人数
|
||||
- 快速加入按钮
|
||||
|
||||
4. **小组成员**
|
||||
- 头像列表(前12个)
|
||||
- 在线状态
|
||||
- "管理成员"(管理员可见)
|
||||
|
||||
5. **积分排行**
|
||||
- Top10列表
|
||||
- 显示排名变化
|
||||
|
||||
---
|
||||
|
||||
### 5.3 创建小组 (/groups/create)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] 创建小组 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 小组名称 │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ │ │
|
||||
│ │ 小组描述 │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ │ │
|
||||
│ │ 小组头像 │ │
|
||||
│ │ [上传图片] │ │
|
||||
│ │ │ │
|
||||
│ │ 小组类型 │ │
|
||||
│ │ [●]普通小组 [ ]公会 │ │
|
||||
│ │ │ │
|
||||
│ │ 最大成员数 │ │
|
||||
│ │ [50▼] (会员可创建公会,上限500人) │ │
|
||||
│ │ │ │
|
||||
│ │ [取消] [创建小组] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 游戏库
|
||||
|
||||
### 6.1 游戏列表 (/games)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 游戏库 [搜索框] [筛选] │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [标签筛选] MOBA(5) FPS(3) RPG(2) ... │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ [封面图] │ │ [封面图] │ │ [封面图] │ │
|
||||
│ │ 王者荣耀 │ │ 和平精英 │ │ 英雄联盟 │ │
|
||||
│ │ 5v5 MOBA│ │ 吃鸡FPS │ │ 5v5 MOBA │ │
|
||||
│ │ 10人 │ │ 100人 │ │ 10人 │ │
|
||||
│ │ iOS/And │ │ iOS/And │ │ PC │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ [封面图] │ │ [封面图] │ │ [封面图] │ │
|
||||
│ │ 游戏名称 │ │ 游戏名称 │ │ 游戏名称 │ ... │
|
||||
│ │ ... │ │ ... │ │ ... │ │
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 功能特性
|
||||
|
||||
- **搜索**: 支持游戏名称搜索
|
||||
- **标签筛选**: 游戏类型标签
|
||||
- **平台筛选**: iOS/Android/PC/主机
|
||||
- **排序**: 热门/最新/名称
|
||||
- **卡片展示**: 封面图、名称、类型、人数、平台
|
||||
|
||||
---
|
||||
|
||||
### 6.2 游戏详情 (/games/:id)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ [游戏封面图 - 宽] │ │
|
||||
│ │ │ │
|
||||
│ │ 王者荣耀 │ │
|
||||
│ │ 5v5公平竞技游戏 │ │
|
||||
│ │ │ │
|
||||
│ │ [MOBA] [5v5] [iOS/Android] │ │
|
||||
│ │ │ │
|
||||
│ │ 人数: 1-10人 │ │
|
||||
│ │ │ │
|
||||
│ │ [创建预约] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 游戏描述 │ │
|
||||
│ │ 《王者荣耀》是腾讯第一3D英雄... │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 相关预约 │ │
|
||||
│ │ [预约卡片列表] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 预约管理
|
||||
|
||||
### 7.1 预约列表 (/appointments)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 预约管理 [+ 创建预约] [筛选] │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [全部] [即将开始] [进行中] [已结束] │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ [游戏图标] 今晚开黑 │ │
|
||||
│ │ 王者荣耀固定队 │ │
|
||||
│ │ 今天 20:00-23:00 │ │
|
||||
│ │ 参与: 4/5 ●即将开始 │ │
|
||||
│ │ [查看详情] [退出] │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ [游戏图标] 周末桌游局 │ │
|
||||
│ │ 周末休闲组 │ │
|
||||
│ │ 周六 14:00-18:00 │ │
|
||||
│ │ 参与: 6/8 ○未开始 │ │
|
||||
│ │ [查看详情] [退出] │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ...更多预约 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 状态标签
|
||||
|
||||
| 状态 | 标签 | 颜色 |
|
||||
|------|------|------|
|
||||
| open | 未开始 | 绿色 |
|
||||
| full | 已满 | 橙色 |
|
||||
| ongoing | 进行中 | 蓝色 |
|
||||
| finished | 已结束 | 灰色 |
|
||||
| cancelled | 已取消 | 红色 |
|
||||
|
||||
---
|
||||
|
||||
### 7.2 创建预约 (/appointments/create)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] 创建预约 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────┐ │
|
||||
│ │ 选择小组 │ │
|
||||
│ │ [下拉选择 - 王者荣耀固定组 ▼] │ │
|
||||
│ │ │ │
|
||||
│ │ 选择游戏 │ │
|
||||
│ │ [搜索游戏...] │ │
|
||||
│ │ [王者荣耀] [和平精英] ... │ │
|
||||
│ │ │ │
|
||||
│ │ 预约标题 │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ │ │
|
||||
│ │ 预约描述 │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ [_________________________________] │ │
|
||||
│ │ │ │
|
||||
│ │ 开始时间 结束时间 │ │
|
||||
│ │ [日期选择] [日期选择] │ │
|
||||
│ │ [时间选择] [时间选择] │ │
|
||||
│ │ │ │
|
||||
│ │ 最大参与人数 │ │
|
||||
│ │ [5▼] (根据游戏人数范围推荐) │ │
|
||||
│ │ │ │
|
||||
│ │ [取消] [创建预约] │ │
|
||||
│ └───────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 积分排行
|
||||
|
||||
### 8.1 积分排行榜 (/points/ranking/:groupId)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] 积分排行榜 - 王者荣耀固定队 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [本周] [本月] [总榜] │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 🥇 [头像] 用户A │ │
|
||||
│ │ 2,500积分 ↑2 │ │
|
||||
│ │ 参与活动25次 MVP 10次 │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 🥈 [头像] 用户B │ │
|
||||
│ │ 2,100积分 ↓1 │ │
|
||||
│ │ 参与活动22次 MVP 8次 │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 🥉 [头像] 用户C │ │
|
||||
│ │ 1,800积分 - │ │
|
||||
│ │ 参与活动20次 MVP 5次 │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 4 [头像] 用户D │ │
|
||||
│ │ 1,500积分 ↑5 │ │
|
||||
│ │ 参与活动18次 MVP 3次 │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ...更多排名 │
|
||||
│ │
|
||||
│ 我的排名: 第15名 (800积分) │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 特效
|
||||
|
||||
- **Top3特殊样式**: 金银铜牌样式
|
||||
- **排名变化**: ↑↓箭头显示排名变化
|
||||
- **我的排名**: 底部固定显示
|
||||
|
||||
---
|
||||
|
||||
## 9. 荣誉墙
|
||||
|
||||
### 9.1 荣誉时间轴 (/honors/:groupId)
|
||||
|
||||
#### 页面布局
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [←] 荣誉墙 - 王者荣耀固定队 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 2026年 │ │
|
||||
│ │ ───────────────────────────────── │ │
|
||||
│ │ │ │
|
||||
│ │ 🏆 年度MVP │ │
|
||||
│ │ [头像][头像] │ │
|
||||
│ │ 用户A 用户B │ │
|
||||
│ │ │ │
|
||||
│ │ 🏆 最佳新人 │ │
|
||||
│ │ [头像] │ │
|
||||
│ │ 用户C │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 2025年12月 │ │
|
||||
│ │ ───────────────────────────────── │ │
|
||||
│ │ │ │
|
||||
│ │ 🏆 月度冠军 │ │
|
||||
│ │ [头像] │ │
|
||||
│ │ 用户A │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ 2025年11月 │ │
|
||||
│ │ ───────────────────────────────── │ │
|
||||
│ │ ... │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 荣誉类型
|
||||
|
||||
| 类型 | 图标 | 说明 |
|
||||
|------|------|------|
|
||||
| YEARLY | 🏆 | 年度荣誉 |
|
||||
| MONTHLY | 🥇 | 月度荣誉 |
|
||||
| WEEKLY | ⭐ | 周度荣誉 |
|
||||
| CUSTOM | 🎖️ | 自定义荣誉 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 响应式适配
|
||||
|
||||
### 10.1 移动端适配
|
||||
|
||||
#### 顶部导航
|
||||
- 桌面: 水平导航菜单
|
||||
- 移动: 汉堡菜单 + 抽屉式导航
|
||||
|
||||
#### 侧边栏
|
||||
- 桌面: 固定显示
|
||||
- 平板: 可折叠
|
||||
- 移动: 抽屉式侧边栏
|
||||
|
||||
#### 内容布局
|
||||
- 桌面: 3-4列网格
|
||||
- 平板: 2列网格
|
||||
- 移动: 1列堆叠
|
||||
|
||||
#### 卡片信息
|
||||
- 桌面: 完整信息展示
|
||||
- 移动: 精简信息,点击查看详情
|
||||
|
||||
---
|
||||
|
||||
## 11. 页面动效
|
||||
|
||||
### 11.1 页面切换动画
|
||||
|
||||
```css
|
||||
/* 淡入淡出 */
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 滑动 */
|
||||
.slide-enter-active, .slide-leave-active {
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
.slide-enter-from {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
.slide-leave-to {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
```
|
||||
|
||||
### 11.2 列表动画
|
||||
|
||||
```css
|
||||
/* 列表项依次进入 */
|
||||
@keyframes slideInUp {
|
||||
from {
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item {
|
||||
animation: slideInUp 0.3s ease-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.list-item:nth-child(1) { animation-delay: 0ms; }
|
||||
.list-item:nth-child(2) { animation-delay: 50ms; }
|
||||
.list-item:nth-child(3) { animation-delay: 100ms; }
|
||||
/* ... */
|
||||
```
|
||||
|
||||
### 11.3 加载动画
|
||||
|
||||
- **骨架屏**: 内容加载时显示
|
||||
- **Loading Spinner**: 按钮加载、异步操作
|
||||
- **进度条**: 页面顶部加载进度
|
||||
|
||||
---
|
||||
|
||||
## 12. 总结
|
||||
|
||||
本页面设计文档确保:
|
||||
- ✅ **一致性**: 统一的页面布局和交互模式
|
||||
- ✅ **易用性**: 直观的导航和操作流程
|
||||
- ✅ **美观性**: 精心设计的视觉呈现
|
||||
- ✅ **响应式**: 完美适配各种设备
|
||||
- ✅ **性能**: 流畅的页面加载和交互
|
||||
|
||||
---
|
||||
|
||||
**文档维护**: 随页面迭代持续更新
|
||||
**最后更新**: 2026-01-28
|
||||
1161
doc/design/05-移动端与跨平台方案.md
Normal file
1161
doc/design/05-移动端与跨平台方案.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user