# 排乐队 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**:持续集成与部署流程
- **版本控制**:语义化版本控制
- **灰度发布**:新功能灰度发布策略
- **监控告警**:线上问题监控与告警机制
---