application [child-coding-miniapp] view page [pages/share] development
This commit is contained in:
@@ -41,6 +41,12 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "进度页面"
|
"navigationBarTitleText": "进度页面"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/share",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "分享页面"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"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