|
@@ -33,23 +33,32 @@
|
|
|
游戏设置
|
|
|
</nut-divider>
|
|
|
|
|
|
- <!-- 主题选择 -->
|
|
|
- <view class="setting-item">
|
|
|
- <view class="setting-label">游戏主题</view>
|
|
|
- <view class="setting-value" @click="showThemeSelector = true">
|
|
|
- {{ selectedTheme?.text || '请选择主题' }}
|
|
|
- <down size="12" color="#999"></down>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 题目选择 -->
|
|
|
- <view class="setting-item" v-if="selectedTheme">
|
|
|
- <view class="setting-label">游戏题目</view>
|
|
|
- <view class="setting-value" @click="showPuzzleSelector = true">
|
|
|
- {{ selectedPuzzle?.text || '请选择题目' }}
|
|
|
- <down size="12" color="#999"></down>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
+ <!-- 主题选择器 -->
|
|
|
+ <nut-popup position="bottom" v-model:visible="showThemeSelector">
|
|
|
+ <nut-cascader
|
|
|
+ v-model="selectedThemeValue"
|
|
|
+ v-model:visible="showThemeSelector"
|
|
|
+ title="选择游戏主题"
|
|
|
+ text-key="text"
|
|
|
+ value-key="value"
|
|
|
+ children-key="children"
|
|
|
+ :options="themeOptions"
|
|
|
+ @change="onThemeChange"
|
|
|
+ />
|
|
|
+ </nut-popup>
|
|
|
+
|
|
|
+ <!-- 题目选择器 -->
|
|
|
+ <nut-popup position="bottom" v-model:visible="showPuzzleSelector">
|
|
|
+ <nut-cascader
|
|
|
+ v-model="selectedPuzzleValue"
|
|
|
+ v-model:visible="showPuzzleSelector"
|
|
|
+ title="选择游戏题目"
|
|
|
+ text-key="text"
|
|
|
+ value-key="value"
|
|
|
+ :options="puzzleOptions"
|
|
|
+ @change="onPuzzleChange"
|
|
|
+ />
|
|
|
+ </nut-popup>
|
|
|
|
|
|
<!-- 难度选择 -->
|
|
|
<view class="setting-item">
|
|
@@ -303,11 +312,17 @@ export default {
|
|
|
|
|
|
// 游戏设置相关变量
|
|
|
const selectedDifficulty = ref(TurtleSoupDifficulty.MEDIUM)
|
|
|
- const selectedTheme = ref<CascaderOption | null>(null)
|
|
|
- const selectedPuzzle = ref<CascaderOption | null>(null)
|
|
|
const showThemeSelector = ref(false)
|
|
|
const showPuzzleSelector = ref(false)
|
|
|
|
|
|
+ // 主题和题目选择值
|
|
|
+ const selectedThemeValue = ref(['']) // 初始化为空数组或者根据默认值设置
|
|
|
+ const selectedPuzzleValue = ref(['']) // 初始化为空数组或者根据默认值设置
|
|
|
+
|
|
|
+ // 选中的主题和题目对象,用于显示
|
|
|
+ const selectedTheme = ref<CascaderOption | null>(null)
|
|
|
+ const selectedPuzzle = ref<CascaderOption | null>(null)
|
|
|
+
|
|
|
// 主题选项
|
|
|
const themeOptions = ref<CascaderOption[]>([
|
|
|
{
|
|
@@ -329,7 +344,7 @@ export default {
|
|
|
{
|
|
|
value: 'scifi',
|
|
|
text: '科幻主题',
|
|
|
- disabled: false, // 暂时改为false或删除此属性
|
|
|
+ disabled: false,
|
|
|
children: [
|
|
|
{ value: 'space', text: '太空探险' },
|
|
|
{ value: 'future', text: '未来世界' }
|
|
@@ -415,13 +430,11 @@ export default {
|
|
|
const themes = await turtleSoupStore.loadThemes()
|
|
|
|
|
|
// 将API返回的主题格式化为Cascader需要的格式
|
|
|
- // 这里仅为示例,实际需要根据API返回格式调整
|
|
|
if (themes && themes.length) {
|
|
|
themeOptions.value = themes.map(theme => ({
|
|
|
value: theme.id,
|
|
|
text: theme.name,
|
|
|
- disabled: theme.isLocked, // 根据是否解锁决定是否可选
|
|
|
- children: [] // 选择主题后会动态加载题目列表
|
|
|
+ disabled: theme.isLocked
|
|
|
}))
|
|
|
}
|
|
|
} catch (error) {
|
|
@@ -440,7 +453,7 @@ export default {
|
|
|
puzzleOptions.value = puzzles.map(puzzle => ({
|
|
|
value: puzzle.id,
|
|
|
text: puzzle.title,
|
|
|
- disabled: puzzle.isLocked // 使用isLocked替换!puzzle.isUnlocked
|
|
|
+ disabled: puzzle.isLocked
|
|
|
}))
|
|
|
} else {
|
|
|
puzzleOptions.value = []
|
|
@@ -451,21 +464,38 @@ export default {
|
|
|
}
|
|
|
|
|
|
// 监听主题选择变化
|
|
|
- const onThemeChange = async ({ value, selectedOptions }: any) => {
|
|
|
- // 保存选中的主题
|
|
|
- selectedTheme.value = selectedOptions[0]
|
|
|
-
|
|
|
- // 加载该主题下的题目
|
|
|
- await loadPuzzles(value[0])
|
|
|
-
|
|
|
- // 重置题目选择
|
|
|
- selectedPuzzle.value = null
|
|
|
+ const onThemeChange = async (value: string[], pathNodes: CascaderOption[]) => {
|
|
|
+ if (value.length > 0 && pathNodes.length > 0) {
|
|
|
+ // 保存选中的主题
|
|
|
+ selectedTheme.value = {
|
|
|
+ value: value[0],
|
|
|
+ text: pathNodes[0].text
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载该主题下的题目
|
|
|
+ await loadPuzzles(value[0])
|
|
|
+
|
|
|
+ // 重置题目选择
|
|
|
+ selectedPuzzle.value = null
|
|
|
+ selectedPuzzleValue.value = ['']
|
|
|
+
|
|
|
+ // 关闭选择器
|
|
|
+ showThemeSelector.value = false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 监听题目选择变化
|
|
|
- const onPuzzleChange = ({ selectedOptions }: any) => {
|
|
|
- // 保存选中的题目
|
|
|
- selectedPuzzle.value = selectedOptions[0]
|
|
|
+ const onPuzzleChange = (value: string[], pathNodes: CascaderOption[]) => {
|
|
|
+ if (value.length > 0 && pathNodes.length > 0) {
|
|
|
+ // 保存选中的题目
|
|
|
+ selectedPuzzle.value = {
|
|
|
+ value: value[0],
|
|
|
+ text: pathNodes[0].text
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭选择器
|
|
|
+ showPuzzleSelector.value = false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 准备/取消准备(玩家)
|
|
@@ -575,6 +605,15 @@ export default {
|
|
|
// 这里不需要额外处理,因为RoomCode组件内部已处理了分享逻辑
|
|
|
}
|
|
|
|
|
|
+ // 监听难度变化,如果已选择主题则重新加载题目
|
|
|
+ watch(selectedDifficulty, async (newVal) => {
|
|
|
+ if (selectedTheme.value) {
|
|
|
+ await loadPuzzles(selectedTheme.value.value)
|
|
|
+ selectedPuzzle.value = null // 重置题目选择
|
|
|
+ selectedPuzzleValue.value = [''] // 重置级联选择器的值
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
// 页面加载时初始化
|
|
|
onMounted(() => {
|
|
|
initPage()
|
|
@@ -585,17 +624,6 @@ export default {
|
|
|
stopRoomListener()
|
|
|
})
|
|
|
|
|
|
- // 监听难度变化,如果已选择主题则重新加载题目
|
|
|
- watch(selectedDifficulty, async (newVal) => {
|
|
|
- if (selectedTheme.value) {
|
|
|
- await loadPuzzles(selectedTheme.value.value)
|
|
|
- selectedPuzzle.value = null // 重置题目选择
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- const selectedThemeValue = ref([])
|
|
|
- const selectedPuzzleValue = ref([])
|
|
|
-
|
|
|
return {
|
|
|
currentRoom,
|
|
|
isHost,
|