version 2
This commit is contained in:
@@ -158,7 +158,8 @@ const habits = {
|
||||
noPickyEating: { name: '不挑食', icon: '🥦' },
|
||||
washHands: { name: '勤洗手', icon: '🧼' },
|
||||
homeworkFast: { name: '写作业快', icon: '📝' },
|
||||
earlySleep: { name: '早睡', icon: '🌙' }
|
||||
earlySleep: { name: '早睡', icon: '🌙' },
|
||||
cleanRoom: { name: '打扫卫生', icon: '🧹' }
|
||||
};
|
||||
|
||||
// 坏习惯数据
|
||||
@@ -174,7 +175,7 @@ const monsters = {
|
||||
boss: {
|
||||
name: '坏习惯大魔王',
|
||||
health: 500,
|
||||
habits: ['brushTeeth', 'noBedLate', 'noPickyEating', 'washHands', 'homeworkFast', 'earlySleep']
|
||||
habits: ['brushTeeth', 'noBedLate', 'noPickyEating', 'washHands', 'homeworkFast', 'earlySleep', 'cleanRoom']
|
||||
}
|
||||
};
|
||||
|
||||
@@ -190,7 +191,7 @@ const badges = computed(() => starEnergyStore.badges);
|
||||
// 检查习惯是否已打卡
|
||||
const isChecked = (habit: keyof typeof habitData.value) => {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
return habitData.value[habit].lastChecked === today;
|
||||
return habitData.value[habit]?.lastChecked === today;
|
||||
};
|
||||
|
||||
// 打卡习惯
|
||||
|
||||
@@ -65,13 +65,38 @@
|
||||
<!-- 已兑换奖励 -->
|
||||
<div class="claimed-rewards" v-if="claimedRewards.length > 0">
|
||||
<h3 class="claimed-title">🎉 已兑换的奖励</h3>
|
||||
<div class="reward-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">已兑换:</span>
|
||||
<span class="stat-value">{{ claimedRewards.length }} 个</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">已给孩子:</span>
|
||||
<span class="stat-value">{{ givenRewards.length }} 个</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">待领取:</span>
|
||||
<span class="stat-value">{{ claimedRewards.length - givenRewards.length }} 个</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="claimed-grid">
|
||||
<div
|
||||
v-for="id in claimedRewards"
|
||||
:key="id"
|
||||
class="claimed-card"
|
||||
:class="{ given: givenRewards.includes(id) }"
|
||||
>
|
||||
{{ getRewardById(id)?.emoji }} {{ getRewardById(id)?.name }}
|
||||
<div class="claimed-content">
|
||||
{{ getRewardById(id)?.emoji }} {{ getRewardById(id)?.name }}
|
||||
</div>
|
||||
<button
|
||||
v-if="!givenRewards.includes(id)"
|
||||
class="give-btn"
|
||||
@click="markRewardAsGiven(id)"
|
||||
>
|
||||
已给孩子
|
||||
</button>
|
||||
<div v-else class="given-badge">已给孩子 ✓</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,6 +135,9 @@ const currentCategory = ref('all');
|
||||
// 已兑换奖励ID列表
|
||||
const claimedRewards = computed(() => starEnergyStore.claimedRewards);
|
||||
|
||||
// 已给孩子的奖励ID列表
|
||||
const givenRewards = computed(() => starEnergyStore.getGivenRewards || []);
|
||||
|
||||
// 弹窗状态
|
||||
const showSuccessModal = ref(false);
|
||||
const showInsufficientModal = ref(false);
|
||||
@@ -166,7 +194,7 @@ const rewards = [
|
||||
id: 'park_50',
|
||||
name: '去公园玩',
|
||||
description: '可以和爸爸妈妈去公园玩!',
|
||||
cost: 50,
|
||||
cost: 100,
|
||||
emoji: '🎡',
|
||||
category: 'activity'
|
||||
},
|
||||
@@ -191,7 +219,7 @@ const rewards = [
|
||||
id: 'zoo_100',
|
||||
name: '去动物园',
|
||||
description: '可以去动物园看小动物!',
|
||||
cost: 100,
|
||||
cost: 500,
|
||||
emoji: '🦁',
|
||||
category: 'activity'
|
||||
},
|
||||
@@ -200,7 +228,7 @@ const rewards = [
|
||||
id: 'lego_200',
|
||||
name: '乐高积木套装',
|
||||
description: '可以获得一套乐高积木!',
|
||||
cost: 200,
|
||||
cost: 400,
|
||||
emoji: '🧱',
|
||||
category: 'toy'
|
||||
},
|
||||
@@ -224,7 +252,7 @@ const rewards = [
|
||||
id: 'amusement_200',
|
||||
name: '游乐园一日游',
|
||||
description: '可以和爸爸妈妈去游乐园玩一整天!',
|
||||
cost: 200,
|
||||
cost: 500,
|
||||
emoji: '🎢',
|
||||
category: 'activity'
|
||||
},
|
||||
@@ -232,7 +260,7 @@ const rewards = [
|
||||
id: 'bike_200',
|
||||
name: '自行车一辆',
|
||||
description: '可以获得一辆全新的自行车!',
|
||||
cost: 200,
|
||||
cost: 1000,
|
||||
emoji: '🚲',
|
||||
category: 'toy'
|
||||
},
|
||||
@@ -250,7 +278,7 @@ const rewards = [
|
||||
id: 'family_trip_500',
|
||||
name: '家庭旅行',
|
||||
description: '可以和家人一起去旅行!',
|
||||
cost: 500,
|
||||
cost: 1000,
|
||||
emoji: '✈️',
|
||||
category: 'activity'
|
||||
},
|
||||
@@ -258,7 +286,7 @@ const rewards = [
|
||||
id: 'game_console_500',
|
||||
name: '游戏机',
|
||||
description: '可以获得一台游戏机!',
|
||||
cost: 500,
|
||||
cost: 2000,
|
||||
emoji: '🎮',
|
||||
category: 'toy'
|
||||
},
|
||||
@@ -372,7 +400,12 @@ const redeemReward = (reward: any) => {
|
||||
|
||||
// 根据ID获取奖励
|
||||
const getRewardById = (id: string) => {
|
||||
return rewards.find(reward => reward.id === id);
|
||||
return rewards.find(reward => reward.id === id) || { emoji: '🎁', name: '未知奖励' };
|
||||
};
|
||||
|
||||
// 标记奖励为已给孩子
|
||||
const markRewardAsGiven = (rewardId: string) => {
|
||||
starEnergyStore.markRewardAsGiven(rewardId);
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
@@ -661,9 +694,41 @@ const closeModal = () => {
|
||||
animation: bounce 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 奖励统计 */
|
||||
.reward-stats {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: linear-gradient(135deg, #98FB98, #90EE90);
|
||||
border-radius: 20px;
|
||||
border: 3px solid #32CD32;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #006400;
|
||||
font-weight: bold;
|
||||
font-family: var(--cartoon-font);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
color: #006400;
|
||||
font-weight: bold;
|
||||
font-family: var(--cartoon-font);
|
||||
}
|
||||
|
||||
.claimed-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
@@ -677,6 +742,53 @@ const closeModal = () => {
|
||||
color: white;
|
||||
box-shadow: 0 4px 10px rgba(255, 215, 0, 0.4);
|
||||
animation: bounce 2s ease-in-out infinite;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.claimed-card.given {
|
||||
background: linear-gradient(135deg, #98FB98, #32CD32);
|
||||
border: 3px solid #228B22;
|
||||
}
|
||||
|
||||
.claimed-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.give-btn {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #8B4513;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-family: var(--cartoon-font);
|
||||
}
|
||||
|
||||
.give-btn:hover {
|
||||
background: white;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.given-badge {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
font-family: var(--cartoon-font);
|
||||
border: 2px solid rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 弹窗 */
|
||||
|
||||
Reference in New Issue
Block a user