Browse Source

调整加入房间最大最近房间数量

wuzj 1 week ago
parent
commit
7ee634ea56
5 changed files with 187 additions and 112 deletions
  1. 9 12
      src/pages/room/create/index.vue
  2. 9 2
      src/pages/room/join/index.vue
  3. 72 32
      src/services/api/game.ts
  4. 96 65
      src/stores/game.ts
  5. 1 1
      src/stores/room.ts

+ 9 - 12
src/pages/room/create/index.vue

@@ -66,7 +66,7 @@ import { ref } from 'vue'
 import { useGameStore, type Game } from '@/stores/game'
 import { useUserStore } from '@/stores/user'
 import { useRoomStore } from '@/stores/room'
-import { roomAPI } from '@/services/api/room'
+// 移除 roomAPI 导入
 import Tabbar from '@/components/Tabbar.vue'
 
 // 随机房间名称列表
@@ -185,7 +185,7 @@ export default {
           hosterId: userStore.openid || 'temp_host_id',
           hosterName: userStore.nickname || '未知用户',
           createTime: Date.now(),
-          status: 'waiting' as 'waiting' | 'playing' | 'ended', // 使用类型断言确保类型匹配
+          status: 'waiting' as 'waiting' | 'playing' | 'ended',
           users: [{
             id: userStore.openid || 'temp_host_id',
             name: userStore.nickname || '未知用户',
@@ -195,18 +195,14 @@ export default {
           }]
         }
         
-        // 保存到store
-        roomStore.setCurrentRoom(roomData)
+        // 直接使用roomStore创建房间,移除对roomAPI的直接调用
+        const result = await roomStore.createRoom(roomData)
         
-        // 同步到服务器
-        const result = await roomAPI.createRoom(roomData)
-        
-        if (result.success) {
-          Taro.navigateTo({
-            url: `/pages/room/waiting/index?roomId=${result.roomId}`
-          })
+        if (result.success && result.roomId) {
+          // 使用 roomStore 的导航方法
+          roomStore.navigateToRoomPage(result.roomId)
         } else {
-          throw new Error('创建房间失败')
+          throw new Error(result.message || '创建房间失败')
         }
       } catch (error) {
         console.error('创建房间失败:', error)
@@ -241,6 +237,7 @@ export default {
 </script>
 
 <style lang="scss">
+/* 保持样式不变 */
 .create-room-page {
   padding: $spacing-base;
   background-color: $background-color-base;

+ 9 - 2
src/pages/room/join/index.vue

@@ -278,8 +278,12 @@ export default {
 .join-room-page {
   padding: $spacing-base;
   background-color: $background-color-base;
-  min-height: 100vh;
-  padding-bottom: $spacing-large * 4; // 为底部tabbar留出空间
+  height: 100vh; /* 改为固定高度 */
+  overflow: hidden; /* 防止内容溢出导致滚动 */
+  box-sizing: border-box; /* 确保padding不会增加总高度 */
+  display: flex;
+  flex-direction: column;
+  padding-bottom: calc($spacing-large * 4 + 20px); /* 为底部tabbar留出足够空间 */
   
   .header {
     margin-bottom: $spacing-large;
@@ -296,6 +300,7 @@ export default {
     padding: $spacing-large;
     margin-bottom: $spacing-base;
     box-shadow: $shadow-light;
+    flex-shrink: 0; /* 防止被压缩 */
     
     .qr-icon {
       margin-bottom: $spacing-large;
@@ -327,6 +332,7 @@ export default {
     padding: $spacing-large;
     margin-bottom: $spacing-large;
     box-shadow: $shadow-light;
+    flex-shrink: 0; /* 防止被压缩 */
     
     .input-group, .password-group {
       margin-bottom: $spacing-large;
@@ -346,6 +352,7 @@ export default {
     padding: $spacing-base $spacing-base $spacing-large;
     margin-top: $spacing-large;
     box-shadow: $shadow-light;
+    flex-shrink: 0; /* 防止被压缩 */
     
     .room-list {
       .room-item {

+ 72 - 32
src/services/api/game.ts

@@ -1,6 +1,32 @@
 //处理通用游戏列表和游戏详情的获取
 import Taro from '@tarojs/taro'
-import { Game } from '@/stores/game'
+
+// 游戏数据接口移动到API层
+export interface Game {
+  id: string;
+  title: string;
+  image: string;
+  players: string;
+  duration: string;
+  rating: number;
+  isNew: boolean;
+  isHot: boolean;
+  description: string;
+  rules: string;
+  category: string;
+  tips: string[];
+  examples: {
+    question: string;
+    answer: string;
+  }[];
+}
+
+// API返回结果接口
+export interface ApiResult<T> {
+  success: boolean;
+  data?: T;
+  message?: string;
+}
 
 // 控制是否使用云函数(true)或mock数据(false)
 const USE_CLOUD = false
@@ -83,9 +109,10 @@ const mockGames: Game[] = [
 
 // 游戏通用API
 export const gameAPI = {
-  async getGames(): Promise<Game[]> {
-    if (USE_CLOUD && process.env.TARO_ENV === 'weapp') {
-      try {
+  // 获取游戏列表
+  async getGames(): Promise<ApiResult<Game[]>> {
+    try {
+      if (USE_CLOUD && process.env.TARO_ENV === 'weapp') {
         // 云函数实现
         const result = await Taro.cloud.callFunction({
           name: 'getGames',
@@ -94,26 +121,33 @@ export const gameAPI = {
         // 使用类型断言处理结果
         if (result && typeof result === 'object' && 'result' in result) {
           const cloudResult = result.result as any
-          return cloudResult?.data || mockGames
+          return { 
+            success: true, 
+            data: cloudResult?.data || mockGames 
+          }
         }
-        return mockGames
-      } catch (error) {
-        console.error('获取游戏列表失败:', error)
-        return mockGames
+        return { success: false, message: '获取游戏列表失败' }
+      } else {
+        // Mock实现
+        return new Promise(resolve => {
+          setTimeout(() => {
+            resolve({ success: true, data: mockGames })
+          }, 500) // 模拟网络延迟
+        })
+      }
+    } catch (error) {
+      console.error('获取游戏列表失败:', error)
+      return { 
+        success: false, 
+        message: error.message || '获取游戏列表失败' 
       }
-    } else {
-      // Mock实现
-      return new Promise(resolve => {
-        setTimeout(() => {
-          resolve(mockGames)
-        }, 500) // 模拟网络延迟
-      })
     }
   },
 
-  async getGameDetail(id: string): Promise<Game | null> {
-    if (USE_CLOUD && process.env.TARO_ENV === 'weapp') {
-      try {
+  // 获取游戏详情
+  async getGameDetail(id: string): Promise<ApiResult<Game | null>> {
+    try {
+      if (USE_CLOUD && process.env.TARO_ENV === 'weapp') {
         // 云函数实现
         const result = await Taro.cloud.callFunction({
           name: 'getGameDetail',
@@ -123,21 +157,27 @@ export const gameAPI = {
         // 使用类型断言处理结果
         if (result && typeof result === 'object' && 'result' in result) {
           const cloudResult = result.result as any
-          return cloudResult?.data || null
+          return { 
+            success: true, 
+            data: cloudResult?.data || null 
+          }
         }
-        return null
-      } catch (error) {
-        console.error('获取游戏详情失败:', error)
-        return null
+        return { success: false, message: '获取游戏详情失败' }
+      } else {
+        // Mock实现
+        return new Promise(resolve => {
+          setTimeout(() => {
+            const game = mockGames.find(g => g.id === id)
+            resolve({ success: true, data: game || null })
+          }, 300) // 模拟网络延迟
+        })
+      }
+    } catch (error) {
+      console.error('获取游戏详情失败:', error)
+      return { 
+        success: false, 
+        message: error.message || '获取游戏详情失败' 
       }
-    } else {
-      // Mock实现
-      return new Promise(resolve => {
-        setTimeout(() => {
-          const game = mockGames.find(g => g.id === id)
-          resolve(game || null)
-        }, 300) // 模拟网络延迟
-      })
     }
   }
 }

+ 96 - 65
src/stores/game.ts

@@ -1,73 +1,104 @@
-//管理游戏列表和通用游戏详情
+// 管理游戏列表和通用游戏详情
 import { defineStore } from 'pinia'
-import { gameAPI } from '@/services/api/game'
+import { ref, computed } from 'vue'
+import { gameAPI, type Game } from '@/services/api/game'
 
-// 游戏数据接口
-export interface Game {
-  id: string;
-  title: string;
-  image: string;
-  players: string;
-  duration: string;
-  rating: number;
-  isNew: boolean;
-  isHot: boolean;
-  description: string;
-  rules: string;
-  category: string;
-  tips: string[];
-  examples: {
-    question: string;
-    answer: string;
-  }[];
-}
-
-export const useGameStore = defineStore('game', {
-  state: () => ({
-    games: [] as Game[],
-    loading: false,
-    currentGame: null as Game | null,
-  }),
+export const useGameStore = defineStore('game', () => {
+  // 状态
+  const games = ref<Game[]>([])
+  const currentGame = ref<Game | null>(null)
+  const loading = ref(false)
+  const error = ref<string | null>(null)
+  
+  // 计算属性
+  const hotGames = computed(() => games.value.filter(game => game.isHot))
+  const newGames = computed(() => games.value.filter(game => game.isNew))
   
-  actions: {
-    // 获取游戏列表
-    async fetchGames() {
-      this.loading = true;
-      try {
-        this.games = await gameAPI.getGames();
-      } catch (error) {
-        console.error('获取游戏列表失败:', error);
-        this.games = [];
-      } finally {
-        this.loading = false;
+  // 获取游戏列表
+  async function fetchGames() {
+    loading.value = true
+    error.value = null
+    
+    try {
+      const response = await gameAPI.getGames()
+      
+      if (response.success && response.data) {
+        games.value = response.data
+      } else {
+        error.value = response.message || '获取游戏列表失败'
+        games.value = []
       }
-    },
+    } catch (e) {
+      console.error('获取游戏列表失败:', e)
+      error.value = '获取游戏列表失败'
+      games.value = []
+    } finally {
+      loading.value = false
+    }
+  }
+  
+  // 获取游戏详情
+  async function getGameDetail(id: string): Promise<Game | null> {
+    // 先从缓存中查找
+    const cachedGame = games.value.find(game => game.id === id)
+    if (cachedGame) {
+      currentGame.value = cachedGame
+      return cachedGame
+    }
+    
+    // 如果缓存中没有,从API获取
+    loading.value = true
+    error.value = null
     
-    // 获取游戏详情
-    async getGameDetail(id: string) {
-      try {
-        // 查找本地缓存
-        const game = this.games.find(game => game.id === id);
-        if (game) {
-          this.currentGame = game;
-          return game;
-        }
-        
-        // 如果本地没有,从API获取
-        const gameData = await gameAPI.getGameDetail(id);
-        if (gameData) {
-          this.currentGame = gameData;
-          return gameData;
-        }
-        
-        // 如果没有找到,返回null
-        this.currentGame = null;
-        return null;
-      } catch (error) {
-        console.error('获取游戏详情失败:', error);
-        this.currentGame = null;
-        return null;
+    try {
+      const response = await gameAPI.getGameDetail(id)
+      
+      if (response.success && response.data) {
+        currentGame.value = response.data
+        return response.data
+      } else {
+        error.value = response.message || '获取游戏详情失败'
+        currentGame.value = null
+        return null
       }
+    } catch (e) {
+      console.error('获取游戏详情失败:', e)
+      error.value = '获取游戏详情失败'
+      currentGame.value = null
+      return null
+    } finally {
+      loading.value = false
     }
   }
-}) 
+  
+  // 设置当前游戏
+  function setCurrentGame(game: Game | null) {
+    currentGame.value = game
+  }
+  
+  // 清除游戏数据
+  function clearGames() {
+    games.value = []
+    currentGame.value = null
+    error.value = null
+  }
+  
+  return {
+    // 状态
+    games,
+    currentGame,
+    loading,
+    error,
+    hotGames,
+    newGames,
+    
+    // 方法
+    fetchGames,
+    getGameDetail,
+    setCurrentGame,
+    clearGames
+  }
+})
+
+// 重新导出Game类型,方便使用
+export type { Game } from '@/services/api/game'

+ 1 - 1
src/stores/room.ts

@@ -357,7 +357,7 @@ export const useRoomStore = defineStore('room', () => {
   
   // 为join页面提供的限制条数的计算属性
   const limitedRecentRooms = computed(() => {
-    return recentRooms.value.slice(0, 3) // 只显示最近3条
+    return recentRooms.value.slice(0, 2) // 只显示最近3条
   })
   
   // 修改 joinRoomById 方法,确保返回房间数据