docs: add mobile frontend design spec
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
# 手机端前端设计文档
|
||||
|
||||
> 日期:2026-06-15
|
||||
> 仓库:gamegroup2(http://jiulu-gameplay.com.cn:13001/congsh/gamegroup2.git)
|
||||
> 状态:已确认,待实施
|
||||
|
||||
## 1. 目标
|
||||
|
||||
为现有 Game Group V2(游戏组队管理平台)增加完整的手机端前端,使移动设备用户通过手机浏览器即可使用全部功能。手机端与桌面端共存于同一项目、同一域名、同一后端,访问时根据设备自动分流。
|
||||
|
||||
**成功标准**:手机浏览器打开 `http://192.168.1.14:7033`(Dev)/ `7034`(UAT),自动进入手机版界面,可完成登录、群组管理、组队、投票、竞猜、账本、资产、黑名单、回忆、游戏库等全部现有功能,交互符合移动端操作习惯。
|
||||
|
||||
## 2. 技术决策
|
||||
|
||||
### 2.1 方案:单项目双视图层 + 路由分流
|
||||
|
||||
在现有 `frontend` 项目内新增手机端视图层,与桌面端共存:
|
||||
|
||||
- **共享层(零改动,手机端直接复用)**:`api/`(PocketBase 封装)、`stores/`(Pinia)、`types/`(接口定义)、`composables/`(useRealtime 等)、`assets/design.css`(设计系统变量)
|
||||
- **桌面层(不动)**:现有 `views/`、`components/` 保持原样
|
||||
- **手机层(全新)**:`views-mobile/`、`components-mobile/`、`mobile/`(布局与设备检测)
|
||||
|
||||
理由:业务逻辑全在前端、API 为标准 PocketBase SDK,共享层与 UI 无关;分成独立项目会导致 api/stores/types/composables 要么复制要么抽包,维护成本翻倍。单项目共享核心 + 双视图层是最低成本、最高复用的方案。
|
||||
|
||||
### 2.2 手机端组件库:Vant 4
|
||||
|
||||
引入 **Vant 4**(Vue 3 移动端组件库)作为手机端 UI 组件库。
|
||||
|
||||
- 现有 Element Plus 面向桌面(弹窗、表格、复杂表单),手机端的 Tabbar、ActionSheet、PullRefresh、Toast、SwipeCell、NavBar 等交互它不擅长
|
||||
- Vant 专注移动端,与 Vite / Vue 3 / TypeScript 无缝集成
|
||||
- 桌面端继续用 Element Plus,两套通过路由分流隔离,互不干扰
|
||||
|
||||
**新增依赖**:`vant@^4` + `@vant/auto-import-resolver`(Vant 按需引入插件,确保未使用的组件不打包进桌面端产物)
|
||||
|
||||
### 2.3 主题一致性
|
||||
|
||||
将 Vant 的 CSS 变量覆盖为现有 `design.css` 的 `--gg-*` 值,保证手机端与桌面端视觉统一:
|
||||
- 主色 `--van-primary-color: var(--gg-primary)` (#059669)
|
||||
- 背景色、文字色、圆角、阴影等全部映射到 `--gg-*` 对应变量
|
||||
|
||||
### 2.4 语音能力
|
||||
|
||||
手机端 VoiceRoom 做完整 UI(成员网格、控制条、房间布局),实际 WebRTC 连接与麦克风采集暂不接入。原因:非 HTTPS / 部分手机浏览器(如微信内置)限制 `mediaDevices`,桌面 Electron 端已遇到同类问题。
|
||||
|
||||
手机端语音房显示明确占位提示:"语音功能请在 App 中使用"。完整语音能力待后续打包为原生 App(Capacitor / Tauri Mobile)时再接入。
|
||||
|
||||
## 3. 目录结构
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├─ api/ # 共享(PocketBase 封装,零改动)
|
||||
├─ stores/ # 共享(Pinia,零改动)
|
||||
├─ types/ # 共享(接口定义,零改动)
|
||||
├─ composables/ # 共享(useRealtime 等,零改动)
|
||||
├─ assets/
|
||||
│ ├─ design.css # 共享设计系统(桌面+手机)
|
||||
│ └─ mobile.css # 手机端主题覆盖(Vant 变量映射)
|
||||
├─ views/ # 桌面端页面(现有,不动)
|
||||
├─ components/ # 桌面端组件(现有,不动)
|
||||
├─ views-mobile/ # 手机端页面(全新)
|
||||
├─ components-mobile/ # 手机端组件(全新)
|
||||
├─ mobile/ # 手机端专用
|
||||
│ ├─ MobileLayout.vue # 底部 Tab + 顶部栏 主布局
|
||||
│ ├─ useDevice.ts # 设备检测 composable
|
||||
│ └─ DeviceGuard.ts # 路由级设备分流
|
||||
├─ router/
|
||||
│ └─ index.ts # 改造:设备检测 + 分流
|
||||
└─ main.ts # 改造:按需注册 Vant
|
||||
```
|
||||
|
||||
## 4. 设备检测与路由分流
|
||||
|
||||
### 4.1 检测策略
|
||||
|
||||
- **主判据**:`navigator.userAgent` 匹配移动设备关键字(iPhone/Android/Windows Phone 等)
|
||||
- **辅助判据**:`window.innerWidth <= 768`(覆盖平板竖屏)
|
||||
- 检测结果在应用启动时执行一次,存入 `localStorage`(`device_mode`)避免重复检测
|
||||
- 提供手动切换入口(设置页:"切换到桌面版"),少数平板/桌面用户可能需要
|
||||
|
||||
### 4.2 路由结构
|
||||
|
||||
每个业务路由定义 `desktop` 和 `mobile` 两个组件,路由守卫根据设备模式返回对应组件:
|
||||
|
||||
```ts
|
||||
// 示例:路由记录
|
||||
{
|
||||
path: '/group/:id',
|
||||
name: 'GroupView',
|
||||
meta: { requiresAuth: true },
|
||||
component: () => isMobile()
|
||||
? import('@/views-mobile/GroupViewMobile.vue')
|
||||
: import('@/views/GroupView.vue')
|
||||
}
|
||||
```
|
||||
|
||||
- 登录态校验(`requiresAuth` / `requiresGuest`)逻辑不变
|
||||
- 所有路由 URL 与桌面端完全一致(同一 `/group/:id`),只是加载的视图不同
|
||||
- 切换设备模式后整页刷新以重新走路由解析
|
||||
|
||||
## 5. 手机端布局与导航
|
||||
|
||||
### 5.1 整体框架
|
||||
|
||||
```
|
||||
┌──────────────────────────┐
|
||||
│ ← 群组名 🔔(3) │ 顶部栏:返回 / 标题 / 通知
|
||||
├──────────────────────────┤
|
||||
│ │
|
||||
│ 页面内容区 │
|
||||
│ (下拉刷新、滚动) │
|
||||
│ │
|
||||
├──────────────────────────┤
|
||||
│🏠首页 👥群组 🎮游戏 🔔通知 👤我│ 底部 5 Tab
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
- **顶部栏(NavBar)**:左侧返回按钮(次级页面显示)、中间页面标题、右侧通知铃铛(带未读数徽标)
|
||||
- **底部 Tab(Tabbar)**:5 个固定入口,单手拇指可达
|
||||
- **内容区**:占满中间空间,支持下拉刷新(列表页)、无限滚动加载
|
||||
|
||||
### 5.2 底部 Tab 定义
|
||||
|
||||
| Tab | 图标 | 页面 | 说明 |
|
||||
|-----|------|------|------|
|
||||
| 首页 | home-o | HomeMobile | 状态 + 当前组队 + 我的群组 + 热门游戏 |
|
||||
| 群组 | friends-o | GroupsMobile | 群组列表 + 创建/加入入口 |
|
||||
| 游戏 | game-o | GamesLibraryMobile | 游戏库浏览 + 搜索 |
|
||||
| 通知 | bell | NotificationsMobile | 全部站内通知(邀请/组队/入群) |
|
||||
| 我的 | user-o | ProfileMobile | 个人信息 + 状态 + 设置 |
|
||||
|
||||
**投票、竞猜、账本、资产、黑名单、回忆、统计** 不占底部位置,通过群组详情内的标签栏进入(见 5.3)。
|
||||
|
||||
### 5.3 群组详情的子页面组织
|
||||
|
||||
群组详情(`GroupViewMobile`)承载桌面端 GroupView 的全部 Tab 内容,手机端用**可横滑的顶部标签栏**组织:
|
||||
|
||||
```
|
||||
┌──────────────────────────┐
|
||||
│ ← 群组名 [12人] [⚙] │
|
||||
├──────────────────────────┤
|
||||
│ 动态 投票 竞猜 回忆 → │ 可横滑标签(横向滚动)
|
||||
├──────────────────────────┤
|
||||
│ │
|
||||
│ [当前标签内容] │
|
||||
│ │
|
||||
└──────────────────────────┘
|
||||
(其余标签:成员 账本 资产 黑名单 统计)
|
||||
```
|
||||
|
||||
- 9 个标签:动态 / 投票 / 竞猜 / 回忆 / 成员 / 账本 / 资产 / 黑名单 / 统计
|
||||
- 首次进入默认「动态」Tab
|
||||
- 横向可滑动,超出屏幕的标签左右滑出
|
||||
- 群组级独立页面(账本 `/group/:id/ledger`、资产 `/group/:id/assets`、黑名单 `/group/:id/blacklist`)也可从标签进入,URL 保持一致以支持直接跳转和返回
|
||||
|
||||
## 6. 全部页面设计
|
||||
|
||||
### 6.1 认证
|
||||
|
||||
| 页面 | 文件 | 设计要点 |
|
||||
|------|------|---------|
|
||||
| 登录 | `views-mobile/LoginMobile.vue` | 全屏卡片式,顶部 Logo + 标语,大号输入框(昵称/邮箱/用户名 + 密码),主按钮全宽,底部"去注册"链接。键盘弹出时内容上推不遮挡。 |
|
||||
| 注册 | `views-mobile/RegisterMobile.vue` | 步骤化表单:昵称 → 密码 → 确认密码。复用桌面端自动生成 username 的逻辑(`'u' + Date.now().toString(36) + random`)。 |
|
||||
|
||||
### 6.2 主功能
|
||||
|
||||
| 页面 | 文件 | 设计要点 |
|
||||
|------|------|---------|
|
||||
| 首页 | `views-mobile/HomeMobile.vue` | 顶部:当前用户状态卡片(在线/忙碌/离开 + 一键切换 + 状态备注)。中部:当前临时小组卡片(如有,显示成员头像 + 进入语音房按钮)。下方:我的群组横滑卡片列表(点击进群组详情)。底部:热门游戏横滑封面。无群组时显示引导卡(创建/加入)。 |
|
||||
| 群组列表 | `views-mobile/GroupsMobile.vue` | 群组卡片纵向列表(群名 + 成员数 + 简介 + 未读标记),顶部右侧浮动「+」按钮弹出 ActionSheet(创建群组 / 加入群组)。下拉刷新。 |
|
||||
| 群组详情 | `views-mobile/GroupViewMobile.vue` | 顶部群信息条(群名 / 成员数 / 群主 / 容量)+ 快捷操作(账本/资产/黑名单图标入口)+ 可横滑标签栏(见 5.3)。 |
|
||||
| 语音房 | `views-mobile/VoiceRoomMobile.vue` | 成员头像大网格(2-3 列,显示麦克风开关状态、说话动效)。底部固定控制条(麦克风开关 / 静音 / 退出)。顶部显示房间名和在线人数。WebRTC 未接入时显示占位提示。 |
|
||||
|
||||
### 6.3 群组内功能(标签栏子页面)
|
||||
|
||||
| 功能 | 组件 | 设计要点 |
|
||||
|------|------|---------|
|
||||
| 动态 | `components-mobile/group/ActivityFeed.vue` | 当前组队状态卡 + 空闲成员列表 + 所有成员按状态分组列表。 |
|
||||
| 投票 | `components-mobile/poll/PollListMobile.vue` + `PollDetailMobile.vue` | 卡片列表(标题 / 选项数 / 截止时间 / 状态),下拉刷新,点击进详情投票。创建投票走底部弹出表单。 |
|
||||
| 竞猜 | `components-mobile/bet/BetListMobile.vue` + `BetDetailMobile.vue` | 卡片列表(标题 / 下注范围 / 截止时间 / 我的下注),点击进详情下注。结算展示结果。 |
|
||||
| 回忆 | `components-mobile/memory/MemoryGridMobile.vue` | 九宫格图片视频缩略图,点击全屏浏览(支持滑动切换、捏合缩放)。上传走底部弹出(拍照/相册选择)。 |
|
||||
| 成员 | `components-mobile/group/MemberListMobile.vue` | 按状态分组列表(头像 + 昵称 + 状态备注),群主可管理(踢人/审核入群)。 |
|
||||
| 账本 | `views-mobile/LedgerMobile.vue` | 顶部月度汇总卡片(总收入/支出/结余),下方账目列表,右下角浮动「+」添加(弹出表单:金额/类型/备注)。 |
|
||||
| 资产 | `views-mobile/AssetMobile.vue` | 资产卡片列表(名称 / 类型 / 当前持有者),点击查看详情 / 转移。 |
|
||||
| 黑名单 | `views-mobile/BlacklistMobile.vue` | 顶部 Tab 切换「游戏黑名单 / 玩家黑名单」。游戏:卡片列表(游戏名 + 标签 + 备注)。玩家:列表(昵称 + 标签 + 备注)。 |
|
||||
| 统计 | `components-mobile/stats/StatsPanelMobile.vue` | 桌面 GroupStatsPanel 的简化只读版,展示群组活跃度、游戏偏好等核心数据(图表用简化柱状/环形,避免手机端图表过密)。 |
|
||||
|
||||
### 6.4 全局页面
|
||||
|
||||
| 页面 | 文件 | 设计要点 |
|
||||
|------|------|---------|
|
||||
| 游戏库 | `views-mobile/GamesLibraryMobile.vue` | 顶部搜索栏,下方游戏封面瀑布流(2 列),点击弹出详情底部面板(封面 / 平台 / 标签 / 评论 / 收藏 / 发起组队)。 |
|
||||
| 通知 | `views-mobile/NotificationsMobile.vue` | 全部通知列表(类型图标 + 内容 + 时间),按时间倒序,支持标记已读 / 接受 / 拒绝操作。下拉刷新。 |
|
||||
| 个人中心 | `views-mobile/ProfileMobile.vue` | 头像 + 昵称 + 用户名,状态切换,积分余额,我的群组数 / 组队次数等数据,设置 / 更新日志 / 退出登录入口。 |
|
||||
| 设置 | `views-mobile/SettingsMobile.vue` | 列表式设置项:通知开关、主题(预留)、切换到桌面版、关于。 |
|
||||
| 更新日志 | `views-mobile/ChangelogMobile.vue` | 时间线列表展示版本更新记录。 |
|
||||
|
||||
## 7. 共享层改动说明
|
||||
|
||||
手机端零改动地复用以下现有代码:
|
||||
|
||||
| 层 | 内容 | 说明 |
|
||||
|----|------|------|
|
||||
| `api/pocketbase.ts` | PocketBase 单例、`getCurrentUser()`、`isAuthenticated()`、`logout()` | 手机端直接 import 使用 |
|
||||
| `api/*` | users / groups / sessions / invitations / games / polls / bets / points / ledgers / assets / memories / notifications / gameBlacklist / playerBlacklist | 全部领域 API 封装,手机端复用 |
|
||||
| `stores/*` | user / group / team / notification / poll / ledger / asset / memory | Pinia stores,组合式 API,手机端复用(UI 状态可按需扩展) |
|
||||
| `composables/useRealtime.ts` | PocketBase 实时订阅管理 | 手机端复用,组件卸载自动清理 |
|
||||
| `types/index.ts` | 全部接口定义 + `displayName()` + 状态映射常量 | 手机端复用 |
|
||||
|
||||
**桌面端代码零改动**:现有 `views/`、`components/` 保持原样,不影响桌面用户。
|
||||
|
||||
## 8. 构建与部署
|
||||
|
||||
- **Vite 构建合并**:手机端和桌面端在同一份构建产物中,路由层负责分流。Vant 按需引入(`@vant/auto-import-resolver`),不使用的组件不打包,避免桌面端访问时加载手机端组件库。
|
||||
- **部署不变**:现有 `deploy-dev.sh` / `deploy-uat.sh` 流程不变,nginx 配置不变,同一端口同一域名同时服务两端。
|
||||
- **环境变量**:`.env` 的 `VITE_PB_URL`、`VITE_PORT` 对两端同样生效。
|
||||
|
||||
## 9. 实施顺序
|
||||
|
||||
分 9 个阶段,每阶段产出可验证的成果(可在手机浏览器实测):
|
||||
|
||||
1. **基础设施**:安装 Vant、设备检测(`useDevice`)、路由分流改造、`MobileLayout`(底部 Tab + 顶部栏)、`mobile.css` 主题覆盖
|
||||
2. **认证**:LoginMobile + RegisterMobile(打通登录注册全流程)
|
||||
3. **首页 + 群组列表**:HomeMobile + GroupsMobile(含创建/加入群组弹层)
|
||||
4. **群组详情核心**:GroupViewMobile + 动态标签(组队状态 + 成员列表)+ 成员管理
|
||||
5. **组队 + 语音房 UI**:发起组队、邀请、接受邀请、状态切换、VoiceRoomMobile(占位)
|
||||
6. **投票 + 竞猜**:列表 + 详情 + 创建/下注 + 结算
|
||||
7. **游戏库**:GamesLibraryMobile + 详情弹层 + 搜索
|
||||
8. **账本 + 资产 + 黑名单**:三个管理类页面(列表 + 增删改 + 资产转移)
|
||||
9. **回忆 + 统计 + 个人/设置/更新日志**:收尾页面
|
||||
|
||||
## 10. 不在本次范围内
|
||||
|
||||
以下事项明确排除,待后续迭代:
|
||||
|
||||
- **语音 WebRTC 实际接入**:手机端语音房仅做 UI 和占位提示,实际通话能力待打包为原生 App(Capacitor / Tauri Mobile)时实现
|
||||
- **PWA / 离线支持**:本次不做离线缓存和可安装 Web App
|
||||
- **推送通知(原生)**:本次仅做站内通知,App 级推送待后续
|
||||
- **桌面端改动**:现有桌面端代码不做任何修改
|
||||
|
||||
## 11. 风险与缓解
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| Vant 与 Element Plus 样式冲突 | 两套组件库通过路由分流隔离,不同时挂载;Vant 主题变量全部覆盖为 `--gg-*` 值 |
|
||||
| 手机端浏览器实时订阅稳定性 | 复用现有 `useRealtime`,组件卸载自动清理;移动端切后台时 PocketBase SSE 断连,回前台后自动重连(现有机制) |
|
||||
| 构建体积增长 | Vant 按需引入,仅打包手机端实际用到的组件 |
|
||||
| 微信内置浏览器限制 | 语音功能已有占位;如遇其他 API 限制(如某些路由 history 模式),预留 hash 模式降级方案 |
|
||||
|
||||
## 12. 验收标准
|
||||
|
||||
- [ ] 手机浏览器访问 Dev/UAT 自动进入手机版界面
|
||||
- [ ] 桌面浏览器访问仍是原桌面版,行为不变
|
||||
- [ ] 登录 / 注册 / 退出全流程正常
|
||||
- [ ] 首页:状态切换、群组入口、当前组队卡片显示正常
|
||||
- [ ] 群组详情:9 个标签全部可访问,数据正确
|
||||
- [ ] 组队流程:发起 / 邀请 / 接受 / 状态流转正常
|
||||
- [ ] 投票 / 竞猜:创建 / 参与 / 结算正常
|
||||
- [ ] 账本 / 资产 / 黑名单:增删改查正常,资产转移正常
|
||||
- [ ] 回忆:浏览 + 上传正常
|
||||
- [ ] 游戏库:浏览 + 搜索 + 详情正常
|
||||
- [ ] 通知:接收 / 标记已读 / 接受拒绝正常
|
||||
- [ ] 个人中心 / 设置:状态切换、切换桌面版正常
|
||||
- [ ] 语音房界面完整,占位提示明确
|
||||
Reference in New Issue
Block a user