import Msg from '../msg'; // 确保路径是正确的 const CryptoJS = require("crypto-js"); const AppKey = "57afbdc608db9aa423e1b15b321d7de0" const Account = "H1EqhbpA80jt0Jw6Q3T2"//ws请求密钥 const Order = require('../model/OrderModel') const Server = require('../model/ServerModel') const Version = require('../model/VersionModel') const logger = require('../log') const axios = require('axios'); const ClientId = "849706610247-rok24bfm4sapiggunbuirugf2n31c3ho.apps.googleusercontent.com" const ClientSecret = "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" const RefreshToken = '1//06IooeZBqGqUsCgYIARAAGAYSNwF-L9Ir7cRRL3vBcSsZcQunM2NF6H6rwBjE-WJ_sLIiVyvVCE1iWj4QHOUDGUE0FlA05d8LtPU' const PackageName = "com.ultimategame.sso" const ProductId = "com.ultimategame.sso.aos." //根据区服id获取地址 const getServerList = async (serverId, tag) => { const servers = (await Server.getServerList(tag)) for (let i = 0; i < servers.length; i++) { if (servers[i].id == serverId) { return 'ws://' + servers[i].ip + ':' + servers[i].port } } } const callPay = async (ctx) => { let ret = { code: 0, msg: '发货失败' } const redisClient = ctx.redis.client; let access_token = await redisClient.get('access_token'); if (!access_token) { console.log('请求api获取token') const apiData = { "grant_type": "refresh_token", "client_id": ClientId, "client_secret": ClientSecret, "refresh_token": RefreshToken } const response = await axios.post('https://accounts.google.com/o/oauth2/token', apiData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); logger.info("token params:", { "data": response.data, "params": apiData }) if (!response.data.access_token) { return ret } access_token = response.data.access_token await redisClient.set('access_token', response.data.access_token); await redisClient.expire('access_token', 1800); } if (!access_token) { return ret; } let data = ctx.request.body let orderId = data.orderId let googleToken = data.purchaseToken let out_trade_no = '' logger.info("pay callback params:", { "url": ctx.href, "params": data }) const orderInfo = (await Order.getOrder(orderId))[0] if (!orderInfo) { logger.info(`订单${orderId}不存在`) ret.msg = `订单${orderId}不存在` return ret } if (orderInfo.status == 2) { logger.info(`订单${orderId}已经重复发货`) ret.code = 1 ret.msg = `订单${orderId}已经重复发货` return ret } let url = await getServerList(orderInfo.server_id, 'default') if (!url) { logger.info(`区服id错误: serverId ${orderInfo.server_id}`) ret.msg = `区服id错误: serverId ${orderInfo.server_id}` return ret } const productId = ProductId + orderInfo.product_id let apiUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}?access_token=${access_token}` let maxRetries = 5; let currentRetry = 0; let isCheck = false; // 使用 while 循环进行重试 while (currentRetry < maxRetries) { try { // // 尝试执行的操作 const googleRes = await axios.get(apiUrl, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) console.log(googleRes.data) // 如果操作成功,退出循环 if (googleRes.data.purchaseState == 0) { out_trade_no = googleRes.data.orderId isCheck = true break; } } catch (error) { // 如果操作失败,记录错误并继续尝试 console.log(error) } currentRetry++; } if (!isCheck) { return ret; } Msg.connect(url, Account); let orgMemId = orderInfo.uid let orgOderId = orderId let orgProductId = orderInfo.product_id let orgProductPrice = orderInfo.amount // 在适当的时机,调用 CG_ASK_LOGIN 方法 let params = `{"account":"${orgMemId}","order":"${orgOderId}","id":${orgProductId},"cnt":100,"money":${orgProductPrice}}` return new Promise((resolve) => { setTimeout(async () => { const send_res = Msg.CG_ASK_LOGIN(Account, 0, "", 'cn', 'CN', ctx.request.ip, params); if (!send_res) { resolve(ret); return; } const update_time = formatDate(new Date()) const res = await Order.updateOrderStats( orderId, 2, out_trade_no, update_time ); if (res.affectedRows <= 0) { logger.info(`订单${orderId} 发货失败`) ret.msg = '发货失败' resolve(ret); return; } ret.code = 1 ret.msg = '发货成功' resolve(ret); }, 2000); }); } const compareVersions = (v1: string, v2: string) => { const parts1 = v1.split('.').map(Number); const parts2 = v2.split('.').map(Number); for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) { const num1 = parts1[i] || 0; const num2 = parts2[i] || 0; if (num1 > num2) return 1; if (num1 < num2) return -1; } return 0; } const checkVersion = async (ctx) => { let ret = { code: 0, msg: '无需更新', url: '', } let data = ctx.request.body let version = data.version let tag = data.tag || 'default' logger.info("checkVersion params:", { "url": ctx.href, "params": data }) const versionInfo = (await Version.getGameVersion(tag))[0] if (!versionInfo) { return ret } if (compareVersions(versionInfo.version, version) === 1) { if (versionInfo.download_url) { ret.code = 1 ret.msg = '需要更新' ret.url = versionInfo.download_url } } return ret } //验证账号 const checkUserToken = async (ctx) => { let data = ctx.request.body //签名参数 let signData = Object.keys(data).filter(key => key !== 'sign'); let signStr = signData.map(key => `${data[key]}`).join(''); signStr += AppKey let newSign = CryptoJS.MD5(signStr).toString(); console.log("signStr:", signStr) console.log("newSign:", newSign) if (data.sign != newSign) { console.log("签名错误:", signStr, newSign, data.sign) return false } return data.sign } const generateOrderNumber = () => { const date = new Date(); const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); const seconds = date.getSeconds().toString().padStart(2, '0'); const dateString = `${year}${month}${day}${hours}${minutes}${seconds}`; const randomString1 = Math.floor(Math.random() * 1090000000800) .toString() .slice(0, 4); const randomString2 = Math.floor(Math.random() * 1090000000800) .toString() .slice(0, 4); return "CP" + dateString + randomString1 + randomString2; } const formatDate = (date: Date) => { const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = date.getDate().toString().padStart(2, '0'); return `${year}-${month}-${day}`; } class ApiController { async createOrder(ctx) { let { uid, level, amount, role_id, role_name, product_id, server_id } = ctx.request.body logger.info("create params:", { "params": ctx }) logger.info("create params:", { "params": ctx.request.body }) if (!product_id || !server_id || !role_name || !role_id || !amount || !uid) { ctx.body = { code: -1, message: '参数错误,创建订单失败!!', data: '' } return } const orderId = generateOrderNumber(); // 生成一个长度为8的订单号 const create_time = formatDate(new Date()) const res = await Order.createOrder( orderId, uid, level, amount, role_id, role_name, product_id, server_id, create_time ); if (res.affectedRows > 0) { ctx.body = { code: 0, message: '创建订单成功', data: orderId } } else { ctx.body = { code: -1, message: '创建订单失败', data: '' } } logger.info("创建订单返回结果:", { "params": ctx.body }) } async checkUserToken(ctx) { const result = await checkUserToken(ctx); let data = { "status": false, "sign": "" } if (result) { data.status = true data.sign = result } ctx.body = data } async callPay(ctx) { var result = await callPay(ctx) console.log('发货结果', result) ctx.body = result } async checkVersion(ctx) { var result = await checkVersion(ctx) console.log('校验版本', result) ctx.body = result } async getServerList(ctx) { let tag = ctx.query.tag || 'default' const servers = (await Server.getServerList(tag)) ctx.body = servers } } module.exports = new ApiController()