application [child-coding-miniapp] view page [pages/levels] development
This commit is contained in:
@@ -23,6 +23,12 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "注册"
|
"navigationBarTitleText": "注册"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/levels",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "关卡列表"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
|
|||||||
163
apps/child-coding-miniapp/src/pages/levels.vue
Normal file
163
apps/child-coding-miniapp/src/pages/levels.vue
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<view class="levels-page">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">选择关卡</text>
|
||||||
|
</view>
|
||||||
|
<uni-list>
|
||||||
|
<uni-list-item
|
||||||
|
v-for="level in levels"
|
||||||
|
:key="level.id"
|
||||||
|
:title="level.title"
|
||||||
|
:note="level.description"
|
||||||
|
@click="enterLevel(level)"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="level-info">
|
||||||
|
<view class="difficulty">难度: {{ getDifficultyText(level.difficulty) }}</view>
|
||||||
|
<view class="progress" :class="{ completed: getLevelProgress(level.id) }">
|
||||||
|
{{ getLevelProgress(level.id) ? '已完成' : '未完成' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { entities, auth } from '@/lib/nvwa'
|
||||||
|
|
||||||
|
interface Level {
|
||||||
|
id: number
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
difficulty: number
|
||||||
|
order: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UserLevelProgress {
|
||||||
|
level_id: number
|
||||||
|
completed: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const levels = ref<Level[]>([])
|
||||||
|
const progress = ref<UserLevelProgress[]>([])
|
||||||
|
const currentUser = ref<any>(null)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
currentUser.value = await auth.currentUser()
|
||||||
|
await loadLevels()
|
||||||
|
await loadProgress()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('初始化失败:', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function loadLevels() {
|
||||||
|
const { data, error } = await entities
|
||||||
|
.from('level')
|
||||||
|
.select('id, title, description, difficulty, order')
|
||||||
|
.order('order')
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('加载关卡失败:', error)
|
||||||
|
uni.showToast({
|
||||||
|
title: '加载关卡失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
levels.value = data || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadProgress() {
|
||||||
|
if (!currentUser.value?.id) return
|
||||||
|
|
||||||
|
const { data, error } = await entities
|
||||||
|
.from('user_level_progress')
|
||||||
|
.select('level_id, completed')
|
||||||
|
.eq('user_id', currentUser.value.id)
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('加载进度失败:', error)
|
||||||
|
} else {
|
||||||
|
progress.value = data || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLevelProgress(levelId: number): boolean {
|
||||||
|
return progress.value.find(p => p.level_id === levelId)?.completed || false
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDifficultyText(difficulty: number): string {
|
||||||
|
const texts = ['萌新', '简单', '中等', '挑战', '大师']
|
||||||
|
return texts[difficulty - 1] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
function enterLevel(level: Level) {
|
||||||
|
// TODO: 导航到关卡游戏页面
|
||||||
|
uni.showModal({
|
||||||
|
title: '进入关卡',
|
||||||
|
content: `即将进入关卡: ${level.title}`,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 暂时显示提示,后续可以导航到实际游戏页面
|
||||||
|
uni.showToast({
|
||||||
|
title: '关卡功能开发中',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.levels-page {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.difficulty {
|
||||||
|
color: #ffd93d;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress.completed {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress:not(.completed) {
|
||||||
|
background-color: #ff6b6b;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user