huaanglimeng/utils/pointsManager.js

300 lines
8.5 KiB
JavaScript
Raw Normal View History

/**
* 积分管理模块
* 提供积分的初始化查询增减校验等功能
* 使用微信小程序本地存储实现
*/
const STORAGE_KEY_POINTS = 'tarot_points';
const STORAGE_KEY_LAST_LOGIN = 'tarot_last_login';
const STORAGE_KEY_AD_DATE = 'tarot_ad_date';
const STORAGE_KEY_AD_COUNT = 'tarot_ad_count';
const DEFAULT_POINTS = 20; // 新用户默认积分
const DAILY_REWARD = 3; // 每日登录奖励
// 积分来源常量
const POINT_SOURCE = {
DAILY_LOGIN: 'daily_login',
TAROT_USE: 'tarot_use',
KNOWLEDGE_READ: 'knowledge_read',
AD_REWARD: 'ad_reward'
};
// 广告奖励配置
const AD_REWARD_CONFIG = {
REWARD_POINTS: 5, // 每次奖励积分
DAILY_LIMIT: 3 // 每日上限次数
};
/**
* 初始化积分系统
* 如果用户是首次使用设置默认积分
*/
function initPoints() {
try {
const points = wx.getStorageSync(STORAGE_KEY_POINTS);
if (points === '' || points === null || points === undefined) {
wx.setStorageSync(STORAGE_KEY_POINTS, DEFAULT_POINTS);
console.log(`[积分系统] 新用户初始化,赋予 ${DEFAULT_POINTS} 积分`);
return DEFAULT_POINTS;
}
return points;
} catch (error) {
console.error('[积分系统] 初始化失败:', error);
return DEFAULT_POINTS;
}
}
/**
* 获取当前积分
* @returns {number} 当前积分数
*/
function getPoints() {
try {
const points = wx.getStorageSync(STORAGE_KEY_POINTS);
if (points === '' || points === null || points === undefined) {
return initPoints();
}
return points;
} catch (error) {
console.error('[积分系统] 获取积分失败:', error);
return 0;
}
}
/**
* 增加积分
* @param {number} num - 要增加的积分数
* @param {string} source - 积分来源可选
* @returns {number} 增加后的积分数
*/
function addPoints(num, source = '') {
try {
if (typeof num !== 'number' || num <= 0) {
console.warn('[积分系统] 无效的增加数值:', num);
return getPoints();
}
const currentPoints = getPoints();
const newPoints = currentPoints + num;
wx.setStorageSync(STORAGE_KEY_POINTS, newPoints);
// 记录积分来源
if (source) {
console.log(`[积分系统] +${num} 积分,来源: ${source},当前: ${newPoints}`);
} else {
console.log(`[积分系统] 增加 ${num} 积分,当前: ${newPoints}`);
}
return newPoints;
} catch (error) {
console.error('[积分系统] 增加积分失败:', error);
return getPoints();
}
}
/**
* 扣除积分
* @param {number} num - 要扣除的积分数
* @returns {number} 扣除后的积分数如果积分不足则返回当前积分
*/
function deductPoints(num) {
try {
if (typeof num !== 'number' || num <= 0) {
console.warn('[积分系统] 无效的扣除数值:', num);
return getPoints();
}
const currentPoints = getPoints();
if (currentPoints < num) {
console.warn(`[积分系统] 积分不足,当前: ${currentPoints},需要: ${num}`);
return currentPoints;
}
const newPoints = currentPoints - num;
wx.setStorageSync(STORAGE_KEY_POINTS, newPoints);
console.log(`[积分系统] 扣除 ${num} 积分,剩余: ${newPoints}`);
return newPoints;
} catch (error) {
console.error('[积分系统] 扣除积分失败:', error);
return getPoints();
}
}
/**
* 检查积分是否足够
* @param {number} num - 需要的积分数
* @returns {boolean} 是否足够
*/
function hasEnough(num) {
try {
if (typeof num !== 'number' || num < 0) {
console.warn('[积分系统] 无效的检查数值:', num);
return false;
}
const currentPoints = getPoints();
return currentPoints >= num;
} catch (error) {
console.error('[积分系统] 检查积分失败:', error);
return false;
}
}
/**
* 检查并发放每日登录奖励
* @returns {object} { rewarded: boolean, points: number, message: string }
*/
function checkDailyReward() {
try {
const today = new Date().toDateString(); // 格式: "Sun Feb 09 2026"
const lastLogin = wx.getStorageSync(STORAGE_KEY_LAST_LOGIN);
// 如果是新的一天
if (lastLogin !== today) {
// 更新最后登录日期
wx.setStorageSync(STORAGE_KEY_LAST_LOGIN, today);
// 如果不是首次登录(首次登录已经有初始积分了)
if (lastLogin !== '' && lastLogin !== null && lastLogin !== undefined) {
const newPoints = addPoints(DAILY_REWARD, POINT_SOURCE.DAILY_LOGIN);
console.log(`[积分系统] 每日登录奖励 +${DAILY_REWARD} 积分`);
return {
rewarded: true,
points: newPoints,
message: `每日登录奖励 +${DAILY_REWARD} 积分`
};
} else {
// 首次登录,只记录日期,不发放奖励
console.log('[积分系统] 首次登录,已记录日期');
return {
rewarded: false,
points: getPoints(),
message: '欢迎使用塔罗占卜'
};
}
}
// 今天已经登录过了
return {
rewarded: false,
points: getPoints(),
message: '今日已签到'
};
} catch (error) {
console.error('[积分系统] 每日奖励检查失败:', error);
return {
rewarded: false,
points: getPoints(),
message: '签到检查失败'
};
}
}
/**
* 获取今日广告观看次数
* @returns {number} 今日已观看次数
*/
function getTodayAdCount() {
try {
const today = new Date().toDateString();
const lastDate = wx.getStorageSync(STORAGE_KEY_AD_DATE) || '';
// 如果不是今天,返回 0
if (lastDate !== today) {
return 0;
}
return wx.getStorageSync(STORAGE_KEY_AD_COUNT) || 0;
} catch (error) {
console.error('[广告系统] 获取广告次数失败:', error);
return 0;
}
}
/**
* 增加广告观看次数
*/
function incrementAdCount() {
try {
const today = new Date().toDateString();
const count = getTodayAdCount();
wx.setStorageSync(STORAGE_KEY_AD_DATE, today);
wx.setStorageSync(STORAGE_KEY_AD_COUNT, count + 1);
console.log(`[广告系统] 今日广告次数: ${count + 1}/${AD_REWARD_CONFIG.DAILY_LIMIT}`);
} catch (error) {
console.error('[广告系统] 增加广告次数失败:', error);
}
}
/**
* 检查是否可以观看广告
* @returns {boolean} 是否可以观看
*/
function canWatchAd() {
return getTodayAdCount() < AD_REWARD_CONFIG.DAILY_LIMIT;
}
/**
* 广告奖励积分核心方法
* 未来只需修改此函数内部逻辑UI 调用方式不变
* @returns {Object} { success, message, points, remainingCount }
*/
function rewardFromAd() {
try {
// 检查每日次数限制
if (!canWatchAd()) {
return {
success: false,
message: '今日广告次数已用完',
points: 0,
remainingCount: 0
};
}
// 🎬 未来在此处接入真实广告 SDK
// 当前版本:直接模拟成功
// 增加积分
const rewardPoints = AD_REWARD_CONFIG.REWARD_POINTS;
addPoints(rewardPoints, POINT_SOURCE.AD_REWARD);
// 增加广告次数
incrementAdCount();
const remaining = AD_REWARD_CONFIG.DAILY_LIMIT - getTodayAdCount();
return {
success: true,
message: `获得 +${rewardPoints} 积分`,
points: rewardPoints,
remainingCount: remaining
};
} catch (error) {
console.error('[广告奖励] 失败:', error);
return {
success: false,
message: '广告奖励失败',
points: 0,
remainingCount: 0
};
}
}
module.exports = {
initPoints,
getPoints,
addPoints,
deductPoints,
hasEnough,
checkDailyReward,
// 广告奖励相关
getTodayAdCount,
canWatchAd,
rewardFromAd,
// 常量导出
POINT_SOURCE,
AD_REWARD_CONFIG
};