|
@@ -1,636 +1,228 @@
|
|
|
-// services/games/turtlesoup.ts
|
|
|
import { Result, createSuccess, createError } from '@/types/result'
|
|
|
import { cloudApi } from '@/api'
|
|
|
import { USE_MOCK } from '@/services'
|
|
|
-import {
|
|
|
+import {
|
|
|
type TurtleSoupGameHostView,
|
|
|
type TurtleSoupGamePlayerView,
|
|
|
- type TurtleSoupQuestion,
|
|
|
- type TurtleSoupHint,
|
|
|
type TurtleSoupGameSettings,
|
|
|
- type TurtleSoupGameResult,
|
|
|
type TurtleSoupTheme,
|
|
|
type TurtleSoupPuzzle,
|
|
|
TurtleSoupGameStatus,
|
|
|
TurtleSoupDifficulty,
|
|
|
- TurtleSoupAnswerType,
|
|
|
TurtleSoupThemeType
|
|
|
} from '@/types/games/turtlesoup'
|
|
|
|
|
|
-// Mock 主题数据
|
|
|
+// Mock 主题数据(字段同步 themeId)
|
|
|
const mockThemes: TurtleSoupTheme[] = [
|
|
|
{
|
|
|
- id: 'theme-1',
|
|
|
+ themeId: 'theme-1',
|
|
|
name: '经典解谜',
|
|
|
description: '基础主题 · 免费',
|
|
|
type: TurtleSoupThemeType.BASIC,
|
|
|
isLocked: false
|
|
|
},
|
|
|
{
|
|
|
- id: 'theme-2',
|
|
|
+ themeId: 'theme-2',
|
|
|
name: '环球影城',
|
|
|
description: '特色主题 · 20元/小时',
|
|
|
type: TurtleSoupThemeType.PREMIUM,
|
|
|
price: 20,
|
|
|
isNew: true,
|
|
|
isLocked: true
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'theme-3',
|
|
|
- name: '迪士尼奇幻',
|
|
|
- description: '特色主题 · 15元/小时',
|
|
|
- type: TurtleSoupThemeType.PREMIUM,
|
|
|
- price: 15,
|
|
|
- isLocked: true
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'theme-4',
|
|
|
- name: '奇幻冒险',
|
|
|
- description: '特色主题 · 12元/小时',
|
|
|
- type: TurtleSoupThemeType.PREMIUM,
|
|
|
- price: 12,
|
|
|
- isLocked: true
|
|
|
}
|
|
|
]
|
|
|
|
|
|
-// Mock 题目数据
|
|
|
+// Mock 题目数据(字段同步 puzzleId 等)
|
|
|
const mockPuzzles: TurtleSoupPuzzle[] = [
|
|
|
{
|
|
|
- id: 'puzzle-1',
|
|
|
+ puzzleId: 'puzzle-1',
|
|
|
+ themeId: 'theme-1',
|
|
|
title: '神秘的手表',
|
|
|
- description: '简单 · 平均用时25分钟',
|
|
|
+ scenario: '一个男人收到了一块神秘的手表...',
|
|
|
+ truth: '这块手表可以预知未来...',
|
|
|
+ keyClues: ['这块手表有特殊功能。', '它能预测未来。'],
|
|
|
+ hints: [
|
|
|
+ { keyword: '特殊功能', sentence: '手表可以预知未来。' }
|
|
|
+ ],
|
|
|
difficulty: TurtleSoupDifficulty.EASY,
|
|
|
averageDuration: 25
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'puzzle-2',
|
|
|
- title: '迷路的青蛙',
|
|
|
- description: '中等 · 平均用时35分钟',
|
|
|
- difficulty: TurtleSoupDifficulty.MEDIUM,
|
|
|
- averageDuration: 35
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'puzzle-3',
|
|
|
- title: '消失的邮轮',
|
|
|
- description: '困难 · 平均用时50分钟',
|
|
|
- difficulty: TurtleSoupDifficulty.HARD,
|
|
|
- averageDuration: 50
|
|
|
}
|
|
|
]
|
|
|
|
|
|
-// Mock 主持人视图数据
|
|
|
+// Mock 主持人视图
|
|
|
const mockHostView: TurtleSoupGameHostView = {
|
|
|
id: 'game-1',
|
|
|
roomId: 'room-1',
|
|
|
title: '欢乐海龟汤',
|
|
|
- roomCode: 'ABC123',
|
|
|
- description: '一个男人收到了一块神秘的手表,戴上后就再也无法取下来,一周后他自杀了,为什么?',
|
|
|
- solution: '这个手表可以预知未来24小时内将发生的事情。男人看到了自己将在一周后死亡,尝试了各种方法改变命运但都失败了。最终,由于无法承受这种预知但无法改变的煎熬,他选择了自杀。这反而实现了手表的预言。',
|
|
|
- hints: [
|
|
|
- {
|
|
|
- id: 'hint-1',
|
|
|
- content: '这块手表有特殊功能,不是普通手表。',
|
|
|
- revealed: true,
|
|
|
- revealedAt: Date.now() - 600000 // 10分钟前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'hint-2',
|
|
|
- content: '手表可以显示未来将发生的事情。',
|
|
|
- revealed: true,
|
|
|
- revealedAt: Date.now() - 300000 // 5分钟前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'hint-3',
|
|
|
- content: '男人尝试了多种方法改命运,但都失败了。',
|
|
|
- revealed: false
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'hint-4',
|
|
|
- content: '手表预测的是他的死亡,但没有预测到真体方式。',
|
|
|
- revealed: false
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'hint-5',
|
|
|
- content: '手表的预言总是会实现,但方式可能有所不同。',
|
|
|
- revealed: false
|
|
|
- }
|
|
|
- ],
|
|
|
- questions: [
|
|
|
- {
|
|
|
- id: 'q-1',
|
|
|
- content: '手表是有特殊功能的吗?',
|
|
|
- askedBy: 'user-1',
|
|
|
- askedByName: '小明',
|
|
|
- timestamp: Date.now() - 900000, // 15分钟前
|
|
|
- answered: true,
|
|
|
- answer: TurtleSoupAnswerType.YES,
|
|
|
- answeredAt: Date.now() - 890000 // 14分50秒前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'q-2',
|
|
|
- content: '这块手表能预测未来吗?',
|
|
|
- askedBy: 'user-2',
|
|
|
- askedByName: '小红',
|
|
|
- timestamp: Date.now() - 600000, // 10分钟前
|
|
|
- answered: true,
|
|
|
- answer: TurtleSoupAnswerType.YES,
|
|
|
- answeredAt: Date.now() - 590000 // 9分50秒前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'q-3',
|
|
|
- content: '是因为手表带来厄运吗?',
|
|
|
- askedBy: 'user-1',
|
|
|
- askedByName: '小明',
|
|
|
- timestamp: Date.now() - 300000, // 5分钟前
|
|
|
- answered: false
|
|
|
- }
|
|
|
- ],
|
|
|
+ theme: mockThemes[0],
|
|
|
+ puzzle: mockPuzzles[0],
|
|
|
status: TurtleSoupGameStatus.ACTIVE,
|
|
|
- createTime: Date.now() - 3600000, // 1小时前
|
|
|
- startTime: Date.now() - 1800000, // 30分钟前
|
|
|
+ startTime: Date.now() - 1800000,
|
|
|
currentTime: Date.now(),
|
|
|
- duration: 30, // 30分钟
|
|
|
+ duration: 30,
|
|
|
hostId: 'host-user',
|
|
|
hostName: '小明 (我)',
|
|
|
players: [
|
|
|
{
|
|
|
id: 'user-1',
|
|
|
name: '小红',
|
|
|
- avatar: 'https://example.com/avatar1.png',
|
|
|
- joinedAt: Date.now() - 3000000, // 50分钟前
|
|
|
+ avatar: '',
|
|
|
+ joinedAt: Date.now() - 3000000,
|
|
|
questionCount: 2
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'user-2',
|
|
|
- name: '小李',
|
|
|
- avatar: 'https://example.com/avatar2.png',
|
|
|
- joinedAt: Date.now() - 2700000, // 45分钟前
|
|
|
- questionCount: 1
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'user-3',
|
|
|
- name: '丽丽',
|
|
|
- avatar: 'https://example.com/avatar3.png',
|
|
|
- joinedAt: Date.now() - 1800000, // 30分钟前
|
|
|
- questionCount: 0
|
|
|
}
|
|
|
],
|
|
|
+ progress: 40,
|
|
|
+ difficulty: TurtleSoupDifficulty.MEDIUM,
|
|
|
settings: {
|
|
|
themeId: 'theme-1',
|
|
|
puzzleId: 'puzzle-1',
|
|
|
difficulty: TurtleSoupDifficulty.MEDIUM,
|
|
|
- maxPlayers: 10,
|
|
|
- isPrivate: false
|
|
|
- },
|
|
|
- playerCount: 3,
|
|
|
- progress: 40 // 40%
|
|
|
+ maxPlayers: 10
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// Mock 玩家视图数据
|
|
|
+// Mock 玩家视图
|
|
|
const mockPlayerView: TurtleSoupGamePlayerView = {
|
|
|
id: 'game-1',
|
|
|
roomId: 'room-1',
|
|
|
title: '欢乐海龟汤',
|
|
|
- description: '一个男人收到了一块神秘的手表,戴上后就再也无法取下来,一周后他自杀了,为什么?',
|
|
|
- revealedHints: [
|
|
|
- {
|
|
|
- id: 'hint-1',
|
|
|
- content: '这块手表有特殊功能,不是普通手表。',
|
|
|
- revealedAt: Date.now() - 600000 // 10分钟前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'hint-2',
|
|
|
- content: '手表可以显示未来将发生的事情。',
|
|
|
- revealedAt: Date.now() - 300000 // 5分钟前
|
|
|
- }
|
|
|
- ],
|
|
|
- myQuestions: [
|
|
|
- {
|
|
|
- id: 'q-1',
|
|
|
- content: '手表是有特殊功能的吗?',
|
|
|
- askedBy: 'user-1',
|
|
|
- askedByName: '小明 (我)',
|
|
|
- timestamp: Date.now() - 900000, // 15分钟前
|
|
|
- answered: true,
|
|
|
- answer: TurtleSoupAnswerType.YES,
|
|
|
- answeredAt: Date.now() - 890000 // 14分50秒前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'q-3',
|
|
|
- content: '是因为手表带来厄运吗?',
|
|
|
- askedBy: 'user-1',
|
|
|
- askedByName: '小明 (我)',
|
|
|
- timestamp: Date.now() - 300000, // 5分钟前
|
|
|
- answered: false
|
|
|
- }
|
|
|
- ],
|
|
|
- allQuestions: [
|
|
|
- {
|
|
|
- id: 'q-1',
|
|
|
- content: '手表是有特殊功能的吗?',
|
|
|
- askedByName: '小明 (我)',
|
|
|
- answer: TurtleSoupAnswerType.YES,
|
|
|
- timestamp: Date.now() - 900000 // 15分钟前
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'q-2',
|
|
|
- content: '这块手表能预测未来吗?',
|
|
|
- askedByName: '小红',
|
|
|
- answer: TurtleSoupAnswerType.YES,
|
|
|
- timestamp: Date.now() - 600000 // 10分钟前
|
|
|
- }
|
|
|
- ],
|
|
|
+ theme: mockThemes[0],
|
|
|
+ puzzle: mockPuzzles[0],
|
|
|
status: TurtleSoupGameStatus.ACTIVE,
|
|
|
- startTime: Date.now() - 1800000, // 30分钟前
|
|
|
+ startTime: Date.now() - 1800000,
|
|
|
currentTime: Date.now(),
|
|
|
- duration: 30, // 30分钟
|
|
|
+ duration: 30,
|
|
|
hostId: 'host-user',
|
|
|
- hostName: '小明',
|
|
|
- progress: 40, // 40%
|
|
|
+ hostName: '小明 (我)',
|
|
|
+ progress: 40,
|
|
|
difficulty: TurtleSoupDifficulty.MEDIUM,
|
|
|
+ settings: {
|
|
|
+ themeId: 'theme-1',
|
|
|
+ puzzleId: 'puzzle-1',
|
|
|
+ difficulty: TurtleSoupDifficulty.MEDIUM,
|
|
|
+ maxPlayers: 10
|
|
|
+ },
|
|
|
+ myPlayerInfo: {
|
|
|
+ id: 'user-1',
|
|
|
+ name: '小红',
|
|
|
+ avatar: '',
|
|
|
+ joinedAt: Date.now() - 3000000,
|
|
|
+ questionCount: 2
|
|
|
+ },
|
|
|
otherPlayers: [
|
|
|
{
|
|
|
id: 'user-2',
|
|
|
- name: '小红',
|
|
|
- avatar: 'https://example.com/avatar2.png'
|
|
|
- },
|
|
|
- {
|
|
|
- id: 'user-3',
|
|
|
name: '小李',
|
|
|
- avatar: 'https://example.com/avatar3.png'
|
|
|
+ avatar: ''
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
|
|
|
-// 海龟汤游戏服务
|
|
|
export const turtleSoupService = {
|
|
|
- /**
|
|
|
- * 获取主题列表
|
|
|
- */
|
|
|
async getThemes(): Promise<Result<TurtleSoupTheme[]>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess(mockThemes));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => resolve(createSuccess(mockThemes)), 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
return cloudApi.call<{ themes: TurtleSoupTheme[] }>('getTurtleSoupThemes')
|
|
|
.then(result => {
|
|
|
- if (result.success && result.data?.themes) {
|
|
|
- return createSuccess(result.data.themes);
|
|
|
- }
|
|
|
- return createError(result.message || '获取主题列表失败');
|
|
|
+ if (result.success && result.data?.themes) return createSuccess(result.data.themes)
|
|
|
+ return createError(result.message || '获取主题列表失败')
|
|
|
})
|
|
|
- .catch(error => {
|
|
|
- console.error('获取主题列表失败:', error);
|
|
|
- return createError(error.message || '获取主题列表失败');
|
|
|
- });
|
|
|
+ .catch(error => createError(error.message || '获取主题列表失败'))
|
|
|
},
|
|
|
-
|
|
|
|
|
|
- /**
|
|
|
- * 解锁主题
|
|
|
- * @param themeId 主题ID
|
|
|
- */
|
|
|
async unlockTheme(themeId: string): Promise<Result<TurtleSoupTheme>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- const theme = mockThemes.find(t => t.id === themeId);
|
|
|
- if (!theme) {
|
|
|
- resolve(createError('主题未找到'));
|
|
|
- } else {
|
|
|
- resolve(createSuccess(theme));
|
|
|
- }
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => {
|
|
|
+ const theme = mockThemes.find(t => t.themeId === themeId)
|
|
|
+ resolve(theme ? createSuccess(theme) : createError('主题未找到'))
|
|
|
+ }, 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
return cloudApi.call<{ theme: TurtleSoupTheme }>('unlockTurtleSoupTheme', { themeId })
|
|
|
- .then(result => {
|
|
|
- if (result.success && result.data?.theme) {
|
|
|
- return createSuccess(result.data.theme);
|
|
|
- }
|
|
|
- return createError(result.message || '解锁主题失败');
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- console.error('解锁主题失败:', error);
|
|
|
- return createError(error.message || '解锁主题失败');
|
|
|
- });
|
|
|
+ .then(result => result.success && result.data?.theme
|
|
|
+ ? createSuccess(result.data.theme)
|
|
|
+ : createError(result.message || '解锁主题失败'))
|
|
|
+ .catch(error => createError(error.message || '解锁主题失败'))
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取题目列表
|
|
|
- * @param themeId 主题ID
|
|
|
- * @param difficulty 可选的难度筛选
|
|
|
- */
|
|
|
+
|
|
|
async getPuzzles(themeId: string, difficulty?: TurtleSoupDifficulty): Promise<Result<TurtleSoupPuzzle[]>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- let puzzles = [...mockPuzzles];
|
|
|
-
|
|
|
- // 如果指定了难度,进行过滤
|
|
|
- if (difficulty) {
|
|
|
- puzzles = puzzles.filter(p => p.difficulty === difficulty);
|
|
|
- }
|
|
|
-
|
|
|
- resolve(createSuccess(puzzles));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => {
|
|
|
+ let puzzles = mockPuzzles.filter(p => p.themeId === themeId)
|
|
|
+ if (difficulty) puzzles = puzzles.filter(p => p.difficulty === difficulty)
|
|
|
+ resolve(createSuccess(puzzles))
|
|
|
+ }, 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
return cloudApi.call<{ puzzles: TurtleSoupPuzzle[] }>('getTurtleSoupPuzzles', { themeId, difficulty })
|
|
|
.then(result => {
|
|
|
- if (result.success && result.data?.puzzles) {
|
|
|
- return createSuccess(result.data.puzzles);
|
|
|
- }
|
|
|
- return createError(result.message || '获取题目列表失败');
|
|
|
+ if (result.success && result.data?.puzzles) return createSuccess(result.data.puzzles)
|
|
|
+ return createError(result.message || '获取题目列表失败')
|
|
|
})
|
|
|
- .catch(error => {
|
|
|
- console.error('获取题目列表失败:', error);
|
|
|
- return createError(error.message || '获取题目列表失败');
|
|
|
- });
|
|
|
+ .catch(error => createError(error.message || '获取题目列表失败'))
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取主持人游戏数据
|
|
|
- * @param gameId 游戏ID
|
|
|
- */
|
|
|
+
|
|
|
+ async createGame(settings: TurtleSoupGameSettings): Promise<Result<{ gameId: string, roomId: string, title: string }>> {
|
|
|
+ if (!settings.themeId) return createError('请选择游戏主题')
|
|
|
+ if (!settings.puzzleId) return createError('请选择游戏题目')
|
|
|
+ if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
+ return new Promise(resolve => setTimeout(() => {
|
|
|
+ const gameId = `game-${Date.now()}`
|
|
|
+ const roomId = `room-${Date.now()}`
|
|
|
+ resolve(createSuccess({
|
|
|
+ gameId,
|
|
|
+ roomId,
|
|
|
+ title: mockPuzzles.find(p => p.puzzleId === settings.puzzleId)?.title || '新游戏'
|
|
|
+ }))
|
|
|
+ }, 500))
|
|
|
+ }
|
|
|
+ return cloudApi.call<{ gameId: string, roomId: string, title: string }>('createTurtleSoupGame', settings)
|
|
|
+ },
|
|
|
+
|
|
|
async getHostGameData(gameId: string): Promise<Result<TurtleSoupGameHostView>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess(mockHostView));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => resolve(createSuccess(mockHostView)), 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
return cloudApi.call<{ game: TurtleSoupGameHostView }>('getTurtleSoupHostGame', { gameId })
|
|
|
- .then(result => {
|
|
|
- if (result.success && result.data?.game) {
|
|
|
- return createSuccess(result.data.game);
|
|
|
- }
|
|
|
- return createError(result.message || '获取游戏数据失败');
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- console.error('获取主持人游戏数据失败:', error);
|
|
|
- return createError(error.message || '获取游戏数据失败');
|
|
|
- });
|
|
|
+ .then(result => result.success && result.data?.game
|
|
|
+ ? createSuccess(result.data.game)
|
|
|
+ : createError(result.message || '获取游戏数据失败'))
|
|
|
+ .catch(error => createError(error.message || '获取主持人游戏数据失败'))
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取玩家游戏数据
|
|
|
- * @param gameId 游戏ID
|
|
|
- */
|
|
|
+
|
|
|
async getPlayerGameData(gameId: string): Promise<Result<TurtleSoupGamePlayerView>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess(mockPlayerView));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => resolve(createSuccess(mockPlayerView)), 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
return cloudApi.call<{ game: TurtleSoupGamePlayerView }>('getTurtleSoupPlayerGame', { gameId })
|
|
|
- .then(result => {
|
|
|
- if (result.success && result.data?.game) {
|
|
|
- return createSuccess(result.data.game);
|
|
|
- }
|
|
|
- return createError(result.message || '获取游戏数据失败');
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- console.error('获取玩家游戏数据失败:', error);
|
|
|
- return createError(error.message || '获取游戏数据失败');
|
|
|
- });
|
|
|
+ .then(result => result.success && result.data?.game
|
|
|
+ ? createSuccess(result.data.game)
|
|
|
+ : createError(result.message || '获取游戏数据失败'))
|
|
|
+ .catch(error => createError(error.message || '获取玩家游戏数据失败'))
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建新游戏
|
|
|
- * @param settings 游戏设置
|
|
|
- */
|
|
|
- async createGame(settings: TurtleSoupGameSettings): Promise<Result<{ gameId: string, roomId: string, title: string }>> {
|
|
|
- // 数据验证
|
|
|
- if (!settings.themeId) return createError('请选择游戏主题');
|
|
|
- if (!settings.puzzleId) return createError('请选择游戏题目');
|
|
|
-
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- const gameId = `game-${Date.now()}`;
|
|
|
- const roomId = `room-${Date.now()}`;
|
|
|
- resolve(createSuccess({
|
|
|
- gameId,
|
|
|
- roomId,
|
|
|
- title: mockPuzzles.find(p => p.id === settings.puzzleId)?.title || '新游戏'
|
|
|
- }));
|
|
|
- }, 500);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ gameId: string, roomId: string, title: string }>('createTurtleSoupGame', settings);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 为已有房间创建游戏
|
|
|
- * @param roomId 房间ID
|
|
|
- * @param settings 游戏设置
|
|
|
- */
|
|
|
- async createGameForRoom(roomId: string, settings: TurtleSoupGameSettings): Promise<Result<{ gameId: string }>> {
|
|
|
- // 数据验证
|
|
|
- if (!settings.themeId) return createError('请选择游戏主题');
|
|
|
- if (!settings.puzzleId) return createError('请选择游戏题目');
|
|
|
-
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- const gameId = `game-${Date.now()}`;
|
|
|
- resolve(createSuccess({ gameId }));
|
|
|
- }, 500);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ gameId: string }>('createTurtleSoupGameForRoom', { roomId, settings });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 开始游戏
|
|
|
- * @param gameId 游戏ID
|
|
|
- */
|
|
|
+
|
|
|
async startGame(gameId: string): Promise<Result<{ success: boolean }>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess({ success: true }));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => resolve(createSuccess({ success: true })), 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ success: boolean }>('startTurtleSoupGame', { gameId });
|
|
|
+ return cloudApi.call<{ success: boolean }>('startTurtleSoupGame', { gameId })
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 提交问题
|
|
|
- * @param gameId 游戏ID
|
|
|
- * @param content 问题内容
|
|
|
- */
|
|
|
- async submitQuestion(gameId: string, content: string): Promise<Result<{ questionId: string }>> {
|
|
|
- if (!content.trim()) {
|
|
|
- return createError('问题内容不能为空');
|
|
|
- }
|
|
|
-
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- const questionId = `q-${Date.now()}`;
|
|
|
- resolve(createSuccess({ questionId }));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ questionId: string }>('submitTurtleSoupQuestion', { gameId, content });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 回答问题
|
|
|
- * @param questionId 问题ID
|
|
|
- * @param answer 答案类型
|
|
|
- */
|
|
|
- async answerQuestion(questionId: string, answer: TurtleSoupAnswerType): Promise<Result<{ success: boolean }>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess({ success: true }));
|
|
|
- }, 200);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ success: boolean }>('answerTurtleSoupQuestion', { questionId, answer });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 公开提示
|
|
|
- * @param gameId 游戏ID
|
|
|
- * @param hintId 提示ID
|
|
|
- */
|
|
|
- async revealHint(gameId: string, hintId: string): Promise<Result<{ success: boolean }>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess({ success: true }));
|
|
|
- }, 200);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ success: boolean }>('revealTurtleSoupHint', { gameId, hintId });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 提交解答
|
|
|
- * @param gameId 游戏ID
|
|
|
- * @param solution 玩家提交的解答
|
|
|
- */
|
|
|
+
|
|
|
async submitSolution(gameId: string, solution: string): Promise<Result<{ correct: boolean }>> {
|
|
|
- if (!solution.trim()) {
|
|
|
- return createError('解答内容不能为空');
|
|
|
- }
|
|
|
-
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
+ if (!solution.trim()) return createError('解答内容不能为空')
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- // 模拟50%的概率答对
|
|
|
- const correct = Math.random() > 0.5;
|
|
|
- resolve(createSuccess({ correct }));
|
|
|
- }, 300);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => {
|
|
|
+ const correct = Math.random() > 0.5
|
|
|
+ resolve(createSuccess({ correct }))
|
|
|
+ }, 300))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ correct: boolean }>('submitTurtleSoupSolution', { gameId, solution });
|
|
|
+ return cloudApi.call<{ correct: boolean }>('submitTurtleSoupSolution', { gameId, solution })
|
|
|
},
|
|
|
-
|
|
|
- /**
|
|
|
- * 结束游戏
|
|
|
- * @param gameId 游戏ID
|
|
|
- * @param result 游戏结果数据
|
|
|
- */
|
|
|
- async endGame(gameId: string, result: {
|
|
|
- solved: boolean;
|
|
|
- solvedBy?: string;
|
|
|
- solvedByName?: string;
|
|
|
- solution?: string;
|
|
|
- }): Promise<Result<TurtleSoupGameResult>> {
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
- if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- const gameResult: TurtleSoupGameResult = {
|
|
|
- gameId,
|
|
|
- solved: result.solved,
|
|
|
- solvedBy: result.solvedBy,
|
|
|
- solvedByName: result.solvedByName,
|
|
|
- solution: result.solution,
|
|
|
- duration: 30, // 30分钟
|
|
|
- questionCount: 15,
|
|
|
- hintsRevealed: 2,
|
|
|
- completionTime: Date.now(),
|
|
|
- playerCount: 4
|
|
|
- };
|
|
|
-
|
|
|
- resolve(createSuccess(gameResult));
|
|
|
- }, 400);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<TurtleSoupGameResult>('endTurtleSoupGame', { gameId, result });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新游戏进度
|
|
|
- * @param gameId 游戏ID
|
|
|
- * @param progress 进度百分比(0-100)
|
|
|
- */
|
|
|
+
|
|
|
async updateProgress(gameId: string, progress: number): Promise<Result<{ success: boolean }>> {
|
|
|
- if (progress < 0 || progress > 100) {
|
|
|
- return createError('进度值必须在0-100之间');
|
|
|
- }
|
|
|
-
|
|
|
- // 如果在开发环境或非小程序环境,使用Mock数据
|
|
|
+ if (progress < 0 || progress > 100) return createError('进度值必须在0-100之间')
|
|
|
if (USE_MOCK || process.env.TARO_ENV !== 'weapp') {
|
|
|
- return new Promise(resolve => {
|
|
|
- setTimeout(() => {
|
|
|
- resolve(createSuccess({ success: true }));
|
|
|
- }, 200);
|
|
|
- });
|
|
|
+ return new Promise(resolve => setTimeout(() => resolve(createSuccess({ success: true })), 200))
|
|
|
}
|
|
|
-
|
|
|
- // 使用cloudApi调用云函数
|
|
|
- return cloudApi.call<{ success: boolean }>('updateTurtleSoupProgress', { gameId, progress });
|
|
|
+ return cloudApi.call<{ success: boolean }>('updateTurtleSoupProgress', { gameId, progress })
|
|
|
}
|
|
|
-};
|
|
|
+}
|