import cloud from '@lafjs/cloud' import Utils from "@/Utils"; import signInClaim from "@/signInClaim"; import { activateSignInActivity, getActiveSignInConfig, getChinaDateKey, getSignInActivityStatus, getSignInClaims, getSignInConfig, getUserSignInLevel, normalizeSignInState, } from "@/SignInActivity"; const db = cloud.database(); export default async function (ctx: FunctionContext) { const uid = ctx.body?.uid; if (!uid) { return { code: 0, data: null, msg: "未获取到uid" }; } if (ctx.body?.gameName === "iaa") { return { code: 0, data: null, msg: "七日签到仅支持主游戏" }; } const userResult = await db.collection("users").where({ _id: uid }).getOne(); const user = userResult.data; if (!user) { return { code: 0, data: null, msg: "未获取到用户信息" }; } if (user.token && !Utils.checkToken(ctx.body?.token, user.token)) { return { code: 0, data: null, msg: "token校验失败" }; } let now = Date.now(); let state = normalizeSignInState(user.signInActivity); let config = state ? await getSignInConfig(state.activityId) : await getActiveSignInConfig(); if (!config) { return { code: 0, data: null, msg: "签到活动配置不存在或配置无效" }; } const triggerReached = getUserSignInLevel(user) >= Number(config.triggerLevel); if (!state && !triggerReached) { return { code: 1, data: false, msg: "未达到签到活动开启关卡" }; } if (!state) { const activation = await activateSignInActivity(user, now); state = activation.state; config = activation.config || config; if (!state) { return { code: 0, data: null, msg: "签到活动开启失败" }; } } let claims = await getSignInClaims(uid, state.activityId); const canAutoClaim = getSignInActivityStatus(state, claims.length, now) === "active" && !claims.some(claim => String(claim.dateKey) === getChinaDateKey(now)); if (canAutoClaim) { // 等待领取落库后再返回;不在云函数响应结束后启动无人等待的后台任务。 const result = await signInClaim(ctx); now = Date.now(); claims = await getSignInClaims(uid, state.activityId); // 并发请求可能已领取成功,以数据库记录为准;其他失败不伪装成成功。 if (result.code !== 1 && !claims.some(claim => String(claim.dateKey) === getChinaDateKey(now)) && getSignInActivityStatus(state, claims.length, now) === "active") { return result; } } const todayClaim = claims.find(claim => String(claim.dateKey) === getChinaDateKey(now)); const claimedDays = new Set(claims.map(claim => Number(claim.rewardDay))); const todayClaimed = claims.some(claim => String(claim.dateKey) === getChinaDateKey(now)); const claimedCount = claims.length; const status = getSignInActivityStatus(state, claimedCount, now); return { code: 1, data: { serverNow: now, activityId: config.activityId, status, triggerLevel: Number(config.triggerLevel), triggerReached, startAt: state.startAt, endAt: state.endAt, claimedCount, todayClaimed, todayClaim: todayClaim ? { claimId: todayClaim.claimId, rewardDay: Number(todayClaim.rewardDay), rewards: todayClaim.rewards, } : null, canClaim: status === "active" && !todayClaimed, nextRewardDay: status === "active" && !todayClaimed ? claimedCount + 1 : null, rewards: config.rewards.map(reward => ({ day: Number(reward.day), items: reward.items, claimed: claimedDays.has(Number(reward.day)), })), }, msg: "成功", }; }