forked from zhouruizhe/gmTouringMiniApp
114 lines
2.8 KiB
JavaScript
114 lines
2.8 KiB
JavaScript
// 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
|
|
};
|