import SevenDayGiftApi, { SevenDayActivityInfo, SevenDayRewardItem } from "./SevenDayGiftApi"; import SevenDayGiftReward from "./SevenDayGiftReward"; const AUTO_OPEN_KEY = "seven_day_gift_auto_open_v1"; type ClaimHandler = (callback: (success: boolean) => void) => void; export interface SevenDayGiftRuntimeView { catArt: cc.SpriteFrame; setData(info: SevenDayActivityInfo, claimHandler: ClaimHandler): void; setCloseHandler(closeHandler: () => void): void; show(autoClaim?: boolean): void; } /** Bundle 内的正式业务逻辑,只处理活动领取、发奖和状态刷新。 */ export default class SevenDayGiftRuntime { private info: SevenDayActivityInfo = null; private querying = false; private loadingSequence = 0; private loadingTimer: any = null; private loadingVisible = false; private disposed = false; constructor(private view: SevenDayGiftRuntimeView) { } public initialize(info: SevenDayActivityInfo, closeHandler: () => void) { if (this.disposed) return; this.view.setCloseHandler(closeHandler); if (info) this.updateInfo(info); } public updateInfo(info: SevenDayActivityInfo) { if (this.disposed || !info) return; this.info = info; this.view.setData(this.info, this.claimReward.bind(this)); } public show(autoClaim: boolean = false) { if (!this.info || this.disposed) return; this.view.setData(this.info, this.claimReward.bind(this)); this.view.show(autoClaim); } public destroy() { if (this.disposed) return; this.disposed = true; this.closeHomeLoading(this.loadingSequence); this.querying = false; this.info = null; this.view = null; } private claimReward(callback: (success: boolean) => void) { const loadingToken = this.openHomeLoading(7000); SevenDayGiftApi.claim(response => { if (this.disposed) return; if (!response || response.code !== 1 || !response.data) { this.closeHomeLoading(loadingToken); this.clearAutoOpened(); cc.warn("[SevenDayGift] 领取失败", response && response.msg); callback(false); return; } SevenDayGiftReward.grant(response.data, (success: boolean, message?: string) => { if (this.disposed) return; if (!success) { this.closeHomeLoading(loadingToken); this.clearAutoOpened(); cc.warn("[SevenDayGift] 奖励同步失败", message); callback(false); return; } this.applyClaimState(response.data.rewardDay, response.data.claimedCount, response.data.completed); this.closeHomeLoading(loadingToken); this.showRewardWindow(response.data.rewards); this.queryActivity(() => callback(true)); }); }); } private queryActivity(callback?: (success: boolean) => void) { if (this.querying) { if (callback) callback(false); return; } if (!SevenDayGiftApi.getUid()) { if (callback) callback(false); return; } this.querying = true; SevenDayGiftApi.getInfo(response => { if (this.disposed) return; this.querying = false; if (!response || response.code !== 1 || !response.data) { if (callback) callback(false); return; } this.updateInfo(response.data); if (callback) callback(true); }); } private applyClaimState(rewardDay: number, claimedCount: number, completed: boolean) { if (!this.info) return; this.info.claimedCount = Number(claimedCount) || this.info.claimedCount; this.info.todayClaimed = true; this.info.canClaim = false; if (completed) this.info.status = "completed"; if (Array.isArray(this.info.rewards)) { this.info.rewards.forEach(reward => { if (Number(reward.day) === Number(rewardDay)) reward.claimed = true; }); } this.view.setData(this.info, this.claimReward.bind(this)); } private showRewardWindow(rewards: SevenDayRewardItem[]) { if (!Array.isArray(rewards) || rewards.length === 0) return; const displayRewards = rewards.map(item => { const rewardCount = item.count !== undefined ? item.count : item.amount; return { type: item.type === "magic_wand" ? "magic" : item.type, count: Math.max(0, Number(rewardCount) || 0), spriteFrame: item.type === "cat_skin" ? this.view.catArt : null, }; }).filter(item => item.count > 0); if (displayRewards.length === 0) return; const home = this.getHomeController(); if (!home || typeof home.openRewardWindow !== "function") { cc.warn("[SevenDayGift] 公共奖励弹窗不可用"); return; } home.openRewardWindow(displayRewards); } private openHomeLoading(timeoutMs: number): number { const token = ++this.loadingSequence; if (this.loadingTimer !== null) clearTimeout(this.loadingTimer); const home = this.getHomeController(); if (home && typeof home.openLoad === "function") { this.loadingVisible = true; home.openLoad(); } this.loadingTimer = setTimeout(() => this.closeHomeLoading(token), timeoutMs); return token; } private closeHomeLoading(token: number) { if (token !== this.loadingSequence) return; if (this.loadingTimer !== null) { clearTimeout(this.loadingTimer); this.loadingTimer = null; } if (!this.loadingVisible) return; this.loadingVisible = false; const home = this.getHomeController(); if (home && typeof home.closeLoad === "function") home.closeLoad(); } private getHomeController(): any { const canvas = cc.find("Canvas"); return canvas && canvas.getComponent("JiaZai"); } private clearAutoOpened() { if (!this.info || !this.info.activityId) return; const key = AUTO_OPEN_KEY + ":" + SevenDayGiftApi.getUid() + ":" + this.info.activityId; cc.fx.StorageMessage.removeStorage(key); } }