261 lines
10 KiB
TypeScript
261 lines
10 KiB
TypeScript
import JiaZai from "../../Script/JiaZai";
|
|
import LoadingCatAnimation from "../../Script/LoadingCatAnimation";
|
|
import Utils from "../../Script/module/Pay/Utils";
|
|
import { MiniGameSdk } from "../../Script/Sdk/MiniGameSdk";
|
|
import { applyStarterPackStatus, starterPackRemaining, starterPackTimeText } from "../../Script/module/Config/StarterPack";
|
|
|
|
const { ccclass, property } = cc._decorator;
|
|
declare const wx: any;
|
|
|
|
@ccclass
|
|
export default class NewbieGift extends cc.Component {
|
|
// Retain the unused serialized properties in the existing prefab.
|
|
@property(cc.Node) monthCardTime: cc.Node = null;
|
|
@property(cc.Node) monthCardBtn: cc.Node = null;
|
|
@property(cc.Node) monthCardBtn2: cc.Node = null;
|
|
btn_Touch = true;
|
|
private paying = false;
|
|
private polling = false;
|
|
private onShowListener: () => void = null;
|
|
private pendingOrder = "";
|
|
private confirmedOrder = "";
|
|
|
|
init(first: boolean) {
|
|
this.node.opacity = 255;
|
|
this.closeConfirmBox();
|
|
if (!this.paying) this.closeLoad();
|
|
const title = cc.find("ConfirmBox/title", this.node);
|
|
if (title) title.getComponent(cc.Label).string = "幸运礼包充值";
|
|
// The old Spine/propBg nodes stay disabled. Preserve the authored layout.
|
|
this.unschedule(this.refreshCountdown);
|
|
this.schedule(this.refreshCountdown, 1);
|
|
this.refreshCountdown();
|
|
if (typeof wx !== "undefined" && !this.onShowListener) {
|
|
this.onShowListener = () => this.onShow();
|
|
wx.onShow(this.onShowListener);
|
|
}
|
|
this.onShow();
|
|
cc.fx.GameTool.recordStarterPackShown();
|
|
}
|
|
|
|
refreshCountdown() {
|
|
if (!cc.isValid(this)) return;
|
|
const seconds = starterPackRemaining();
|
|
const label = cc.find("timeContainer/time", this.node).getComponent(cc.Label);
|
|
label.string = seconds > 0 ? starterPackTimeText(seconds) : "已结束";
|
|
this.btn_Touch = seconds > 0 && !this.paying;
|
|
cc.find("btnContainer/btn", this.node).getComponent(cc.Button).interactable = this.btn_Touch;
|
|
}
|
|
|
|
onShow() {
|
|
// wx.onShow and the payment callback may arrive together. Only one query
|
|
// chain owns the order; refreshing activity data is not reward delivery.
|
|
if (this.polling) return;
|
|
Utils.getStarter_pack(res => {
|
|
if (res && res.code === 1) applyStarterPackStatus(res.data);
|
|
this.refreshCountdown();
|
|
});
|
|
const order = this.pendingOrder || cc.fx.GameConfig.GM_INFO.iosStarterOrder;
|
|
if (!order) return;
|
|
this.polling = true;
|
|
this.paying = true;
|
|
this.openLoad();
|
|
// Retry only the delivery acknowledgement after payment was confirmed.
|
|
if (this.confirmedOrder === order) {
|
|
this.finishOrder(order);
|
|
return;
|
|
}
|
|
const directPayment = !!this.pendingOrder;
|
|
const version = cc.fx.GameTool.getWechatGameVersion();
|
|
this.logPayment("开始查单", order, {
|
|
channel: directPayment ? "直购" : "iOS客服", version,
|
|
server: version === "开发版" || version === "体验版" ? Utils.testHttpip : Utils.httpip,
|
|
});
|
|
const done = (data) => {
|
|
if (directPayment && data?.code === 1 && data.data?.pay_state === 2) {
|
|
this.confirmedOrder = order;
|
|
this.finishOrder(order);
|
|
} else if (!directPayment && data?.code === 1 && data.data?.payment_name === "starter_pack") {
|
|
// The original customer-service API already completes the order.
|
|
this.completeOrder(order);
|
|
} else if ((directPayment && data?.code === 1 && data.data?.pay_state === 1)
|
|
|| (!directPayment && data?.code === 0 && data.msg === "已经获取到奖励")) {
|
|
// A completed legacy order is not a new grant; clear stale UI state.
|
|
this.completeOrder(order, false);
|
|
} else {
|
|
this.logPayment("等待确认,保留订单供重试", order, {
|
|
code: data?.code, pay_state: data?.data?.pay_state, msg: data?.msg || data?.message,
|
|
});
|
|
this.polling = false;
|
|
this.paying = false;
|
|
this.closeLoad();
|
|
this.refreshCountdown();
|
|
// Keep the order for retry, including after the offer expires.
|
|
this.openConfirmBox();
|
|
}
|
|
};
|
|
if (this.pendingOrder) Utils.getPayInfo(done, order, {
|
|
timeoutMs: 30000,
|
|
onProgress: res => this.logPayment("查单返回", order, {
|
|
code: res?.code, pay_state: res?.data?.pay_state, msg: res?.msg || res?.message,
|
|
}),
|
|
});
|
|
else Utils.getIosPayInfo(order, done);
|
|
}
|
|
|
|
againGet() {
|
|
this.closeConfirmBox();
|
|
this.onShow();
|
|
}
|
|
|
|
buyProduct(event?: cc.Event, customData?: string) {
|
|
if (this.pendingOrder || cc.fx.GameConfig.GM_INFO.iosStarterOrder) {
|
|
this.onShow();
|
|
return;
|
|
}
|
|
this.refreshCountdown();
|
|
if (!this.btn_Touch) return;
|
|
this.paying = true;
|
|
this.refreshCountdown();
|
|
this.openLoad();
|
|
// Fetch the server deadline; purchase eligibility is enforced by this UI.
|
|
Utils.getStarter_pack(res => {
|
|
if (!res || res.code !== 1) {
|
|
this.failPayment("礼包状态获取失败,请重试");
|
|
return;
|
|
}
|
|
applyStarterPackStatus(res.data);
|
|
if (starterPackRemaining() <= 0) {
|
|
this.failPayment("礼包已结束或已购买");
|
|
return;
|
|
}
|
|
let systemType = "Android";
|
|
if (typeof wx !== "undefined" && wx.getSystemInfoSync().platform === "ios") systemType = "ios";
|
|
if (systemType === "ios" && !cc.fx.GameConfig.GM_INFO.iosCanPay) {
|
|
this.iosOldPay();
|
|
return;
|
|
}
|
|
Utils.buyProp("starter_pack", 1, 300, systemType, "starter_pack", result => {
|
|
if (!result || result.err) {
|
|
if (result && result.errCode === 16) {
|
|
this.iosOldPay();
|
|
return;
|
|
}
|
|
this.failPayment(result?.errMsg || "充值未完成");
|
|
return;
|
|
}
|
|
if (!result.outTradeNo) {
|
|
this.failPayment("支付订单号缺失,请重进游戏检查补单");
|
|
return;
|
|
}
|
|
this.pendingOrder = result.outTradeNo;
|
|
this.logPayment("微信支付回调成功,等待服务端确认", this.pendingOrder);
|
|
this.onShow();
|
|
});
|
|
});
|
|
}
|
|
|
|
private finishOrder(order: string) {
|
|
this.logPayment("支付已确认,开始领取确认", order);
|
|
this.paying = true;
|
|
this.openLoad();
|
|
Utils.setPayInfo(res => {
|
|
this.logPayment("领取确认返回", order, { code: res?.code, msg: res?.msg || res?.message });
|
|
this.polling = false;
|
|
if (!res || res.code !== 1) {
|
|
this.paying = false;
|
|
this.openConfirmBox();
|
|
this.refreshCountdown();
|
|
return;
|
|
}
|
|
this.completeOrder(order);
|
|
}, order);
|
|
}
|
|
|
|
private completeOrder(order: string, grant = true) {
|
|
if (grant) {
|
|
this.logPayment("开始前端发奖", order);
|
|
// The legacy acknowledgement returns data: "ok", not order metadata.
|
|
cc.fx.GameTool.shopBuy("starter_pack", false, { outTradeNo: order });
|
|
this.logPayment("前端发奖调用完成", order);
|
|
MiniGameSdk.API.yinli_Pay(300, order, "购买金币道具:starter_pack");
|
|
MiniGameSdk.API.showToast("充值成功");
|
|
}
|
|
this.pendingOrder = "";
|
|
this.confirmedOrder = "";
|
|
cc.fx.GameConfig.GM_INFO.iosStarterOrder = "";
|
|
cc.fx.GameConfig.GM_INFO.starterPackPurchased = true;
|
|
this.polling = false;
|
|
this.paying = false;
|
|
this.buyStarter_pack();
|
|
}
|
|
|
|
private logPayment(stage: string, order: string, details: any = {}) {
|
|
console.log("[新手礼包支付] " + stage, { orderSuffix: String(order).slice(-6), ...details });
|
|
}
|
|
|
|
buyStarter_pack() {
|
|
const canvas = cc.find("Canvas");
|
|
const home = canvas && canvas.getComponent(JiaZai);
|
|
if (home) {
|
|
home.newbieGift = false;
|
|
home.startStarter_pack();
|
|
home.updateCoin();
|
|
}
|
|
const scene = canvas && canvas.getComponent("SceneManager");
|
|
if (scene) scene.refreshJungleRewardDisplay();
|
|
this.closeLoad();
|
|
if (cc.isValid(this)) this.closeStarter_pack();
|
|
}
|
|
|
|
private failPayment(message: string) {
|
|
this.paying = false;
|
|
this.closeLoad();
|
|
this.refreshCountdown();
|
|
MiniGameSdk.API.showToast(message);
|
|
cc.fx.GameTool.shushu_Track("payment_fail", {
|
|
outTradeNo: this.pendingOrder || cc.fx.GameConfig.GM_INFO.iosStarterOrder || "",
|
|
pay_amount: 300, payment_name: "starter_pack", payment_num: 1,
|
|
fail_reason: message,
|
|
});
|
|
}
|
|
|
|
iosOldPay() {
|
|
Utils.GoKEFu({ price: 300, payment_name: "starter_pack", payment_count: 1 }, result => {
|
|
this.paying = false;
|
|
this.closeLoad();
|
|
this.refreshCountdown();
|
|
if (result !== "success") {
|
|
cc.fx.GameConfig.GM_INFO.iosStarterOrder = "";
|
|
MiniGameSdk.API.showToast("未能打开支付,请重试");
|
|
}
|
|
});
|
|
}
|
|
|
|
closeStarter_pack() {
|
|
this.node.active = false;
|
|
this.node.emit("starter-pack-closed");
|
|
}
|
|
openLoad() {
|
|
if (cc.isValid(this)) LoadingCatAnimation.play(this.node.getChildByName("Loading"));
|
|
}
|
|
closeLoad() {
|
|
if (cc.isValid(this)) LoadingCatAnimation.stop(this.node.getChildByName("Loading"));
|
|
}
|
|
openConfirmBox() {
|
|
this.closeLoad();
|
|
if (cc.isValid(this)) this.node.getChildByName("ConfirmBox").active = true;
|
|
}
|
|
closeConfirmBox() {
|
|
if (cc.isValid(this)) this.node.getChildByName("ConfirmBox").active = false;
|
|
}
|
|
onDisable() {
|
|
this.unschedule(this.refreshCountdown);
|
|
if (typeof wx !== "undefined" && this.onShowListener) wx.offShow(this.onShowListener);
|
|
this.onShowListener = null;
|
|
}
|
|
onDestroy() {
|
|
this.onDisable();
|
|
}
|
|
}
|