diff --git a/assets/Scripts/Sub/UI/LoginUI.ts b/assets/Scripts/Sub/UI/LoginUI.ts index 68329664..11535c16 100644 --- a/assets/Scripts/Sub/UI/LoginUI.ts +++ b/assets/Scripts/Sub/UI/LoginUI.ts @@ -41,7 +41,7 @@ export class LoginUI extends li_BaseView { const deviceId = DeviceIdService.I.id; const os = MachineInfoService.I.getMachineOs(); const reqData = { - platType: "guset", + platType: "guest", userId: deviceId, device: deviceId, os, diff --git a/assets/Scripts/chat18x/data/OrderData.ts b/assets/Scripts/chat18x/data/OrderData.ts index ee50e211..3a1d429a 100644 --- a/assets/Scripts/chat18x/data/OrderData.ts +++ b/assets/Scripts/chat18x/data/OrderData.ts @@ -62,6 +62,7 @@ export class OrderData extends BaseData { vo.status = mapQueryOrderStatus(res.status); vo.retCode = res.retCode ?? 0; this._orders.set(orderId, vo); + console.log("更新订单数据:", vo); } /** 获取所有需要继续轮询查询的订单 id */ diff --git a/assets/Scripts/chat18x/payment/PaymentPoller.ts b/assets/Scripts/chat18x/payment/PaymentPoller.ts index bc3db85d..a50bf099 100644 --- a/assets/Scripts/chat18x/payment/PaymentPoller.ts +++ b/assets/Scripts/chat18x/payment/PaymentPoller.ts @@ -6,41 +6,75 @@ import { PaymentApi } from "./PaymentApi"; import proto from 'db://assets/Scripts/proto/proto.pb.js'; export interface PollOptions { - maxDurationMs: number; // 轮询总时长(例如 2分钟) - startIntervalMs: number; // 初始间隔(例如 2s) - maxIntervalMs: number; // 最大间隔(例如 10s) - jitter?: boolean; // 抖动 + maxDurationMs: number; // 最大轮询时长(超过就自动退出)(例如 2分钟) + startIntervalMs: number; // 第一次轮询等待的间隔(例如 2s) + maxIntervalMs: number; // 最大允许的间隔,防止指数增长过大(例如 10s) + jitter?: boolean; // 是否启用抖动(让等待时间带点随机性,避免所有客户端同一时间请求服务器) } export class PaymentPoller { private cancelled = false; + private currentPollCount = 0; // 轮询次数 // 取消轮询 - cancel() { this.cancelled = true; } + cancel() { + this.cancelled = true; + } - // 轮询订单 - async poll(orderId: string, opt: PollOptions, onTick?: (d: proto.cs.ICSQueryOrderRes) => void): Promise { + // 获取当前轮询次数 + public getCurrentPollCount(): number { + return this.currentPollCount; + } + + /** + * 轮询订单 + * @param orderId 要查询的订单 ID + * @param opt 轮询配置(间隔、最大时长、是否抖动) + * @param onTick 可选回调函数,每次轮询到结果时调用 + * @returns 最终查询到的订单结果 ICSQueryOrderRes,或者 null(超时/被取消) + */ + async poll(orderId: string, opt: PollOptions, onTick?: (d: proto.cs.ICSQueryOrderRes) => void): Promise { const t0 = Date.now(); let interval = opt.startIntervalMs; while (!this.cancelled) { + // 增加轮询次数 + this.currentPollCount++; // 查询 let reqData = {orderId: orderId}; + console.log("第 ", this.currentPollCount, " 次轮询订单的请求数据:", reqData); const r = await PaymentApi.I.queryOrder(reqData); + console.log("第 ", this.currentPollCount, " 次轮询订单的响应数据:", r); if (r.code === proto.cs.EnmRetCode.SUCCESS && r.data) { // 回调 onTick?.(r.data); + // 订单状态,-1:失败,0:成功,1:处理中 if ([-1, 0].indexOf(r.data.status) !== -1) { return r.data; } } - // 退出条件 - if (Date.now() - t0 > opt.maxDurationMs) return null; + // 轮询超时 + if (Date.now() - t0 > opt.maxDurationMs) { + let resultData: proto.cs.ICSQueryOrderRes = { + status: 92, // 自定义的状态,代表客户端轮询超时 + retCode: 0, + balance: 0, + vipExpire: 0, + } + return resultData; + } // 等待 await this.sleep(this.jitter(interval, opt)); // 每次轮询后,interval 会按照 1.5 倍增长,直到达到最大间隔 maxIntervalMs,避免在短时间内重复请求 interval = Math.min(interval * 1.5, opt.maxIntervalMs); } - return null; + // 至此,代表取消了轮询订单 + let resultData: proto.cs.ICSQueryOrderRes = { + status: 90, // 自定义的状态,代表取消 + retCode: 0, + balance: 0, + vipExpire: 0, + } + return resultData; } // 用来暂停一定的时间(ms 毫秒),并让轮询进入等待状态 diff --git a/assets/Scripts/chat18x/payment/PaymentService.ts b/assets/Scripts/chat18x/payment/PaymentService.ts index 5fc08385..66200005 100644 --- a/assets/Scripts/chat18x/payment/PaymentService.ts +++ b/assets/Scripts/chat18x/payment/PaymentService.ts @@ -32,12 +32,12 @@ export class PaymentService { } /** 发起支付:创建订单→打开URL→回到App后开始轮询 */ - async startPayment(req: proto.cs.ICSCreateOrderReq, open: OpenStrategy = "system"): Promise { + async startPayment(req: proto.cs.ICSCreateOrderReq, open: OpenStrategy = "system"): Promise { // 下单 const create = await PaymentApi.I.createOrder(req); console.log("创建订单的响应数据:", create); if (create.code !== proto.cs.EnmRetCode.SUCCESS || !create.data) { - return { status: -1, retCode: -1 }; + return { status: -1, retCode: -1, balance: 0, vipExpire: 0}; } const { orderId, payUrl } = create.data; this.bus.emit(PaymentEvents.Started, { orderId }); @@ -108,6 +108,7 @@ export class PaymentService { return new Promise((resolve) => { let finished = false; const finish = () => { + console.log("应用回到 finish"); if (finished) return; finished = true; // 安全移除监听 @@ -117,6 +118,7 @@ export class PaymentService { const onShow = () => { // 应用回到前台 + console.log("应用回到了前台"); finish(); }; @@ -124,8 +126,8 @@ export class PaymentService { game.on(Game.EVENT_SHOW, onShow, this); // 兜底:某些环境(桌面浏览器)可能不会触发隐藏/显示事件,避免一直卡住 - const FALLBACK_MS = 15000; // 按需调整 - setTimeout(finish, FALLBACK_MS); + const FALLBACK_MS = 25000; // 按需调整 + // setTimeout(finish, FALLBACK_MS); }); } } diff --git a/assets/Scripts/chat18x/payment/PaymentUtil.ts b/assets/Scripts/chat18x/payment/PaymentUtil.ts index 25f00cda..c66fb4e4 100644 --- a/assets/Scripts/chat18x/payment/PaymentUtil.ts +++ b/assets/Scripts/chat18x/payment/PaymentUtil.ts @@ -22,13 +22,15 @@ export function mapQueryOrderStatus( case 1: return "PENDING"; // 处理中 case 0: return "SUCCESS"; // 成功 case -1: return "FAILED"; // 失败 + case 90: return "CANCELED"; // 取消 + case 92: return "TIMEOUT"; // 轮询超时 default: return "CREATED"; // 未知/初始,按“已创建”兜底 } } /** 是否为终态(无需再轮询) */ export function isTerminalStatus(s: OrderStatus): boolean { - return s === "SUCCESS" || s === "FAILED" || s === "CANCELED" || s === "EXPIRED"; + return s === "SUCCESS" || s === "FAILED" || s === "CANCELED" || s === "EXPIRED" || s === "TIMEOUT"; } /** 是否应继续轮询查询订单 */ diff --git a/assets/Scripts/chat18x/payment/types.ts b/assets/Scripts/chat18x/payment/types.ts index 88198b9a..0a3fc4d6 100644 --- a/assets/Scripts/chat18x/payment/types.ts +++ b/assets/Scripts/chat18x/payment/types.ts @@ -9,6 +9,7 @@ export type OrderStatus = | "SUCCESS" // 成功 | "FAILED" // 失败 | "CANCELED" // 取消 + | "TIMEOUT" // 轮询超时 | "EXPIRED"; // 过期 // 订单数据的数据结构 diff --git a/assets/Scripts/chat18x/ui/panels/PurchasePanel.ts b/assets/Scripts/chat18x/ui/panels/PurchasePanel.ts index 4a63647b..93de86a9 100644 --- a/assets/Scripts/chat18x/ui/panels/PurchasePanel.ts +++ b/assets/Scripts/chat18x/ui/panels/PurchasePanel.ts @@ -186,10 +186,19 @@ export class PurchasePanel extends li_BaseView { const reqData = { goodId }; - // let res = await PaymentService.I.startPayment(reqData); - // if (res) { - - // } + let res = await PaymentService.I.startPayment(reqData); + console.log("支付完成的响应数据:", res); + if (res) { + let status = res.status; + if (status === -1) { + console.log("支付失败!!!,错误码:", res.retCode); + } else if (status === 0) { + console.log("支付成功!!!"); + const walletData = DataManager.I.getDataById(DataId.Wallet); + walletData.balance = Number(res.balance); + walletData.vipExpire = Number(res.vipExpire); + } + } } onDestroy() { diff --git a/assets/Scripts/proto/proto.pb.d.ts b/assets/Scripts/proto/proto.pb.d.ts index 7fac9e72..13800188 100644 --- a/assets/Scripts/proto/proto.pb.d.ts +++ b/assets/Scripts/proto/proto.pb.d.ts @@ -5802,11 +5802,23 @@ static getTypeUrl(typeUrlPrefix?: string): string; /** EnmRetCode enum. */ enum EnmRetCode { SUCCESS = 0, - GenJWTFailed = 5010, - InvalidArg = 5013, - MySQL = 5027, - TokenExpire = 5046, - TokenInvalid = 5047 + GenJWTFailed = 5000, + Insufficient = 5001, + InvalidArg = 5002, + InvalidSign = 5003, + JsonFormat = 5004, + MySQL = 5005, + NotRegist = 5006, + NotResConfig = 5007, + Rate_Limited = 5008, + Redis = 5009, + Request_Too_More = 5010, + RMGOrder_Code = 5011, + RMGOrder_Http = 5012, + RMGOrder_MaxQuery = 5013, + RMGOrder_NotFound = 5014, + TokenExpire = 5015, + TokenInvalid = 5016 } } diff --git a/assets/Scripts/proto/proto.pb.js b/assets/Scripts/proto/proto.pb.js index 909bff9b..f2b4b0ac 100644 --- a/assets/Scripts/proto/proto.pb.js +++ b/assets/Scripts/proto/proto.pb.js @@ -13854,20 +13854,44 @@ $root.cs = (function() { * @name cs.EnmRetCode * @enum {number} * @property {number} SUCCESS=0 SUCCESS value - * @property {number} GenJWTFailed=5010 GenJWTFailed value - * @property {number} InvalidArg=5013 InvalidArg value - * @property {number} MySQL=5027 MySQL value - * @property {number} TokenExpire=5046 TokenExpire value - * @property {number} TokenInvalid=5047 TokenInvalid value + * @property {number} GenJWTFailed=5000 GenJWTFailed value + * @property {number} Insufficient=5001 Insufficient value + * @property {number} InvalidArg=5002 InvalidArg value + * @property {number} InvalidSign=5003 InvalidSign value + * @property {number} JsonFormat=5004 JsonFormat value + * @property {number} MySQL=5005 MySQL value + * @property {number} NotRegist=5006 NotRegist value + * @property {number} NotResConfig=5007 NotResConfig value + * @property {number} Rate_Limited=5008 Rate_Limited value + * @property {number} Redis=5009 Redis value + * @property {number} Request_Too_More=5010 Request_Too_More value + * @property {number} RMGOrder_Code=5011 RMGOrder_Code value + * @property {number} RMGOrder_Http=5012 RMGOrder_Http value + * @property {number} RMGOrder_MaxQuery=5013 RMGOrder_MaxQuery value + * @property {number} RMGOrder_NotFound=5014 RMGOrder_NotFound value + * @property {number} TokenExpire=5015 TokenExpire value + * @property {number} TokenInvalid=5016 TokenInvalid value */ cs.EnmRetCode = (function() { var valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "SUCCESS"] = 0; - values[valuesById[5010] = "GenJWTFailed"] = 5010; - values[valuesById[5013] = "InvalidArg"] = 5013; - values[valuesById[5027] = "MySQL"] = 5027; - values[valuesById[5046] = "TokenExpire"] = 5046; - values[valuesById[5047] = "TokenInvalid"] = 5047; + values[valuesById[5000] = "GenJWTFailed"] = 5000; + values[valuesById[5001] = "Insufficient"] = 5001; + values[valuesById[5002] = "InvalidArg"] = 5002; + values[valuesById[5003] = "InvalidSign"] = 5003; + values[valuesById[5004] = "JsonFormat"] = 5004; + values[valuesById[5005] = "MySQL"] = 5005; + values[valuesById[5006] = "NotRegist"] = 5006; + values[valuesById[5007] = "NotResConfig"] = 5007; + values[valuesById[5008] = "Rate_Limited"] = 5008; + values[valuesById[5009] = "Redis"] = 5009; + values[valuesById[5010] = "Request_Too_More"] = 5010; + values[valuesById[5011] = "RMGOrder_Code"] = 5011; + values[valuesById[5012] = "RMGOrder_Http"] = 5012; + values[valuesById[5013] = "RMGOrder_MaxQuery"] = 5013; + values[valuesById[5014] = "RMGOrder_NotFound"] = 5014; + values[valuesById[5015] = "TokenExpire"] = 5015; + values[valuesById[5016] = "TokenInvalid"] = 5016; return values; })(); diff --git a/assets/bundles/DataTable/tblanguage.bin b/assets/bundles/DataTable/tblanguage.bin index d0c0b1b8..17a8b660 100644 Binary files a/assets/bundles/DataTable/tblanguage.bin and b/assets/bundles/DataTable/tblanguage.bin differ diff --git a/proto_cs b/proto_cs index 02474af6..5a82a609 160000 --- a/proto_cs +++ b/proto_cs @@ -1 +1 @@ -Subproject commit 02474af62a6831a909fa28fefa83afa382cc86ee +Subproject commit 5a82a609b0dc5778ebb7afe701d424ed1d97bd4a diff --git a/xchat_cfg b/xchat_cfg index cc6aa938..564088fe 160000 --- a/xchat_cfg +++ b/xchat_cfg @@ -1 +1 @@ -Subproject commit cc6aa9382db0ee133926dbf5c18f2df682aa4dc7 +Subproject commit 564088febe1f4e89a900e6712659dad22fff58f2