const { ccclass } = cc._decorator; /** 首页真实流程诊断;可清理测试账号的本地资格和领取缓存。 */ @ccclass export default class BenefitsRuntimeTest extends cc.Component { private bridge: any; private panel: cc.Node; private output: cc.Label; private unsubscribe: () => void; private entry: cc.Node; private rank: cc.Node; private message = "选择入口资格后打开福利,手动测试领取。"; initialize(bridge: any): void { this.bridge = bridge; } onLoad(): void { if (!this.bridge || !this.bridge.getTestEnvironment().allowed) { this.node.destroy(); return; } const size = this.node.parent.getContentSize(); this.node.scale = Math.min(1, size.width / 1080, size.height / 1920); this.entry = this.node.getChildByName("entry"); this.entry.setContentSize(200, 88); this.rank = cc.find("Load/Top/rank", this.node.parent); this.lateUpdate(); this.panel = this.node.getChildByName("panel"); const background = this.panel.addComponent(cc.Graphics); background.fillColor = cc.color(25, 30, 42, 245); background.roundRect(-500, -700, 1000, 1400, 18); background.fill(); this.output = this.panel.getChildByName("viewport").getChildByName("content").getComponent(cc.Label); this.bind(this.node.getChildByName("entry"), () => { this.panel.active = true; this.render(); }); this.bind(this.panel.getChildByName("close"), () => this.panel.active = false); this.bind(this.panel.getChildByName("query"), () => { if (!this.bridge.getUid()) throw new Error("请等待登录完成"); if (Number(this.bridge.getTestSnapshot().level) < 1) throw new Error("请先通过第 1 关"); this.panel.active = false; this.bridge.open(); }); this.bind(this.panel.getChildByName("clearClaim"), () => this.setEligibility("favorite_entry")); this.bind(this.panel.getChildByName("clearAuto"), () => this.setEligibility("desktop_entry")); this.bind(this.panel.getChildByName("recheck"), () => this.setEligibility()); this.bind(this.panel.getChildByName("clearLocalClaims"), () => { this.bridge.clearTestClaimCache(); this.message = "已清本地领取缓存,道具数量不变。重新领奖需后台重置领取标记后重新登录。"; this.render(); }); this.unsubscribe = this.bridge.subscribe(() => { if (this.panel.active) this.render(); }); } lateUpdate(): void { if (!this.entry || !this.rank || !cc.isValid(this.rank, true)) return; // Follow the actual ranking button after Widgets/layout have moved the home bar. const left = this.rank.convertToWorldSpaceAR(cc.v2(-this.rank.width * this.rank.anchorX, 0)); const position = this.node.convertToNodeSpaceAR(left); this.entry.setPosition(position.x - this.entry.width / 2 - 24, position.y); } private bind(node: cc.Node, action: () => void): void { node.on(cc.Node.EventType.TOUCH_END, (event: cc.Event) => { event.stopPropagation(); if (!this.bridge.getTestEnvironment().allowed) { this.node.active = false; return; } try { action(); } catch (error) { this.message = error && error.message || "操作失败"; this.render(); } }, this); } private setEligibility(task?: string): void { this.bridge.setTestEligibility(task); this.message = task ? "已模拟本地入口资格;点击“打开福利”手动领取。" : "已清除当前账号的两项本地入口资格。"; this.render(); } private render(): void { const s = this.bridge.getTestSnapshot(); const describe = (id: string) => { const item = s.state[id] || {}; return item.claimedAt ? (item.deliveryPending ? "已确认 / 道具同步待重试" : "已领取") : item.eligibleAt ? "可领取(仍需通过首关)" : "未获得入口资格"; }; this.output.string = [this.message, "环境:" + s.environment.version + "\n地址:" + s.environment.baseUrl, "UID:" + (s.uid || "未登录") + "\n关卡:" + s.level, "我的小程序(1104):" + describe("favorite_entry"), "桌面入口(1023):" + describe("desktop_entry"), "首页入口:" + (s.entryVisible ? "显示" : "隐藏") + " / 红点:" + (s.redDot ? "亮" : "灭"), "福利弹窗:" + (s.panelBusy ? "打开或加载/释放中" : "已关闭"), "登录返回 miniProgramWelfare:\n" + JSON.stringify(s.loginWelfare || null, null, 2), "本地资格:\n" + JSON.stringify(s.eligibility, null, 2), "当前领取状态:\n" + JSON.stringify(s.state, null, 2), "最近入口记录(模拟按钮不伪造微信记录):\n" + JSON.stringify(s.diagnostics, null, 2), "领取会调用测试服 miniProgramWelfare 和 userProp,影响测试账号道具。\n清资格不会重置服务端已领取状态;重复测试领奖请换测试账号或由后端重置。\n此处展示当前登录快照,不额外请求领奖接口。" ].join("\n\n"); this.scheduleOnce(() => { if (cc.isValid(this.node, true)) this.panel.getChildByName("viewport").getComponent(cc.ScrollView).scrollToTop(0); }, 0); } onDestroy(): void { if (this.unsubscribe) this.unsubscribe(); } }