// userStore.js // 用户数据管理模块:负责积分、徽章、打卡记录的本地存储与业务逻辑 const STORAGE_KEY = 'USER_DATA'; // 默认的用户数据结构 const defaultUserData = { points: 0, // 用户积分 badges: [], // 用户徽章列表,元素形如 { name, obtainedAt } checkIns: [] // 打卡记录,元素形如 { poiId, poiName, time } }; /** * 获取完整的用户数据 * 如果本地没有数据,返回默认结构 * @returns {{points:number, badges:Array, checkIns:Array}} */ function getUserData() { try { const data = wx.getStorageSync(STORAGE_KEY); if (data && typeof data === 'object') { // 兼容旧数据:补齐可能缺失的字段 return Object.assign({}, defaultUserData, data); } } catch (e) { console.error('[userStore] 读取用户数据失败:', e); } // 深拷贝默认数据,避免外部修改影响默认值 return JSON.parse(JSON.stringify(defaultUserData)); } /** * 保存用户数据到本地 * @param {Object} data */ function saveUserData(data) { try { wx.setStorageSync(STORAGE_KEY, data); } catch (e) { console.error('[userStore] 保存用户数据失败:', e); } } /** * 判断某个景点是否已经打卡过 * @param {string|number} poiId * @returns {boolean} */ function hasCheckedIn(poiId) { const data = getUserData(); return data.checkIns.some(item => item.poiId === poiId); } /** * 判断是否已经拥有某个徽章 * @param {Object} data 用户数据 * @param {string} badgeName * @returns {boolean} */ function hasBadge(data, badgeName) { return data.badges.some(b => b.name === badgeName); } /** * 处理打卡逻辑 * 检查是否已打卡;如未打卡则 +10 积分,添加“探索者”徽章(如没有),保存数据 * @param {string|number} poiId 景点 ID * @param {string} poiName 景点名称 * @returns {{success:boolean, message:string, data?:Object}} */ function checkIn(poiId, poiName) { if (!poiId) { return { success: false, message: '景点 ID 无效' }; } const data = getUserData(); // 已打卡则不再重复奖励 if (data.checkIns.some(item => item.poiId === poiId)) { return { success: false, message: '你已经打卡过该景点', data }; } // 增加打卡记录 data.checkIns.push({ poiId, poiName: poiName || '', time: Date.now() }); // 增加 10 积分 data.points += 10; // 添加“探索者”徽章(若尚未拥有) const BADGE_NAME = '探索者'; if (!hasBadge(data, BADGE_NAME)) { data.badges.push({ name: BADGE_NAME, obtainedAt: Date.now() }); } // 保存到本地 saveUserData(data); return { success: true, message: '打卡成功,积分 +10', data }; } module.exports = { getUserData, saveUserData, hasCheckedIn, checkIn };