123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- // services/room.ts
- import Taro from '@tarojs/taro'
- import {
- type Room,
- type RoomUserInfo,
- RoomRole,
- RoomStatus,
- RoomVisibility
- } from '@/types/room'
- import { type UserInfo } from '@/types/user'
- // Mock房间数据(测试用)
- const mockRooms: Record<string, Room> = {
- 'room_001': {
- roomId: 'room_001',
- name: '海龟汤房间',
- gameId: '1',
- gameTitle: '海龟汤',
- maxPlayers: 10,
- visibility: RoomVisibility.PUBLIC,
- hosterId: 'host_123',
- createTime: Date.now() - 3600000,
- status: RoomStatus.WAITING,
- users: [
- {
- openid: 'host_123',
- nickname: '主持人',
- avatar: '',
- roomRole: RoomRole.HOSTER,
- joinTime: Date.now() - 3600000,
- isReady: true
- }
- ]
- },
- 'room_002': {
- roomId: 'room_002',
- name: '狼人杀小队',
- gameId: '2',
- gameTitle: '狼人杀',
- maxPlayers: 8,
- visibility: RoomVisibility.PRIVATE,
- password: '1234',
- hosterId: 'host_456',
- createTime: Date.now() - 86400000,
- status: RoomStatus.WAITING,
- users: [
- {
- openid: 'host_456',
- nickname: '狼王',
- avatar: '',
- roomRole: RoomRole.HOSTER,
- joinTime: Date.now() - 86400000,
- isReady: true
- }
- ]
- }
- };
- // 房间API - 适配新数据结构
- export const roomService = {
- // 获取最近房间
- async getRecentRooms(): Promise<Room[]> {
- try {
- // 从缓存获取
- const cachedRooms = Taro.getStorageSync('recentRooms')
- if (cachedRooms) {
- return JSON.parse(cachedRooms)
- }
-
- // 返回默认mock数据
- return [
- {
- roomId: 'room_001',
- name: '海龟汤房间',
- gameTitle: '海龟汤',
- gameId: '1',
- maxPlayers: 10,
- visibility: RoomVisibility.PUBLIC,
- hosterId: 'host_123',
- createTime: Date.now() - 3600000,
- status: RoomStatus.WAITING,
- users: []
- },
- {
- roomId: 'room_002',
- name: '狼人杀小队',
- gameTitle: '狼人杀',
- gameId: '2',
- maxPlayers: 8,
- visibility: RoomVisibility.PRIVATE,
- password: '1234',
- hosterId: 'host_456',
- createTime: Date.now() - 86400000,
- status: RoomStatus.WAITING,
- users: []
- }
- ]
- } catch (error) {
- console.error('获取最近房间失败:', error)
- return []
- }
- },
-
- // 检查房间是否存在
- async checkRoomExist(gameId: string, roomId: string): Promise<{exists: boolean, needPassword: boolean}> {
- try {
- // 先查询本地存储
- const recentRooms = Taro.getStorageSync('recentRooms')
- if (recentRooms) {
- const rooms = JSON.parse(recentRooms)
- const room = rooms.find((r: Room) => r.roomId === `${gameId}-${roomId}`)
- if (room) {
- return { exists: true, needPassword: room.visibility === RoomVisibility.PRIVATE }
- }
- }
-
- // 如果本地没有,检查mock数据
- const mockRoom = mockRooms[`${gameId}-${roomId}`]
- if (mockRoom) {
- return {
- exists: true,
- needPassword: mockRoom.visibility === RoomVisibility.PRIVATE
- }
- }
-
- return { exists: false, needPassword: false }
- } catch (error) {
- console.error('检查房间失败:', error)
- return { exists: false, needPassword: false }
- }
- },
-
- // 验证房间密码
- async verifyRoomPassword(gameId: string, roomId: string, password: string): Promise<{valid: boolean}> {
- try {
- // 简化实现:仅检查mock数据中的密码
- const mockRoom = mockRooms[`${gameId}-${roomId}`]
- if (mockRoom && mockRoom.visibility === RoomVisibility.PRIVATE) {
- return { valid: mockRoom.password === password }
- }
-
- return { valid: true }
- } catch (error) {
- console.error('验证房间密码失败:', error)
- return { valid: false }
- }
- },
-
- // 创建新房间 - 适配新数据结构
- async createRoom(roomData: Room, userInfo: UserInfo): Promise<{success: boolean, message?: string}> {
- try {
- if (!userInfo.openid) {
- return { success: false, message: '用户未登录' }
- }
-
- // 本地存储一份房间信息
- const recentRooms = Taro.getStorageSync('recentRooms') || '[]'
- const rooms = JSON.parse(recentRooms)
-
- rooms.unshift(roomData)
- // 只保留最近10个房间
- if (rooms.length > 10) {
- rooms.pop()
- }
-
- Taro.setStorageSync('recentRooms', JSON.stringify(rooms))
-
- // 简化实现:仅存储在本地缓存
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${roomData.gameId}-${roomData.roomId}`
- roomsObj[roomKey] = roomData
- Taro.setStorageSync('allRooms', JSON.stringify(roomsObj))
-
- return { success: true }
- } catch (error) {
- console.error('创建房间失败:', error)
- return { success: false, message: '创建房间失败' }
- }
- },
-
- // 加入房间 - 适配新数据结构
- async joinRoom(gameId: string, roomId: string, userData: RoomUserInfo): Promise<{success: boolean, roomData?: Room, message?: string}> {
- try {
- // 查找房间 - 先从本地缓存查询
- let room: Room | null = null
-
- // 检查本地缓存中是否有该房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${gameId}-${roomId}`
- if (roomsObj[roomKey]) {
- room = roomsObj[roomKey]
- } else if (mockRooms[roomKey]) {
- // 使用mock数据
- room = mockRooms[roomKey]
- }
-
- if (!room) {
- return { success: false, message: '房间不存在' }
- }
-
- // 检查房间是否已满
- if (room.users && room.users.length >= room.maxPlayers) {
- return { success: false, message: '房间已满' }
- }
-
- // 检查用户是否已在房间中
- const existingUser = room.users.find(u => u.openid === userData.openid)
- if (!existingUser) {
- // 添加用户到房间
- room.users.push(userData)
-
- // 更新本地缓存
- roomsObj[roomKey] = room
- Taro.setStorageSync('allRooms', JSON.stringify(roomsObj))
- }
-
- // 保存到最近加入的房间
- const roomInfo: Room = {
- roomId: room.roomId,
- name: room.name,
- gameId: room.gameId,
- gameTitle: room.gameTitle,
- maxPlayers: room.maxPlayers,
- visibility: room.visibility,
- hosterId: room.hosterId,
- createTime: room.createTime,
- startTime: room.startTime,
- endTime: room.endTime,
- status: room.status,
- users: room.users
- }
-
- // 更新最近房间列表
- this.saveToRecentRooms(roomInfo)
-
- return { success: true, roomData: room }
- } catch (error) {
- console.error('加入房间失败:', error)
- return { success: false, message: '加入房间失败' }
- }
- },
-
- // 保存到最近加入的房间
- async saveToRecentRooms(roomInfo: Room): Promise<void> {
- try {
- const recentRooms = Taro.getStorageSync('recentRooms') || '[]'
- const rooms = JSON.parse(recentRooms)
-
- // 检查是否已存在
- const existingIndex = rooms.findIndex((r: Room) => r.roomId === roomInfo.roomId)
- if (existingIndex !== -1) {
- // 移除已存在的
- rooms.splice(existingIndex, 1)
- }
-
- // 添加到最前面
- rooms.unshift(roomInfo)
-
- // 只保留最近10个房间
- if (rooms.length > 10) {
- rooms.pop()
- }
-
- Taro.setStorageSync('recentRooms', JSON.stringify(rooms))
- } catch (error) {
- console.error('保存最近房间失败:', error)
- }
- },
-
- // 退出房间
- async leaveRoom(gameId: string, roomId: string, userId: string): Promise<{success: boolean, message?: string}> {
- try {
- // 从本地缓存找到房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${gameId}-${roomId}`
-
- if (roomsObj[roomKey]) {
- const room = roomsObj[roomKey]
-
- // 过滤掉当前用户
- room.users = room.users.filter(u => u.openid !== userId)
-
- // 更新本地缓存
- roomsObj[roomKey] = room
- Taro.setStorageSync('allRooms', JSON.stringify(roomsObj))
- }
-
- return { success: true }
- } catch (error) {
- console.error('退出房间失败:', error)
- return { success: false, message: '退出房间失败' }
- }
- },
-
- // 获取房间信息
- async getRoomInfo(gameId: string, roomId: string): Promise<Room | null> {
- try {
- // 检查本地缓存中是否有该房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${gameId}-${roomId}`
-
- if (roomsObj[roomKey]) {
- return roomsObj[roomKey]
- }
-
- // 如果本地没有,使用mock数据
- if (mockRooms[roomKey]) {
- return mockRooms[roomKey]
- }
-
- return null
- } catch (error) {
- console.error('获取房间信息失败:', error)
- return null
- }
- },
- // 获取进行中的房间
- async getActiveRooms(userId: string): Promise<Room[]> {
- try {
- // 从缓存或模拟数据获取所有房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
-
- // 添加类型断言,确保 Object.values 返回的是 Room[] 类型
- const activeRooms = Object.values(roomsObj) as Room[];
-
- // 过滤出用户参与的且状态为"waiting"或"playing"的房间
- const userActiveRooms = activeRooms.filter(room => {
- return room.status !== RoomStatus.ENDED &&
- room.users &&
- room.users.some(u => u.openid === userId)
- })
-
- // 添加mock数据用于测试
- if (userActiveRooms.length === 0) {
- return [
- {
- roomId: 'room_001',
- name: '欢乐海龟汤',
- gameId: '1',
- gameTitle: '海龟汤',
- hosterId: 'host_123',
- status: RoomStatus.PLAYING,
- users: [
- {
- openid: userId,
- nickname: '玩家',
- avatar: '',
- roomRole: RoomRole.PLAYER,
- joinTime: Date.now(),
- isReady: true
- }
- ],
- createTime: Date.now() - 3600000,
- maxPlayers: 10,
- visibility: RoomVisibility.PUBLIC
- },
- {
- roomId: 'room_002',
- name: '趣味谜题',
- gameId: '1',
- gameTitle: '海龟汤',
- hosterId: userId,
- status: RoomStatus.WAITING,
- users: [
- {
- openid: userId,
- nickname: '玩家',
- avatar: '',
- roomRole: RoomRole.HOSTER,
- joinTime: Date.now(),
- isReady: true
- }
- ],
- createTime: Date.now() - 7200000,
- maxPlayers: 8,
- visibility: RoomVisibility.PUBLIC
- }
- ]
- }
-
- return userActiveRooms
- } catch (error) {
- console.error('获取进行中房间失败:', error)
- return []
- }
- },
- // 更新房间中的用户信息
- async updateUserInRoom(gameId: string, roomId: string, userId: string, userData: Partial<RoomUserInfo>): Promise<{success: boolean, message?: string}> {
- try {
- // 从本地缓存找到房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${gameId}-${roomId}`
-
- if (roomsObj[roomKey]) {
- const room = roomsObj[roomKey]
-
- // 找到对应用户
- const userIndex = room.users.findIndex(u => u.openid === userId)
- if (userIndex !== -1) {
- // 更新用户信息
- room.users[userIndex] = {
- ...room.users[userIndex],
- ...userData
- }
-
- // 更新本地缓存
- roomsObj[roomKey] = room
- Taro.setStorageSync('allRooms', JSON.stringify(roomsObj))
-
- return { success: true }
- } else {
- return { success: false, message: '用户不在房间中' }
- }
- } else if (mockRooms[roomId]) {
- // 更新mock数据
- const room = mockRooms[roomId]
- const userIndex = room.users.findIndex(u => u.openid === userId)
-
- if (userIndex !== -1) {
- room.users[userIndex] = {
- ...room.users[userIndex],
- ...userData
- }
- return { success: true }
- } else {
- return { success: false, message: '用户不在房间中' }
- }
- }
-
- return { success: false, message: '房间不存在' }
- } catch (error) {
- console.error('更新用户信息失败:', error)
- return { success: false, message: '更新用户信息失败' }
- }
- },
- // 更新房间状态
- async updateRoomStatus(gameId: string, roomId: string, status: RoomStatus): Promise<{success: boolean, message?: string}> {
- try {
- // 从本地缓存找到房间
- const allRooms = Taro.getStorageSync('allRooms') || '{}'
- const roomsObj = JSON.parse(allRooms)
- const roomKey = `${gameId}-${roomId}`
-
- if (roomsObj[roomKey]) {
- const room = roomsObj[roomKey]
-
- // 更新状态
- room.status = status
-
- // 更新本地缓存
- roomsObj[roomKey] = room
- Taro.setStorageSync('allRooms', JSON.stringify(roomsObj))
-
- // 同时更新最近房间列表中的状态
- const recentRooms = Taro.getStorageSync('recentRooms') || '[]'
- const rooms = JSON.parse(recentRooms)
- const roomIndex = rooms.findIndex((r: Room) => r.roomId === roomId)
-
- if (roomIndex !== -1) {
- rooms[roomIndex].status = status
- Taro.setStorageSync('recentRooms', JSON.stringify(rooms))
- }
-
- return { success: true }
- } else if (mockRooms[roomId]) {
- // 更新mock数据
- mockRooms[roomId].status = status
- return { success: true }
- }
-
- return { success: false, message: '房间不存在' }
- } catch (error) {
- console.error('更新房间状态失败:', error)
- return { success: false, message: '更新房间状态失败' }
- }
- }
- }
|