feat: 初始化项目脚手架

This commit is contained in:
UGREEN USER
2026-01-28 14:35:43 +08:00
commit 1377b18790
31 changed files with 13898 additions and 0 deletions

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff