cb/assets/shop/script/passCheck.ts

771 lines
29 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<any> = []; // 存储处理后的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;
}
}
}