import JiaZai from "../../Script/JiaZai"; import Utils from "../../Script/module/Pay/Utils"; import NumberToImage from "../../Script/NumberToImage"; import { MiniGameSdk } from "../../Script/Sdk/MiniGameSdk"; const { ccclass, property } = cc._decorator; @ccclass export default class passCheck extends cc.Component { @property(cc.Button) descriptionBtn: cc.Button = null; @property(cc.Button) closetBtn: cc.Button = null; @property(cc.Button) activateBtn: cc.Button = null; @property(cc.Sprite) barSpr: cc.Sprite = null; @property(cc.Node) currentLv: cc.Node = null; @property(cc.Node) progress_1: cc.Node = null; @property(cc.Node) progress_2: cc.Node = null; @property(cc.Node) descriptionNode: cc.Node = null; @property(cc.Label) time: cc.Label = null; // @property(cc.Prefab) // passCheckItemLv: cc.Prefab = null; @property(cc.Prefab) buyActivate: cc.Prefab = null; @property(cc.Button) btnActivate1: cc.Button = null; private timeNumber: number = 0; private progressNum1: number = 0; private progressNum2: number = 0; private currentLvNum: number = 0; private ProgressIndex: number = 0; // 记录当前进度索引 private countdownTimer: any = null; private endTime: number = 0; // 结束时间戳(毫秒) private passListData: Array = []; // 存储处理后的passList数据 private btn_Touch: boolean = false; private iosPrice: number = 0; private iosProductId: string = ""; private iosCount: number = 1; private onShowListener: () => void; public passCheckMgr: any = null; public oldPassCheckInfo: any = null; protected onLoad(): void { } start() { // 添加按钮事件监听 this.descriptionBtn.node.on('click', this.onDescriptionBtnClick, this); this.closetBtn.node.on('click', this.onCloseBtnClick, this); this.activateBtn.node.on('click', this.onActivateBtnClick, this); // this.initPassList(); this.onShowListener = null; if (cc.sys.platform === cc.sys.WECHAT_GAME) { // 定义监听函数 console.log("通行证添加监听"); this.onShowListener = () => { console.log("回到前台,通行证添加监听"); this.onShow(); }; //@ts-ignore wx.onShow(this.onShowListener); } this.btn_Touch = true; } setInfo(passCheck) { this.onInit(passCheck); } onInit(passCheckInfo) { const passCheckData = cc.fx.GameConfig.PASS_CHECK; // let _playerPassLevel = cc.fx.GameConfig.GM_INFO.playerPassLevel // let getUserLevel = cc.fx.GameConfig.GM_INFO.level; let passCheck = null; if (cc.fx.GameConfig.GM_INFO.getItemType == 2) { this.oldPassCheckInfo = passCheckInfo[1]; passCheck = passCheckInfo[2]; this.activateBtn.node.active = !passCheck.activate; } else { this.oldPassCheckInfo = passCheckInfo[2]; passCheck = passCheckInfo[1]; this.activateBtn.node.active = false; } this.ProgressIndex = cc.fx.StorageMessage.getStorage("ProgressIndex") || 1; // 设置固定开始时间:2025年11月4日10:00 // const startDate = new Date(2025, 10, 4, 10, 0, 0); // 月份从0开始,所以11月是10 // const startTime = startDate.getTime(); // const now = new Date().getTime(); // // 计算结束时间(开始时间 + 60天) // this.endTime = passCheck.time + (30 * 24 * 60 * 60 * 1000); // 开始时间 + 60天的毫秒数 this.endTime = passCheck.time; if (typeof passCheck === 'string') { try { passCheck = JSON.parse(passCheck); console.log("解析后的 passCheck:", passCheck); console.log("解析后的 progressLevel:", passCheck.activate); } catch (e) { console.error("JSON 解析失败:", e); } } this.timeNumber = 0; this.progressNum1 = passCheck.progress; if (passCheck.progressLevel > 30) { passCheck.progressLevel = 30; this.progressNum1 = passCheckData[passCheck.progressLevel - 1].token; } this.progressNum2 = passCheckData[passCheck.progressLevel - 1].token; let lvNum = passCheck.progressLevel; if (this.progressNum1 == this.progressNum2) { lvNum += 1; this.currentLvNum = passCheck.progressLevel; } else { this.currentLvNum = passCheck.progressLevel - 1; } if (this.currentLvNum <= 0) { this.currentLvNum = 1; } else if (this.currentLvNum > 30) { this.currentLvNum = 30; } if (lvNum >= 30) { lvNum = 30; } NumberToImage.numberToImageNodes(lvNum, 35, 20, "month_", this.currentLv, true); if (lvNum == 1 || (lvNum >= 10 && lvNum <= 19)) { this.currentLv.x -= 5; } NumberToImage.numberToImageNodes(this.progressNum1, 20, 15, "mul", this.progress_1, true); NumberToImage.numberToImageNodes(this.progressNum2, 20, 15, "mul", this.progress_2, true); cc.fx.GameConfig.GM_INFO.passCheckActivate = passCheck.activate; // this.barSpr.fillRange = this.progressNum1 / this.progressNum2; let barSprFillRange = this.progressNum1 / this.progressNum2; this.barSpr.node.active = true; let forInt = passCheck.progressLevel - this.ProgressIndex; // if (forInt < 1) { // forInt = 1; // } if (cc.fx.GameConfig.GM_INFO.getItemType == 1) { forInt = 0; // 当前是第二期领第一期物品 } // let time = 0.3; let fillRangeFun = (fillRange, time, reset?: boolean) => { cc.tween(this.barSpr) .delay(time) .to(time, { fillRange: fillRange }) .call(() => { if (reset) { this.barSpr.fillRange = 0; if (this.progressNum1 == this.progressNum2) { if (this.currentLvNum >= 30) { NumberToImage.numberToImageNodes(4, 20, 15, "mul", this.progress_1, true); } else { NumberToImage.numberToImageNodes(0, 20, 15, "mul", this.progress_1, true); } let lvNumber = passCheck.progressLevel; if (passCheck.progressLevel >= 30) { lvNumber = 29; } NumberToImage.numberToImageNodes(passCheckData[lvNumber].token, 20, 15, "mul", this.progress_2, true); } // NumberToImage.numberToImageNodes(0, 20, 15, "mul", this.progress_1, true); // NumberToImage.numberToImageNodes(0, 20, 15, "mul", this.progress_2, true); // 可能还需要更新其他相关数据 // self.currentLvNum += 1; // NumberToImage.numberToImageNodes(self.currentLvNum, 35, 20, "month_", self.currentLv, true); } }) .start(); } // 确保动画按顺序执行 for (let j = 0; j < forInt; j++) { cc.tween(this.barSpr).delay(j * 0.6 + 0.3).call(() => { if (j == forInt - 1) { // 最后一个动画,根据当前 fillRange 值决定 if (barSprFillRange == 1) { // 延迟执行最后一个动画,确保前面的动画完成 fillRangeFun(1, 0.3, true); } else { fillRangeFun(barSprFillRange, 0.3); } } else { // 中间的动画,都填满到1 fillRangeFun(1, 0.3, true); } }).start(); } if (forInt == 0) { fillRangeFun(1, 0, true); } this.setbarNodePosX() this.initCountDown(); this.passListData = []; // 遍历数据并按照指定格式填充passList for (let i = 0; i < passCheckData.length; i++) { const item = passCheckData[i]; const level = item.level; // 解析free字段 "2002:1" 格式 const freeParts = item.free.split(":"); const freeItemID = parseInt(freeParts[0]); const freeItemNum = parseInt(freeParts[1]); // 解析paid字段 "1001:500" 格式 const paidParts = item.paid.split(":"); const paidItemID = parseInt(paidParts[0]); const paidItemNum = parseInt(paidParts[1]); const freeValue = passCheck.free.length > i ? passCheck.free[i] : -1; // const passCheckValue = passCheck.activate ? (passCheck.passCheck.length > i ? passCheck.passCheck[i] : -1) : -2; const passCheckValue = passCheck.passCheck.length > i ? passCheck.passCheck[i] : -1 this.passListData.push({ id: i, ItemID1: freeItemID, ItemNum1: freeItemNum, ItemID2: paidItemID, ItemNum2: paidItemNum, free: freeValue, passCheck: passCheckValue }); } this.onShowList(this.passListData); } onShowList(data: any) { this.node.getChildByName("scrollViewNode").active = true; var passCheckMgr = this.node.getChildByName("scrollViewNode").getComponent("passCheckMgr"); passCheckMgr.init(data, this.currentLvNum, this.oldPassCheckInfo, this.endTime); this.passCheckMgr = passCheckMgr; // passCheckMgr.updateProgressBars(); } // 根据passList生成对应条数的Item initPassListItems() { } initCountDown() { this.time.node.active = true; // 立即更新一次显示 this.updateCountdown(); // 每分钟更新一次倒计时 this.countdownTimer = setInterval(() => { this.updateCountdown(); }, 60000); // 每60秒更新一次 } updateCountdown() { const now = new Date().getTime(); const distance = this.endTime - now; if (distance <= 0) { // 倒计时结束 if (this.countdownTimer) { clearInterval(this.countdownTimer); this.countdownTimer = null; } let barNode = this.node.getChildByName("centralNode").getChildByName("barNode") barNode.x = 0; this.activateBtn.node.active = false; this.time.string = "已结束"; return; } // 计算天、小时、分钟 const days = Math.floor(distance / (1000 * 60 * 60 * 24)); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); // 格式化显示 const formattedHours = hours.toString().padStart(2, '0'); const formattedMinutes = minutes.toString().padStart(2, '0'); if (days > 0) { // 大于1天时,显示 xx天xx时 this.time.string = `${days}天${formattedHours}时`; } else { // 小于1天时,显示 xx时xx分 this.time.string = `${formattedHours}时${formattedMinutes}分`; } } /** * descriptionBtn事件,显示descriptionNode节点 */ onDescriptionBtnClick() { if (this.descriptionNode) { this.descriptionNode.active = true; } for (let i = 1; i <= 8; i++) { let description = this.descriptionNode.getChildByName("description_" + i); if (description) { // 先隐藏节点 description.scale = 0; description.active = true; // 创建弹出动作序列 cc.tween(description) .delay(i * 0.3) // 依次延迟 .to(0.3, { scale: 1 }, { easing: 'backOut' }) // 弹出效果 .start(); } } // 移除之前的事件监听 this.descriptionNode.getChildByName("solidColorBg").off(cc.Node.EventType.TOUCH_START); // 添加新的事件监听 this.descriptionNode.getChildByName("solidColorBg").on(cc.Node.EventType.TOUCH_START, (event) => { // 阻止事件冒泡 for (let i = 1; i <= 8; i++) { let description = this.descriptionNode.getChildByName("description_" + i); if (description) { // 停止节点上的所有动作 cc.Tween.stopAllByTarget(description); } } this.descriptionNode.active = false; }, this); } /** * closetBtn事件,关闭当前页面 */ onCloseBtnClick() { try { // 先移除事件监听器 if (cc.sys.platform === cc.sys.WECHAT_GAME && this.onShowListener) { console.log("shop移除onshow"); //@ts-ignore wx.offShow(this.onShowListener); this.onShowListener = null; } const now = new Date().getTime(); const distance = this.endTime - now; if (cc.fx.GameConfig.GM_INFO.getItemType == 1 || distance <= 0) { const jiazaiNode = cc.find("Canvas"); // 假设 JiaZai 挂在 Canvas 节点 const jiazaiComp = jiazaiNode.getComponent(JiaZai); if (jiazaiComp) { jiazaiComp.closePassCheck(); } } Utils.outTradeNo = null; // 清理定时器 if (this.countdownTimer) { clearInterval(this.countdownTimer); this.countdownTimer = null; } // 执行完整的销毁逻辑 this.destroyPassCheck(); } catch (error) { console.error("关闭通行证界面时发生错误:", error); // 即使出错也要确保清理引用 this.cleanupAndDestroy(); } } private destroyPassCheck() { try { // 先隐藏节点 if (this.node && cc.isValid(this.node)) { this.node.active = false; } // 清理 passCheckMgr 引用 this.passCheckMgr = null; // 延迟销毁节点,给所有清理操作足够的时间 setTimeout(() => { this.cleanupAndDestroy(); }, 100); } catch (error) { console.error("销毁通行证时出错:", error); this.cleanupAndDestroy(); } } private cleanupAndDestroy() { try { if (this.node && cc.isValid(this.node)) { try { // 在销毁前确保 scrollViewNode 被移除 const scrollViewNode = this.node.getChildByName("scrollViewNode"); if (scrollViewNode && cc.isValid(scrollViewNode)) { scrollViewNode.removeFromParent(true); } // 然后销毁主节点 this.node.destroy(); } catch (e) { console.warn("销毁 passCheckNode 时出错:", e); // 如果销毁失败,至少从父节点中移除 try { if (this.node && cc.isValid(this.node)) { this.node.removeFromParent(); } } catch (e2) { console.warn("从父节点移除 passCheckNode 时出错:", e2); } } } } catch (error) { console.error("清理和销毁通行证时出错:", error); } } onShow() { if (cc.sys.platform === cc.sys.WECHAT_GAME) { console.log("从后台进入前台订单号:", cc.fx.GameConfig.GM_INFO.iosPassCheckOrder); if (cc.fx.GameConfig.GM_INFO.iosPassCheckOrder != null && cc.fx.GameConfig.GM_INFO.iosPassCheckOrder != "") { console.log("有苹果订单号,开始轮训"); const iosPassCheckOrder = cc.fx.GameConfig.GM_INFO.iosPassCheckOrder; this.openLoad(); this.btn_Touch = true; Utils.getIosPayInfo(iosPassCheckOrder, (data) => { console.log("获得轮训结果:", data); const iosID = data.data?.payment_name || this.iosProductId; let iosAmount = data.data?.goodsPrice || this.iosPrice; iosAmount = parseInt(iosAmount); if (data.code == 1) { console.log("购买成功"); let name = "购买金币道具:" + iosID; console.log("引力付费透传", iosAmount, iosPassCheckOrder, name); MiniGameSdk.API.yinli_Pay(iosAmount, iosPassCheckOrder, name) this.closeLoad(); // this.btn_Touch = true; console.log("_________正式发货"); MiniGameSdk.API.showToast("充值成功"); // cc.fx.GameTool.shopBuy(iosID, false); this.updatePassCheckActivateStatus(); // 刷新界面 解锁高级通行证 隐藏通行证按钮 进度条挪到中部 cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = null; } else if (data.code == 0) { console.log("用户自己取消充值"); MiniGameSdk.API.showToast("充值失败"); this.closeLoad(); this.btn_Touch = true; const dataFail = { outTradeNo: iosPassCheckOrder, pay_amount: iosAmount, payment_name: iosID, payment_num: this.iosCount, type: "ios", fail_reason: "用户取消充值", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail); cc.fx.GameConfig.GM_INFO.iosPassCheckOrder = null; } else if (data.code == 2) { this.closeLoad(); this.btn_Touch = true; console.log("轮训超时"); MiniGameSdk.API.showToast("请检查网络,如充值成功,请重新登录领取", 4); const dataFail = { outTradeNo: iosPassCheckOrder, pay_amount: iosAmount, payment_name: iosID, payment_num: this.iosCount, type: "ios", fail_reason: "用户充值后,轮训结果超时", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail); this.openConfirmBox(); } // this.btn_Touch = true; }) } } } /** * activateBtn事件,预留支付方法 */ onBuyActivate() { // TODO: 待调用支付接口 // console.log("激活按钮点击,准备调用支付功能"); console.log("激活按钮点击,准备调用支付功能"); if (!this.btn_Touch) { return; } this.btn_Touch = false; const productId = "battlepass"; let id = "battlepass"; let price = 1800; let count = 1; // id = productId; // switch (productId) { // case "starter_pack": // price = 300; // break; // } console.log("获得商品id:", id, count, price); let systemType = "Android"; try { //@ts-ignore const systemInfo = wx.getSystemInfoSync(); if (systemInfo.platform === 'ios') { systemType = "ios"; } } catch (e) { console.error('获取系统信息失败', e); } if (systemType == "ios") { // MiniGameSdk.API.showToast("IOS系统暂不支持支付"); // this.btn_Touch = true; this.openLoad(); this.btn_Touch = true; let iosPayInfo = { price: price, payment_name: productId, payment_count: 1, } this.iosPrice = price; this.iosProductId = productId; this.iosCount = 1; console.log("准备跳客服回话:"); console.log(this.iosProductId); Utils.GoKEFu(iosPayInfo, (res) => { if (res == "success") { console.log("客服回话成功"); } else { console.log("客服回话失败"); this.closeLoad(); } }); } else { this.openLoad(); this.btn_Touch = true; Utils.buyProp(id, count, price, systemType, productId, (res) => { if (res == null) { MiniGameSdk.API.showToast("充值失败"); this.btn_Touch = true; const dataFail = { outTradeNo: Utils.outTradeNo, pay_amount: price, payment_name: productId, payment_num: 1, type: systemType, fail_reason: "网络异常,没有拉起支付", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail); this.closeLoad(); return; } else if (res.err) { MiniGameSdk.API.showToast("充值失败"); //console.log(res); this.btn_Touch = true; let name = "支付拉起失败"; if (res.errCode == -2) { name = "用户取消充值"; } const dataFail = { outTradeNo: Utils.outTradeNo, pay_amount: price, payment_name: productId, payment_num: 1, type: systemType, fail_reason: name, } cc.fx.GameTool.shushu_Track("payment_fail", dataFail); this.closeLoad(); return; } else { Utils.getPayInfo((data) => { // MiniGameSdk.API.showToast("充值成功"); console.log("7.28_______________充值成功,准备轮训", data); //console.log("获得轮训结果:", data); this.closeLoad(); if (data.data.pay_state == 1) { this.btn_Touch = true; MiniGameSdk.API.showToast("取消充值"); const dataFail2 = { outTradeNo: Utils.outTradeNo, pay_amount: price, payment_name: productId, payment_num: 1, type: systemType, fail_reason: "用户取消支付", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail2); } else if (data.data.pay_state == 2) { this.btn_Touch = true; let name = "购买金币道具:" + productId; MiniGameSdk.API.yinli_Pay(price, Utils.outTradeNo, name); console.log("充值成功,轮训成功,准备发货"); Utils.setPayInfo( (res) => { console.log("设置轮训结果:", res); if (res.code === 1) { console.log("正式发货", Utils.outTradeNo); MiniGameSdk.API.showToast("充值成功"); // cc.fx.GameTool.shopBuy(productId, false); this.updatePassCheckActivateStatus(); // // this.updatePower(); //console.log("充值成功获得金币"); // 刷新界面 解锁高级通行证 隐藏通行证按钮 进度条挪到中部 } else { MiniGameSdk.API.showToast("网络异常,充值奖励将在登录后再次发放"); const dataFail4 = { outTradeNo: Utils.outTradeNo, pay_amount: price, payment_name: productId, payment_num: 1, type: systemType, fail_reason: "成功付款,但是发货时请求服务器失败,充值成功未发货", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail4); } }, Utils.outTradeNo) } else { const dataFail3 = { outTradeNo: Utils.outTradeNo, pay_amount: price, payment_name: productId, payment_num: 1, type: systemType, fail_reason: "拉起支付后,付款时网络异常付款失败", } cc.fx.GameTool.shushu_Track("payment_fail", dataFail3); this.btn_Touch = true; } }) } }); } } onActivateBtnClick() { if (cc.fx.GameConfig.GM_INFO.getItemType == 1) { MiniGameSdk.API.showToast("已过期"); } else { let butActivate = cc.instantiate(this.buyActivate); let timeStr = this.time.string; butActivate.getComponent("buyActivate").init(() => { this.onBuyActivate(); }, timeStr); this.node.addChild(butActivate); } } openLoad() { const now = new Date().getTime(); const distance = this.endTime - now; // 计算小时数 const hours = distance / (1000 * 60 * 60); if (hours < 1) { MiniGameSdk.API.showToast("剩余不足1小时,请谨慎购买。"); } this.node.getChildByName("Loading").active = true; this.node.getChildByName("Loading").getChildByName("load").stopAllActions(); this.node.getChildByName("Loading").getChildByName("load").runAction(cc.rotateTo(2, 1080).repeatForever()); } closeLoad() { this.node.getChildByName("Loading").active = false; } openConfirmBox() { this.closeLoad(); this.node.getChildByName("ConfirmBox").active = true; } closeConfirmBox() { this.node.getChildByName("ConfirmBox").active = false; } private updatePassCheckActivateStatus() { this.activateBtn.node.active = false; cc.fx.GameConfig.GM_INFO.passCheckActivate = true; this.setbarNodePosX(); // 获取passCheckMgr实例并更新激活状态 if (this.passCheckMgr && typeof this.passCheckMgr.refreshPassCheckItems === 'function') { this.passCheckMgr.refreshPassCheckItems(); } } setbarNodePosX() { let activate = cc.fx.GameConfig.GM_INFO.passCheckActivate; let barNode = this.node.getChildByName("centralNode").getChildByName("barNode") if (activate || cc.fx.GameConfig.GM_INFO.getItemType == 1) { barNode.x = 0; } else { barNode.x = -253; } } allGetReward() { // 一键领取 // this.passCheckMgr.allGetReward(); } onDestroy() { // 组件销毁时清除定时器 if (this.countdownTimer) { clearInterval(this.countdownTimer); this.countdownTimer = null; } } }