# 排乐队 LineJoy - PRD & TDD 概要文档 ## 产品需求文档 (PRD) ### 1. 产品概述 **产品名称**:基于微信小程序的排队解闷小游戏合集 **产品愿景**:将排队时的无聊等待转变为社交互动的契机,通过线上小游戏引导线下交流,增进陌生人或团队成员间的互动与了解。 **核心价值主张**: - 特定场景解决方案:专为排队场景设计的互动游戏体验 - 线上引导线下:使用小程序作为媒介促进真实社交 - 即开即玩:无需复杂注册,扫码即可参与 - 持续扩展内容:从海龟汤开始,逐步扩展多种游戏类型 ### 2. 目标用户 - **主要用户**:20-35岁年轻人群,在餐厅、景点、医院等场所排队等待的小团体 - **次要用户**:团队建设活动组织者(公司团建、课外活动等) - **潜在用户**:陌生人社交需求者,希望在公共场合认识新朋友的人群 ### 3. 核心功能模块 #### 3.1 游戏广场 - 游戏分类展示(推荐、热门、新增) - 按游戏时长筛选(5分钟、15分钟、30分钟) - 排队场景推荐 - 搜索功能 #### 3.2 房间系统 - **创建房间**(主持人) - 游戏选择 - 难度设置 - 人数限制 - 房间公开性设置 - 位置标记(可选) - **加入房间** - 通过房间码加入 - 扫描二维码加入 - 查看附近的公开房间 #### 3.3 角色系统 - **主持人**(游戏创建者) - 控制游戏进程 - 查看完整游戏信息 - 管理提示公开 - 回答玩家问题 - 公布游戏结果 - **玩家** - 提问询问线索 - 查看已公开信息 - 参与讨论推理 - 提交猜测 #### 3.4 游戏内容 - **海龟汤**(首发核心游戏) - 谜题展示 - 问答系统 - 提示管理 - 线索整理 - 解谜流程 - **其他游戏类型**(后续拓展) - 谁是卧底 - 20个问题 - 微型创意讲故事 - 附近的谎言家 - 队列连连看 - 秘密任务 #### 3.5 社交功能 - 房间内聊天 - 游戏结果分享 - 添加游戏好友 - 历史游戏记录 - 游戏战绩统计 ### 4. 用户流程 #### 4.1 主持人流程 1. 进入游戏广场 2. 选择游戏类型 3. 创建房间并设置参数 4. 分享房间码/二维码邀请他人 5. 等待玩家加入 6. 开始游戏并担任主持角色 7. 游戏结束后查看结果统计 #### 4.2 玩家流程 1. 通过码/二维码打开小程序 2. 输入房间码或扫码加入房间 3. 等待主持人开始游戏 4. 参与游戏互动 5. 游戏结束后查看结果 6. 选择继续游戏或退出房间 ### 5. 特色功能 - **线下互动提示**:定期弹出"看看周围的人"等提示,引导线上到线下的转化 - **时间感知**:根据用户输入的排队预计时间,推荐适合的游戏 - **位置标记**:标记当前排队地点,方便附近用户发现并加入 - **破冰话题**:在游戏过程中提供话题建议,促进陌生人交流 - **合影留念**:游戏结束后提供拍照记录功能,保存互动回忆 ### 6. 性能与体验需求 - **启动速度**:冷启动时间不超过3秒 - **响应时间**:交互响应时间不超过300ms - **离线能力**:基本游戏内容在网络不稳定时仍可使用 - **单手操作**:界面设计适配单手操作场景 - **低电量优化**:提供省电模式,延长排队中的使用时间 ### 7. 发布计划 #### 第一阶段 - 完成核心海龟汤游戏 - 实现基础房间系统 - 构建游戏广场 - 支持扫码和房间码加入 #### 第二阶段 - 增加2-3个新游戏类型 - 完善社交功能 - 优化用户体验 - 增加位置服务 #### 第三阶段 - 开放用户贡献内容 - 增加成就系统 - 推出更多游戏类型 - 增强数据分析能力 --- ## 技术设计文档 (TDD) ### 1. 技术选型 - **前端框架**:Taro4.x + Vue3 + TypeScript + pnpm + Sass - **状态管理**:Pinia - **UI组件库**:NutUI Vue - **后端服务**:微信云开发 - **数据库**:云开发数据库 - **编译**:webpack5 ### 2. 系统架构 ``` 客户端 (Taro) ↑↓ 云开发 API ↑↓ 云函数 (业务逻辑) ↑↓ 云数据库 (数据存储) ``` ### 3. 数据模型设计 #### 3.1 用户模型 ```typescript interface User { id: string; // 用户唯一ID openId: string; // 微信OpenID nickname: string; // 昵称 avatarUrl: string; // 头像 createdAt: Date; // 注册时间 stats: { // 统计数据 gamesPlayed: number; gamesHosted: number; solvedRate: number; // 解谜成功率 }; } ``` #### 3.2 房间模型 ```typescript interface Room { id: string; // 房间ID roomCode: string; // 6位房间码 gameType: string; // 游戏类型 gameId: string; // 游戏内容ID hostId: string; // 主持人ID createdAt: Date; // 创建时间 status: RoomStatus; // 等待中/进行中/已结束 settings: { // 房间设置 maxPlayers: number; isPublic: boolean; difficulty: string; hintRevealMode: string; // 自动/手动 }; location?: { // 可选位置信息 latitude: number; longitude: number; name?: string; // 位置名称 }; players: RoomMember[]; // 玩家列表 } interface RoomMember { id: string; // 用户ID role: RoomRole; // 主持人/玩家 nickname: string; // 昵称 avatarUrl: string; // 头像 joinTime: Date; // 加入时间 isReady: boolean; // 准备状态 } enum RoomRole { HOST = 'host', // 主持人 PLAYER = 'player' // 玩家 } enum RoomStatus { WAITING = 'waiting', // 等待中 PLAYING = 'playing', // 游戏中 ENDED = 'ended' // 已结束 } ``` #### 3.3 游戏模型 (海龟汤) ```typescript interface TurtleSoupGame { id: string; // 游戏ID roomId: string; // 关联房间ID title: string; // 标题 initialStory: string; // 初始故事 hints: string[]; // 提示列表 solution: string; // 解答 revealedHints: number[]; // 已公开提示索引 questions: Question[]; // 问题列表 startTime: Date; // 开始时间 endTime?: Date; // 结束时间 status: GameStatus; // 游戏状态 } interface Question { id: string; // 问题ID playerId: string; // 提问玩家ID playerName: string; // 提问玩家名称 content: string; // 问题内容 answer?: string; // 回答 (是/否/不相关) createdAt: Date; // 创建时间 answeredAt?: Date; // 回答时间 } enum GameStatus { PREPARING = 'preparing', // 准备中 ONGOING = 'ongoing', // 进行中 SOLVED = 'solved', // 已解决 EXPIRED = 'expired' // 已过期 } ``` ### 4. API 设计 #### 4.1 房间管理 API | 接口名称 | 功能描述 | 参数 | 返回值 | |---------|---------|------|-------| | createRoom | 创建游戏房间 | gameType, settings | roomId, roomCode | | joinRoom | 加入游戏房间 | roomCode | roomDetail | | getRoomDetail | 获取房间详情 | roomId | roomDetail | | startGame | 开始游戏 | roomId | gameId | | leaveRoom | 离开房间 | roomId | success | #### 4.2 游戏逻辑 API | 接口名称 | 功能描述 | 参数 | 返回值 | |---------|---------|------|-------| | getGameData | 获取游戏数据 | gameId, role | filteredGameData | | submitQuestion | 提交问题 | gameId, content | questionId | | answerQuestion | 回答问题 | questionId, answer | success | | revealHint | 公开提示 | gameId, hintIndex | success | | endGame | 结束游戏 | gameId, result | gameResult | ### 5. 组件设计 #### 5.1 角色分离组件 **HostOnly组件**:仅主持人可见内容 ```vue ``` **PlayerOnly组件**:仅玩家可见内容 ```vue ``` #### 5.2 核心业务组件 - **GameRoom**:游戏房间容器,负责数据流和状态管理 - **RoomSettings**:房间设置面板(主持人使用) - **PlayerList**:房间玩家列表 - **GameStory**:游戏故事展示 - **QuestionPanel**:问题面板(提问和回答) - **HintManager**:提示管理器(主持人使用) - **HintDisplay**:提示展示(玩家使用) - **ChatRoom**:房间内聊天功能 ### 6. 工程目录结构 g src/ ├── app.config.ts # 小程序全局配置 ├── app.scss # 全局样式 ├── app.ts # 应用入口 ├── assets/ # 静态资源 │ ├── images/ # 图片资源 │ └── styles/ # 样式资源 │ ├── variables.scss # 样式变量 │ ├── nutui-custom.scss # nutui样式 │ └── mixins.scss # 样式混合 ├── components/ # 全局组件 │ ├── HostOnly/ │ └── PlayerOnly/ ├── composables/ # 可组合式函数 │ └── useRoomRole.ts ├── custom-tab-bar/ # 自定义tabbar ├── pages/ # 页面 │ ├── index/ # 游戏广场 │ ├── game-detail/ # 游戏详情 │ ├── room/ # 房间相关页面 │ │ ├── create/ # 创建房间(主持人专用) │ │ ├── join/ # 加入房间(玩家专用) │ │ ├── waiting/ # 等待室(带角色参数) │ │ └── play/ # 游戏进行中(带角色参数) │ ├── profile/ # 个人中心 │ └── history/ # 游戏历史 ├── services/ # API服务 │ ├── api/ # API定义 │ │ ├── game.ts # 游戏 │ │ ├── room.ts # 房间 │ │ └── index.ts # │ ├── request.ts # 请求封装 │ └── cloud.ts # 云函数封装 ├── stores/ # Pinia状态管理 │ ├── modules/ # 状态模块 │ │ ├── user.ts # 用户状态 │ │ ├── room.ts # 房间状态 │ │ └── game.ts # 游戏状态 │ ├── tabbar/ # tabbar状态 │ └── index.ts # 状态入口 ├── types/ # TypeScript类型 │ ├── global.d.ts # 全局 │ └── vue.d.ts # vue └── utils/ # 工具函数 ├── common.ts # 通用工具 ├── format.ts # 格式化工具 └── storage.ts # 存储工具 ### 7. 权限控制机制 #### 7.1 前端权限控制 - 使用 `useRoomRole` 组合式API获取和验证用户角色 - 基于角色条件渲染不同UI组件 - 页面级权限检查,防止直接访问无权限页面 #### 7.2 后端权限控制 - 云函数中验证用户身份和权限 - 数据访问权限过滤 - 主持人专属操作权限验证 #### 7.3 数据过滤策略 ```typescript // 根据角色过滤游戏数据 function filterGameDataByRole(gameData, role: RoomRole) { if (role === RoomRole.HOST) { // 主持人可以看到所有数据 return gameData; } else { // 玩家只能看到部分数据 return { ...gameData, initialStory: gameData.initialStory, revealedHints: gameData.revealedHints, // 隐藏未公开信息 solution: undefined, unreveaedHints: undefined, secretNotes: undefined }; } } ``` ### 8. 实时数据同步 - 使用云开发实时数据库监听房间状态变化 - 使用 WebSocket 实现聊天功能 - 定义数据更新策略,避免频繁刷新 ### 9. 关键技术实现 #### 9.1 角色分离实现 ```typescript // hooks/useRoomRole.ts import { ref, onMounted, computed } from 'vue'; import Taro from '@tarojs/taro'; import { RoomRole } from '@/types'; export function useRoomRole(roomId: string) { const role = ref(null); onMounted(() => { // 从路由参数获取角色 const params = Taro.getCurrentInstance().router?.params; let roleFromParams = params?.role as RoomRole; // 如果没有,从服务器获取 if (!roleFromParams && roomId) { Taro.cloud.callFunction({ name: 'getRoomMemberRole', data: { roomId } }).then(res => { role.value = res.result.role; }); } else { role.value = roleFromParams; } }); const isHost = computed(() => role.value === RoomRole.HOST); const isPlayer = computed(() => role.value === RoomRole.PLAYER); return { role, isHost, isPlayer }; } ``` #### 9.2 实时数据同步 ```typescript // composables/useRoomData.ts import { ref, onMounted, onUnmounted } from 'vue'; import Taro from '@tarojs/taro'; import type { Room } from '@/types'; export function useRoomData(roomId: string) { const roomData = ref(null); let watcher = null; // 设置房间数据监听 onMounted(() => { const db = Taro.cloud.database(); watcher = db.collection('rooms') .doc(roomId) .watch({ onChange: function(snapshot) { roomData.value = snapshot.docs[0]; }, onError: function(err) { console.error('监听房间失败', err); } }); }); // 组件卸载时关闭监听 onUnmounted(() => { if (watcher) { watcher.close(); } }); return { roomData }; } ``` ### 10. 性能优化策略 - **数据缓存**:缓存游戏静态资源和配置 - **按需加载**:按需加载游戏资源 - **防抖节流**:对频繁操作(如聊天输入)进行防抖处理 - **延迟加载**:非关键组件延迟加载 - **状态局部化**:将状态尽可能局部化,避免全局状态过多 ### 11. 安全考虑 - **数据校验**:前后端同时校验数据有效性 - **角色验证**:每次操作前验证用户角色权限 - **数据脱敏**:敏感游戏数据(如解答)仅发送给有权限的用户 - **请求频率限制**:防止恶意请求攻击 ### 12. 测试策略 - **单元测试**:核心业务逻辑单元测试 - **组件测试**:UI组件渲染测试 - **集成测试**:页面流程测试 - **真机测试**:不同设备兼容性测试 - **性能测试**:启动时间、响应时间测试 ### 13. 部署与发布 - **环境配置**:开发、测试、生产环境配置 - **CI/CD**:持续集成与部署流程 - **版本控制**:语义化版本控制 - **灰度发布**:新功能灰度发布策略 - **监控告警**:线上问题监控与告警机制 ---