Files
child-learning/src/stores/starEnergy.ts
2026-03-02 07:02:25 +08:00

423 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineStore } from 'pinia';
// 获取当前用户
const getCurrentUser = () => {
return localStorage.getItem('currentUser') || 'default';
};
// 从 localStorage 加载数据
const loadFromLocalStorage = () => {
try {
const user = getCurrentUser();
const saved = localStorage.getItem(`starEnergyData_${user}`);
return saved ? JSON.parse(saved) : null;
} catch (error) {
console.error('加载数据失败:', error);
return null;
}
};
// 保存到 localStorage
const saveToLocalStorage = (data: any) => {
try {
const user = getCurrentUser();
localStorage.setItem(`starEnergyData_${user}`, JSON.stringify(data));
} catch (error) {
console.error('保存数据失败:', error);
}
};
// 星星能量存储
export const useStarEnergyStore = defineStore('starEnergy', {
state: () => {
// 尝试从 localStorage 加载保存的数据
const savedData = loadFromLocalStorage();
// 获取当前日期
const today = new Date().toDateString();
// 检查是否需要重置怪兽状态和已兑换奖励
let monsters = savedData?.monsters;
let lastResetDate = savedData?.lastResetDate;
let claimedRewards = savedData?.claimedRewards;
let givenRewards = savedData?.givenRewards;
let bossDefeats = savedData?.bossDefeats;
// 防御性检查
if (!Array.isArray(claimedRewards)) {
claimedRewards = [];
}
if (!Array.isArray(givenRewards)) {
givenRewards = [];
}
if (typeof bossDefeats !== 'number') {
bossDefeats = 0;
}
// 如果是新的一天,重置怪兽状态和已兑换奖励
if (!lastResetDate || lastResetDate !== today) {
monsters = {
boss: {
name: '坏习惯大魔王',
health: 500,
defeated: false,
habits: ['brushTeeth', 'noBedLate', 'noPickyEating', 'washHands', 'homeworkFast', 'earlySleep', 'cleanRoom']
}
};
claimedRewards = []; // 重置已兑换奖励
givenRewards = []; // 重置已给孩子的奖励
lastResetDate = today;
}
return {
// 星星能量总数
total: typeof savedData?.total === 'number' ? savedData.total : 20,
// 各区域的星星能量
areas: savedData?.areas || {
knowledge: 0,
craft: 0,
logic: 0,
habit: 0,
parent: 0
},
// 习惯打卡记录
habits: {
brushTeeth: {
name: '刷牙',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.brushTeeth
},
noBedLate: {
name: '不赖床',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.noBedLate
},
noPickyEating: {
name: '不挑食',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.noPickyEating
},
washHands: {
name: '勤洗手',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.washHands
},
homeworkFast: {
name: '写作业快',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.homeworkFast
},
earlySleep: {
name: '早睡',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.earlySleep
},
cleanRoom: {
name: '打扫卫生',
count: 0,
streak: 0,
lastChecked: null as string | null,
...savedData?.habits?.cleanRoom
}
},
// 怪兽状态
monsters: monsters || {
boss: {
name: '坏习惯大魔王',
health: 500,
defeated: false,
habits: ['brushTeeth', 'noBedLate', 'noPickyEating', 'washHands', 'homeworkFast', 'earlySleep', 'cleanRoom']
}
},
// 勋章
badges: Array.isArray(savedData?.badges) ? savedData.badges : [] as string[],
// 已兑换奖励
claimedRewards: claimedRewards,
// 已给孩子的奖励
givenRewards: givenRewards,
// 击败BOSS次数
bossDefeats: bossDefeats,
// 上次重置日期
lastResetDate: lastResetDate || today
};
},
getters: {
// 获取总星星能量
getTotalEnergy: (state) => state.total,
// 获取各区域能量
getAreaEnergy: (state) => (area: keyof typeof state.areas) => state.areas[area],
// 获取习惯打卡情况
getHabitStatus: (state) => (habit: keyof typeof state.habits) => state.habits[habit],
// 获取怪兽状态
getMonsterStatus: (state) => (monster: keyof typeof state.monsters) => state.monsters[monster],
// 获取所有勋章
getAllBadges: (state) => state.badges,
// 获取已兑换奖励
getClaimedRewards: (state) => state.claimedRewards,
// 获取已给孩子的奖励
getGivenRewards: (state) => state.givenRewards,
// 获取击败BOSS次数
getBossDefeats: (state) => state.bossDefeats
},
actions: {
// 保存状态到 localStorage
$persist() {
const data = {
total: this.total,
areas: this.areas,
habits: this.habits,
monsters: this.monsters,
badges: this.badges,
claimedRewards: this.claimedRewards,
givenRewards: this.givenRewards,
bossDefeats: this.bossDefeats,
lastResetDate: this.lastResetDate
};
saveToLocalStorage(data);
},
// 增加星星能量
addEnergy(amount: number, area: keyof typeof this.areas) {
this.total += amount;
this.areas[area] += amount;
this.$persist();
},
// 减少星星能量
removeEnergy(amount: number) {
if (this.total >= amount) {
this.total -= amount;
this.$persist();
return true;
}
return false;
},
// 打卡习惯
checkHabit(habit: keyof typeof this.habits) {
const today = new Date().toISOString().split('T')[0];
const habitData = this.habits[habit];
// 检查习惯数据是否存在
if (!habitData) {
return;
}
// 防止重复打卡
if (habitData.lastChecked === today) {
return;
}
// 保存原来的lastChecked值用于连续打卡计算
const originalLastChecked = habitData.lastChecked;
// 更新打卡记录
habitData.count++;
habitData.lastChecked = today;
// 更新连续打卡天数
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const yesterdayStr = yesterday.toISOString().split('T')[0];
if (originalLastChecked === yesterdayStr) {
habitData.streak++;
} else {
habitData.streak = 1;
}
// 奖励星星能量
this.addEnergy(10, 'habit');
// 连续3天打卡额外奖励
if (habitData.streak % 3 === 0) {
this.addEnergy(5, 'habit');
}
// 保存数据
this.$persist();
},
// 攻击怪兽
attackMonster(monster: keyof typeof this.monsters, energy: number) {
const monsterData = this.monsters[monster];
if (monsterData.defeated) return;
// 每次攻击消耗10颗星星固定掉10滴血
if (this.total >= 10) {
monsterData.health = Math.max(0, monsterData.health - 10);
// 扣除星星能量
this.total -= 10;
// 检查是否击败
if (monsterData.health === 0) {
monsterData.defeated = true;
// 奖励星星能量
this.addEnergy(200, 'habit');
// 增加击败BOSS次数
this.bossDefeats++;
// 解锁勋章
const badge = '习惯守护者';
if (!this.badges.includes(badge)) {
this.badges.push(badge);
}
}
this.$persist();
}
},
// 亲子合力攻击
parentAttack(monster: keyof typeof this.monsters) {
const monsterData = this.monsters[monster];
if (monsterData.defeated) return;
// 亲子攻击固定掉10滴血
monsterData.health = Math.max(0, monsterData.health - 10);
// 检查是否击败
if (monsterData.health === 0) {
monsterData.defeated = true;
// 奖励星星能量
this.addEnergy(200, 'habit');
// 增加击败BOSS次数
this.bossDefeats++;
// 解锁勋章
const badge = '习惯守护者';
if (!this.badges.includes(badge)) {
this.badges.push(badge);
}
}
this.$persist();
},
// 兑换奖励
redeemReward(rewardId: string, cost: number) {
if (this.total < cost) {
return false;
}
this.total -= cost;
if (!this.claimedRewards.includes(rewardId)) {
this.claimedRewards.push(rewardId);
}
this.$persist();
return true;
},
// 标记奖励为已给孩子
markRewardAsGiven(rewardId: string) {
if (!this.givenRewards.includes(rewardId)) {
this.givenRewards.push(rewardId);
this.$persist();
return true;
}
return false;
},
// 取消标记奖励为已给孩子
unmarkRewardAsGiven(rewardId: string) {
const index = this.givenRewards.indexOf(rewardId);
if (index > -1) {
this.givenRewards.splice(index, 1);
this.$persist();
return true;
}
return false;
},
// 重置所有数据(清除游戏进度)
resetAll() {
this.total = 0;
this.areas = {
knowledge: 0,
craft: 0,
logic: 0,
habit: 0,
parent: 0
};
this.habits = {
brushTeeth: {
name: '刷牙',
count: 0,
streak: 0,
lastChecked: null
},
noBedLate: {
name: '不赖床',
count: 0,
streak: 0,
lastChecked: null
},
noPickyEating: {
name: '不挑食',
count: 0,
streak: 0,
lastChecked: null
},
washHands: {
name: '勤洗手',
count: 0,
streak: 0,
lastChecked: null
},
homeworkFast: {
name: '写作业快',
count: 0,
streak: 0,
lastChecked: null
},
earlySleep: {
name: '早睡',
count: 0,
streak: 0,
lastChecked: null
},
cleanRoom: {
name: '打扫卫生',
count: 0,
streak: 0,
lastChecked: null
}
};
this.monsters = {
boss: {
name: '坏习惯大魔王',
health: 500,
defeated: false,
habits: ['brushTeeth', 'noBedLate', 'noPickyEating', 'washHands', 'homeworkFast', 'earlySleep', 'cleanRoom']
}
};
this.badges = [];
this.claimedRewards = [];
this.givenRewards = [];
this.bossDefeats = 0;
const user = getCurrentUser();
localStorage.removeItem(`starEnergyData_${user}`);
}
}
});