/** Development-only fake service. Its balance never touches the player's wallet. */ export default class CoinMadnessMockApi { private failNext = false; constructor(private store: { read: () => any; write: (value: any) => void; level: () => number }, private now = () => Date.now()) {} request(action: string, body: any = {}): any { if (this.failNext) { this.failNext = false; return { code: 0, msg: '模拟接口失败,请重试' }; } const now = this.now(); let state = this.store.read(); if (!state || action === 'reset') { state = { config: { periodId: 'mock-' + now, title: '金币狂热 · 模拟版', startsAt: now, endsAt: now + 7 * 86400000, priceCents: 99, stages: [{ wins: 2, coins: 150 }, { wins: 3, coins: 200 }, { wins: 5, coins: 250 }, { wins: 10, coins: 300 }, { wins: 15, coins: 400 }] }, paidAt: 0, stage: 0, totalWins: 0, baseline: 0, lastLevel: this.store.level(), settled: false, mockBalance: 1000 }; } if (action === 'fail_next') this.failNext = true; if (action === 'expire') state.config.endsAt = now; const target = state.config.stages[state.stage]; const progress = Math.min(target ? target.wins : 0, state.totalWins - state.baseline); let granted = 0; if (now >= state.config.endsAt && !state.settled) { if (state.paidAt && target && progress >= target.wins) { granted = target.coins; state.stage++; } state.settled = true; } let msg = ''; if (action === 'purchase' || action === 'claim') { if (body.periodId !== state.config.periodId) msg = '活动期次已变更,请刷新'; else if (now < state.config.startsAt || now >= state.config.endsAt) msg = '活动已结束或尚未开始'; else if (action === 'purchase' && !state.paidAt) { state.paidAt = now; state.totalWins = 0; state.baseline = 0; state.lastLevel = this.store.level(); } else if (action === 'claim') { if (!state.paidAt || body.stage !== state.stage || !target || progress < target.wins) msg = '当前奖励不可领取'; else { granted = target.coins; state.stage++; state.baseline = state.totalWins; } } } if (action === 'simulate_win' && state.paidAt && !state.settled && now >= state.config.startsAt) state.totalWins++; state.mockBalance += granted; this.store.write(state); const next = state.config.stages[state.stage]; const data = { available: true, serverNow: now, mockBalance: state.mockBalance, granted, state: { ...state, progress: Math.min(next ? next.wins : 0, state.totalWins - state.baseline) } }; return msg ? { code: 0, msg, data } : { code: 1, data }; } }