application [child-coding-miniapp] view page [pages/share] development
This commit is contained in:
@@ -41,6 +41,12 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "进度页面"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/share",
|
||||
"style": {
|
||||
"navigationBarTitleText": "分享页面"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
176
apps/child-coding-miniapp/src/pages/share.vue
Normal file
176
apps/child-coding-miniapp/src/pages/share.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<view class="share-container">
|
||||
<view v-if="achievement" class="achievement-card">
|
||||
<image v-if="achievement.icon" :src="achievement.icon" alt="成就图标" class="achievement-icon" />
|
||||
<h2>{{ achievement.title }}</h2>
|
||||
<p>{{ achievement.description }}</p>
|
||||
<view class="points">获得 {{ achievement.points }} 积分</view>
|
||||
<view class="unlock-time" v-if="userAchievement">解锁时间:{{ formatTime(userAchievement.unlockedAt) }}</view>
|
||||
</view>
|
||||
<view v-else class="loading">加载中...</view>
|
||||
<button @click="shareAchievement" class="share-btn">分享成就</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { auth, entities } from '@/lib/nvwa'
|
||||
import redirectToLogin from '@/custom/redirect-to-login'
|
||||
|
||||
interface Achievement {
|
||||
id: number
|
||||
title: string
|
||||
description: string
|
||||
icon: string
|
||||
type: string
|
||||
condition: any
|
||||
points: number
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
interface UserAchievement {
|
||||
id: number
|
||||
userId: string
|
||||
achievementId: number
|
||||
unlockedAt: string
|
||||
}
|
||||
|
||||
const achievement = ref<Achievement | null>(null)
|
||||
const userAchievement = ref<UserAchievement | null>(null)
|
||||
|
||||
onLoad(async (query: any) => {
|
||||
const achievementId = query.achievementId
|
||||
if (!achievementId) {
|
||||
uni.showToast({ title: '缺少成就ID', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const user = await auth.currentUser()
|
||||
if (!user) {
|
||||
await redirectToLogin()
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 查询成就信息
|
||||
const { data: achData, error: achError } = await entities.from("achievement").select("*").eq("id", parseInt(achievementId))
|
||||
if (achError) {
|
||||
uni.showToast({ title: '获取成就信息失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (achData.length > 0) {
|
||||
achievement.value = achData[0] as Achievement
|
||||
}
|
||||
|
||||
// 查询用户成就信息,确认已解锁
|
||||
const { data: uaData, error: uaError } = await entities.from("user_achievement").select("*").eq("achievement_id", parseInt(achievementId)).eq("user_id", user.id)
|
||||
if (!uaError && uaData.length > 0) {
|
||||
userAchievement.value = uaData[0] as UserAchievement
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: '加载数据失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
|
||||
const shareAchievement = () => {
|
||||
if (!achievement.value) return
|
||||
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneSession',
|
||||
type: 0,
|
||||
title: `我完成了成就:${achievement.value.title}`,
|
||||
summary: achievement.value.description,
|
||||
imageUrl: achievement.value.icon,
|
||||
success: () => {
|
||||
uni.showToast({ title: '分享成功' })
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '分享失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const formatTime = (time: string) => {
|
||||
return new Date(time).toLocaleString()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.share-container {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.achievement-card {
|
||||
background: #fff;
|
||||
padding: 30px;
|
||||
border-radius: 15px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.achievement-icon {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.achievement-card h2 {
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.achievement-card p {
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.points {
|
||||
color: #ff9900;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.unlock-time {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
background-color: #07c160;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
padding: 15px 30px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.share-btn:hover {
|
||||
background-color: #06a552;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user