ApiController.ts 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614
  1. import Msg from "../utils/msg"; // 确保路径是正确的
  2. import QuickAsy from "../utils/quickAsy";
  3. import { parseString } from "xml2js";
  4. import {
  5. RefreshToken,
  6. PackageName,
  7. ProductId,
  8. IosUrl,
  9. AppSecretSanLi,
  10. Account,
  11. ClientSecret,
  12. ClientId,
  13. AppSecret360,
  14. } from "../config/thirdParams";
  15. import {
  16. generateOrderNumber,
  17. formatDate,
  18. getServerList,
  19. } from "../utils/common";
  20. const CryptoJS = require("crypto-js");
  21. const Order = require("../model/OrderModel");
  22. const Server = require("../model/ServerModel");
  23. const System = require("../model/SystemModel");
  24. const User = require("../model/UserModel");
  25. const Version = require("../model/VersionModel");
  26. const CDK = require("../model/CDK");
  27. const notice = require("../json/notice.json");
  28. const th_notice = require("../json/th_notice.json");
  29. const xky_notice = require("../json/xky_notice.json");
  30. const logger = require("../utils/log");
  31. const axios = require("axios");
  32. const googleCallPay = async (ctx) => {
  33. let ret = {
  34. code: 0,
  35. msg: "发货失败",
  36. };
  37. let data = ctx.request.body;
  38. let orderId = data.orderId;
  39. let googleToken = data.purchaseToken;
  40. let out_trade_no = "";
  41. logger.info("pay callback params:", { url: ctx.href, params: data });
  42. const res = await Order.updateOrderToken(orderId, googleToken, "google");
  43. const redisClient = ctx.redis.client;
  44. let access_token = await redisClient.get("access_token");
  45. if (!access_token) {
  46. console.log("请求api获取token");
  47. const apiData = {
  48. grant_type: "refresh_token",
  49. client_id: ClientId,
  50. client_secret: ClientSecret,
  51. refresh_token: RefreshToken,
  52. };
  53. const response = await axios.post(
  54. "https://accounts.google.com/o/oauth2/token",
  55. apiData,
  56. {
  57. headers: {
  58. "Content-Type": "application/x-www-form-urlencoded",
  59. },
  60. }
  61. );
  62. logger.info("token params:", { data: response.data, params: apiData });
  63. if (!response.data.access_token) {
  64. return ret;
  65. }
  66. access_token = response.data.access_token;
  67. await redisClient.set("access_token", response.data.access_token);
  68. await redisClient.expire("access_token", 1800);
  69. }
  70. if (!access_token) {
  71. return ret;
  72. }
  73. const orderInfo = (await Order.getOrder(orderId))[0];
  74. if (!orderInfo) {
  75. logger.info(`订单${orderId}不存在`);
  76. ret.msg = `订单${orderId}不存在`;
  77. return ret;
  78. }
  79. if (orderInfo.status == 2) {
  80. logger.info(`订单${orderId}已经重复发货`);
  81. ret.code = 1;
  82. ret.msg = `订单${orderId}已经重复发货`;
  83. return ret;
  84. }
  85. let url = await getServerList(orderInfo.server_id, "default");
  86. if (!url) {
  87. logger.info(`区服id错误: serverId ${orderInfo.server_id}`);
  88. ret.msg = `区服id错误: serverId ${orderInfo.server_id}`;
  89. return ret;
  90. }
  91. const productId = ProductId + orderInfo.product_id;
  92. let apiUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}?access_token=${access_token}`;
  93. let maxRetries = 3;
  94. let currentRetry = 0;
  95. let isCheck = false;
  96. // 使用 while 循环进行重试
  97. while (currentRetry < maxRetries) {
  98. try {
  99. // // 尝试执行的操作
  100. const googleRes = await axios.get(apiUrl, {
  101. headers: {
  102. "Content-Type": "application/x-www-form-urlencoded",
  103. },
  104. });
  105. console.log(googleRes.data);
  106. // 如果操作成功,退出循环
  107. if (googleRes.data.purchaseState == 0) {
  108. out_trade_no = googleRes.data.orderId;
  109. isCheck = true;
  110. break;
  111. }
  112. } catch (error) {
  113. // 捕获请求中的错误
  114. if (error.response) {
  115. // 请求已发出,服务器用状态码响应
  116. console.error(error.response.data);
  117. console.error(error.response.status);
  118. console.error(error.response.headers);
  119. } else if (error.request) {
  120. // 请求已发出但没有收到响应
  121. // 这通常是网络错误
  122. console.error(error.request);
  123. } else {
  124. // 在设置请求时出现错误
  125. console.error("Error", error.message);
  126. }
  127. }
  128. currentRetry++;
  129. }
  130. if (!isCheck) {
  131. return ret;
  132. }
  133. let sendMsg = new Msg();
  134. sendMsg.connect(url, Account);
  135. let orgMemId = orderInfo.uid;
  136. let orgOderId = orderId;
  137. let orgProductId = orderInfo.product_id;
  138. let orgProductPrice = orderInfo.amount;
  139. const accountInfo = (await User.checkAccountIsExist(orgMemId))[0];
  140. // 在适当的时机,调用 CG_ASK_LOGIN 方法
  141. let params = `{"account":"${orgMemId}","channel_id":${accountInfo.channel_id},"order":"${orgOderId}","id":${orgProductId},"cnt":100,"money":${orgProductPrice}}`;
  142. return new Promise((resolve) => {
  143. setTimeout(async () => {
  144. const send_res = sendMsg.CG_ASK_LOGIN(
  145. Account,
  146. 0,
  147. "",
  148. "cn",
  149. "CN",
  150. ctx.request.ip,
  151. params,
  152. orderInfo.server_id
  153. );
  154. if (!send_res) {
  155. resolve(ret);
  156. return;
  157. }
  158. try {
  159. let acknowledgeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:acknowledge?access_token=${access_token}`;
  160. const acknowledgeRes = await axios.post(
  161. acknowledgeUrl,
  162. {
  163. developerPayload: "",
  164. },
  165. {
  166. headers: {
  167. "Content-Type": "application/json",
  168. },
  169. }
  170. );
  171. } catch (error) {
  172. // 捕获请求中的错误
  173. if (error.response) {
  174. // 请求已发出,服务器用状态码响应
  175. console.error(error.response.data);
  176. console.error(error.response.status);
  177. console.error(error.response.headers);
  178. } else if (error.request) {
  179. // 请求已发出但没有收到响应
  180. // 这通常是网络错误
  181. console.error(error.request);
  182. } else {
  183. // 在设置请求时出现错误
  184. console.error("Error", error.message);
  185. }
  186. ret.msg = "请求第三方失败";
  187. resolve(ret);
  188. }
  189. try {
  190. let consumeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:consume?access_token=${access_token}`;
  191. const consumeRes = await axios.post(
  192. consumeUrl,
  193. {
  194. developerPayload: "",
  195. },
  196. {
  197. headers: {
  198. "Content-Type": "application/json",
  199. },
  200. }
  201. );
  202. } catch (error) {
  203. // 捕获请求中的错误
  204. if (error.response) {
  205. // 请求已发出,服务器用状态码响应
  206. console.error(error.response.data);
  207. console.error(error.response.status);
  208. console.error(error.response.headers);
  209. } else if (error.request) {
  210. // 请求已发出但没有收到响应
  211. // 这通常是网络错误
  212. console.error(error.request);
  213. } else {
  214. // 在设置请求时出现错误
  215. console.error("Error", error.message);
  216. }
  217. ret.msg = "请求第三方失败";
  218. resolve(ret);
  219. }
  220. logger.info("谷歌 pass :", { orderId: orderId });
  221. const update_time = formatDate(new Date());
  222. const res = await Order.updateOrderStats(
  223. orderId,
  224. 2,
  225. out_trade_no,
  226. update_time,
  227. orderInfo.uid
  228. );
  229. if (res.affectedRows <= 0) {
  230. logger.info(`订单${orderId} 发货失败`);
  231. ret.msg = "发货失败";
  232. resolve(ret);
  233. return;
  234. }
  235. ret.code = 1;
  236. ret.msg = "发货成功";
  237. resolve(ret);
  238. }, 1000);
  239. });
  240. };
  241. const appleCallPay = async (ctx) => {
  242. let ret = {
  243. code: 0,
  244. msg: "发货失败",
  245. };
  246. let data = ctx.request.body;
  247. logger.info("pay callback params:", { url: ctx.href, params: data });
  248. if (!data.purchaseToken || !data.orderId) {
  249. return ret;
  250. }
  251. let receipt_data = data.purchaseToken.replace(/ /g, "+");
  252. let orderId = data.orderId;
  253. let maxRetries = 5;
  254. let currentRetry = 0;
  255. let isCheck = false;
  256. let out_trade_no = orderId;
  257. const res = await Order.updateOrderToken(orderId, receipt_data, "apple");
  258. // 使用 while 循环进行重试
  259. while (currentRetry < maxRetries) {
  260. try {
  261. const apiData = {
  262. "receipt-data": receipt_data,
  263. };
  264. const response = await axios.post(IosUrl, apiData, {
  265. headers: {
  266. "Content-Type": "application/json",
  267. },
  268. });
  269. logger.info(`苹果返回的状态:${response.data.status}`);
  270. // 如果操作成功,退出循环
  271. if (response.data.status == 0) {
  272. isCheck = true;
  273. break;
  274. }
  275. } catch (error) {
  276. // 如果操作失败,记录错误并继续尝试
  277. console.log(error);
  278. }
  279. currentRetry++;
  280. }
  281. if (!isCheck) {
  282. logger.info(`票据验证失败!`);
  283. ret.msg = `票据验证失败!`;
  284. return ret;
  285. }
  286. const orderInfo = (await Order.getOrder(orderId))[0];
  287. if (!orderInfo) {
  288. logger.info(`订单${orderId}不存在`);
  289. ret.msg = `订单${orderId}不存在`;
  290. return ret;
  291. }
  292. if (orderInfo.status == 2) {
  293. logger.info(`订单${orderId}已经重复发货`);
  294. ret.code = 1;
  295. ret.msg = `订单${orderId}已经重复发货`;
  296. return ret;
  297. }
  298. let url = await getServerList(orderInfo.server_id, "default");
  299. if (!url) {
  300. logger.info(`区服id错误: serverId ${orderInfo.server_id}`);
  301. ret.msg = `区服id错误: serverId ${orderInfo.server_id}`;
  302. return ret;
  303. }
  304. let sendMsg = new Msg();
  305. sendMsg.connect(url, Account);
  306. let orgMemId = orderInfo.uid;
  307. let orgOderId = orderId;
  308. let orgProductId = orderInfo.product_id;
  309. let orgProductPrice = orderInfo.amount;
  310. const accountInfo = (await User.checkAccountIsExist(orgMemId))[0];
  311. // 在适当的时机,调用 CG_ASK_LOGIN 方法
  312. let params = `{"account":"${orgMemId}","channel_id":${accountInfo.channel_id},"order":"${orgOderId}","id":${orgProductId},"cnt":100,"money":${orgProductPrice}}`;
  313. return new Promise((resolve) => {
  314. setTimeout(async () => {
  315. logger.info(`订单${orderId}通知游戏发货开始`);
  316. const send_res = sendMsg.CG_ASK_LOGIN(
  317. Account,
  318. 0,
  319. "",
  320. "cn",
  321. "CN",
  322. ctx.request.ip,
  323. params,
  324. orderInfo.server_id
  325. );
  326. if (!send_res) {
  327. resolve(ret);
  328. return;
  329. }
  330. logger.info(`订单${orderId}通知游戏发货结束`);
  331. const update_time = formatDate(new Date());
  332. const res = await Order.updateOrderStats(
  333. orderId,
  334. 2,
  335. out_trade_no,
  336. update_time,
  337. orderInfo.uid
  338. );
  339. if (res.affectedRows <= 0) {
  340. logger.info(`订单${orderId} 发货失败`);
  341. ret.msg = "发货失败";
  342. resolve(ret);
  343. return;
  344. }
  345. ret.code = 1;
  346. ret.msg = "发货成功";
  347. resolve(ret);
  348. }, 1000);
  349. });
  350. };
  351. //qucik发货
  352. //扩展参数格式为${serverId};${productId}
  353. const CallPayQuick = async (ctx) => {
  354. let ret = {
  355. code: 0,
  356. msg: "发货失败",
  357. };
  358. //sdk参数
  359. let md5Key = "q97tvr1yqpum8y2h7d0mhvosffrplwlm";
  360. let callbackKey = "77410735093537425113205417841669";
  361. let data = ctx.request.body;
  362. logger.info("qucik 回调参数", { data: data });
  363. let md5Sign = data.md5Sign;
  364. let ntData = data.nt_data;
  365. let verifySignData = QuickAsy.getSign(data, md5Key);
  366. if (verifySignData != md5Sign) {
  367. logger.error("quick 调用md5Sign错误", {
  368. $verifySignData: verifySignData,
  369. md5Sign: md5Sign,
  370. });
  371. return ret;
  372. }
  373. let xmlData = QuickAsy.decode(ntData, callbackKey);
  374. const result = await new Promise((resolve, reject) => {
  375. parseString(xmlData, (err, result) => {
  376. if (err) {
  377. return reject(err);
  378. }
  379. resolve(result);
  380. });
  381. });
  382. const message = (result as any).quicksdk_message.message[0];
  383. const channel = message.channel[0];
  384. const orgMemId = message.channel_uid[0];
  385. const channelOrder = message.channel_order[0];
  386. const orderId = message.game_order[0]; //cp单号
  387. const orderNo = message.order_no[0]; //sdk订单号
  388. const payTime = message.pay_time[0];
  389. const orgProductPrice = message.amount[0]; //充值成功的金额
  390. const status = message.status[0]; //0成功
  391. const extrasParams = message.extras_params[0];
  392. if (status == 1) {
  393. return;
  394. }
  395. const orderInfo = (await Order.getOrder(orderId))[0];
  396. if (!orderInfo) {
  397. logger.info(`订单${orderId}不存在`);
  398. ret.msg = `订单${orderId}不存在`;
  399. return ret;
  400. }
  401. let serverId = orderInfo.server_id; //区服id
  402. let orgProductId = orderInfo.product_id; //商品id
  403. if (orderInfo.status == 2) {
  404. logger.info(`订单${orderId}已经重复发货`);
  405. ret.code = 1;
  406. ret.msg = `订单${orderId}已经重复发货`;
  407. return ret;
  408. }
  409. let url = await getServerList(serverId, "default");
  410. if (!url) {
  411. logger.info(`区服id错误: serverId ${serverId}`);
  412. ret.msg = `区服id错误: serverId ${serverId}`;
  413. return ret;
  414. }
  415. // 使用 Msg 类的 connect 方法连接到 WebSocket 服务器
  416. let sendMsg = new Msg();
  417. sendMsg.connect(url, Account);
  418. logger.info(`订单${orderId} ${url}`);
  419. const accountInfo = (await User.checkAccountIsExist(orgMemId))[0];
  420. // 在适当的时机,调用 CG_ASK_LOGIN 方法
  421. let params = `{"account":"${orgMemId}","order":"${orderId}","channel_id":${accountInfo.channel_id},"id":${orgProductId},"cnt":100,"money":${orgProductPrice}}`;
  422. return new Promise((resolve) => {
  423. setTimeout(async () => {
  424. console.log("这个消息将在3秒后打印出来");
  425. const send_res = sendMsg.CG_ASK_LOGIN(
  426. Account,
  427. 0,
  428. "",
  429. "cn",
  430. "CN",
  431. ctx.request.ip,
  432. params,
  433. serverId
  434. );
  435. if (!send_res) {
  436. resolve(ret);
  437. return;
  438. }
  439. const update_time = formatDate(new Date());
  440. const res = await Order.updateOrderStats(
  441. orderId,
  442. 2,
  443. orderNo,
  444. update_time,
  445. orderInfo.uid
  446. );
  447. if (res.affectedRows <= 0) {
  448. logger.info(`订单${orderId} 发货失败`);
  449. ret.msg = "发货失败";
  450. resolve(ret);
  451. return;
  452. }
  453. ret.code = 1;
  454. ret.msg = "发货成功";
  455. resolve(ret);
  456. }, 1000);
  457. });
  458. };
  459. const CallPay360 = async (ctx) => {
  460. let ret = {
  461. code: 0,
  462. msg: "发货失败",
  463. };
  464. let data = ctx.request.body;
  465. let sign = data.sign;
  466. let serverId = data.serverId;
  467. let orderId = data.cpOrder;
  468. let out_trade_no = data.orderId;
  469. logger.info("pay callback params:", { url: ctx.href, params: data });
  470. const orderInfo = (await Order.getOrder(orderId))[0];
  471. if (!orderInfo) {
  472. logger.info(`订单${orderId}不存在`);
  473. ret.msg = `订单${orderId}不存在`;
  474. return ret;
  475. }
  476. if (orderInfo.status == 2) {
  477. logger.info(`订单${orderId}已经重复发货`);
  478. ret.code = 1;
  479. ret.msg = `订单${orderId}已经重复发货`;
  480. return ret;
  481. }
  482. //签名参数
  483. let signData = Object.keys(data)
  484. .sort()
  485. .filter((key) => key !== "sign");
  486. let signStr = signData.map((key) => `${data[key]}`).join("");
  487. signStr += AppSecret360;
  488. let newSign = CryptoJS.MD5(signStr).toString();
  489. console.log("signStr:", signStr);
  490. console.log("newSign:", newSign);
  491. if (sign != newSign) {
  492. logger.info(`签名错误: 签名串 ${signStr} newSign ${newSign} sign ${sign}`);
  493. ret.msg = `签名错误`;
  494. return ret;
  495. }
  496. let url = await getServerList(serverId, "default");
  497. if (!url) {
  498. logger.info(`区服id错误: serverId ${serverId}`);
  499. ret.msg = `区服id错误: serverId ${serverId}`;
  500. return ret;
  501. }
  502. //发货
  503. // 使用 Msg 类的 connect 方法连接到 WebSocket 服务器
  504. let sendMsg = new Msg();
  505. sendMsg.connect(url, Account);
  506. logger.info(`订单${orderId} ${url}`);
  507. let orgMemId = data.uid;
  508. let orgOderId = data.cpOrder;
  509. let orgProductId = orderInfo.product_id;
  510. let orgExt = data.cText;
  511. let orgProductPrice = data.skuPrice;
  512. const accountInfo = (await User.checkAccountIsExist(orgMemId))[0];
  513. // 在适当的时机,调用 CG_ASK_LOGIN 方法
  514. let params = `{"account":"${orgMemId}","order":"${orgOderId}","id":${orgProductId},"channel_id":${accountInfo.channel_id},"cnt":100,"money":${orgProductPrice}}`;
  515. return new Promise((resolve) => {
  516. setTimeout(async () => {
  517. console.log("这个消息将在3秒后打印出来");
  518. const send_res = sendMsg.CG_ASK_LOGIN(
  519. Account,
  520. 0,
  521. "",
  522. "cn",
  523. "CN",
  524. ctx.request.ip,
  525. params,
  526. serverId
  527. );
  528. if (!send_res) {
  529. resolve(ret);
  530. return;
  531. }
  532. const update_time = formatDate(new Date());
  533. const res = await Order.updateOrderStats(
  534. orderId,
  535. 2,
  536. out_trade_no,
  537. update_time,
  538. orderInfo.uid
  539. );
  540. if (res.affectedRows <= 0) {
  541. logger.info(`订单${orderId} 发货失败`);
  542. ret.msg = "发货失败";
  543. resolve(ret);
  544. return;
  545. }
  546. ret.code = 1;
  547. ret.msg = "发货成功";
  548. resolve(ret);
  549. }, 1000);
  550. });
  551. };
  552. const CallPaySanLi = async (ctx) => {
  553. let ret = {
  554. code: 1,
  555. msg: "发货失败",
  556. };
  557. let data = ctx.request.body;
  558. let sign = data.sign;
  559. let serverId = data.serverId;
  560. let orderId = data.exts;
  561. let out_trade_no = data.orderId;
  562. logger.info("pay callback params:", { url: ctx.href, params: data });
  563. const orderInfo = (await Order.getOrder(orderId))[0];
  564. if (!orderInfo) {
  565. logger.info(`订单${orderId}不存在`);
  566. ret.msg = `订单${orderId}不存在`;
  567. return ret;
  568. }
  569. if (orderInfo.status == 2) {
  570. logger.info(`订单${orderId}已经重复发货`);
  571. ret.code = 1;
  572. ret.msg = `订单${orderId}已经重复发货`;
  573. return ret;
  574. }
  575. //签名参数
  576. let signData = Object.keys(data)
  577. .sort()
  578. .filter((key) => key !== "sign");
  579. let signStr = signData
  580. .map((key) => {
  581. return `${key}=${data[key]}`;
  582. })
  583. .join("&");
  584. signStr += "&key=" + AppSecretSanLi;
  585. let newSign = CryptoJS.MD5(signStr).toString();
  586. console.log("signStr:", signStr);
  587. console.log("newSign:", newSign);
  588. if (sign != newSign) {
  589. logger.info(`签名错误: 签名串 ${signStr} newSign ${newSign} sign ${sign}`);
  590. ret.msg = `签名错误`;
  591. return ret;
  592. }
  593. let url = await getServerList(serverId, "default");
  594. if (!url) {
  595. logger.info(`区服id错误: serverId ${serverId}`);
  596. ret.msg = `区服id错误: serverId ${serverId}`;
  597. return ret;
  598. }
  599. //发货
  600. // 使用 Msg 类的 connect 方法连接到 WebSocket 服务器
  601. let sendMsg = new Msg();
  602. sendMsg.connect(url, Account);
  603. logger.info(`订单${orderId} ${url}`);
  604. let orgMemId = data.userId;
  605. let orgOderId = data.exts;
  606. let orgProductId = orderInfo.productId;
  607. let orgExt = data.exts;
  608. let orgProductPrice = data.orderAmount / 100;
  609. const accountInfo = (await User.checkAccountIsExist(orgMemId))[0];
  610. // 在适当的时机,调用 CG_ASK_LOGIN 方法
  611. let params = `{"account":"${orgMemId}","order":"${orgOderId}","id":${orgProductId},"channel_id":${accountInfo.channel_id},"cnt":100,"money":${orgProductPrice}}`;
  612. return new Promise((resolve) => {
  613. setTimeout(async () => {
  614. console.log("这个消息将在3秒后打印出来");
  615. const send_res = sendMsg.CG_ASK_LOGIN(
  616. Account,
  617. 0,
  618. "",
  619. "cn",
  620. "CN",
  621. ctx.request.ip,
  622. params,
  623. serverId
  624. );
  625. if (!send_res) {
  626. resolve(ret);
  627. return;
  628. }
  629. const update_time = formatDate(new Date());
  630. const res = await Order.updateOrderStats(
  631. orderId,
  632. 2,
  633. out_trade_no,
  634. update_time,
  635. orderInfo.uid
  636. );
  637. if (res.affectedRows <= 0) {
  638. logger.info(`订单${orderId} 发货失败`);
  639. ret.msg = "发货失败";
  640. resolve(ret);
  641. return;
  642. }
  643. ret.code = 200;
  644. ret.msg = "发货成功";
  645. resolve(ret);
  646. }, 1000);
  647. });
  648. };
  649. const testGoogleCallPay = async (ctx) => {
  650. let ret = {
  651. code: 0,
  652. msg: "消费失败",
  653. };
  654. let data = ctx.request.body;
  655. logger.info("pay callback params:", { url: ctx.href, params: data });
  656. const redisClient = ctx.redis.client;
  657. let access_token = await redisClient.get("access_token");
  658. if (!access_token) {
  659. console.log("请求api获取token");
  660. const apiData = {
  661. grant_type: "refresh_token",
  662. client_id: ClientId,
  663. client_secret: ClientSecret,
  664. refresh_token: RefreshToken,
  665. };
  666. const response = await axios.post(
  667. "https://accounts.google.com/o/oauth2/token",
  668. apiData,
  669. {
  670. headers: {
  671. "Content-Type": "application/x-www-form-urlencoded",
  672. },
  673. }
  674. );
  675. logger.info("token params:", { data: response.data, params: apiData });
  676. if (!response.data.access_token) {
  677. return ret;
  678. }
  679. access_token = response.data.access_token;
  680. await redisClient.set("access_token", response.data.access_token);
  681. await redisClient.expire("access_token", 1800);
  682. }
  683. if (!access_token) {
  684. return ret;
  685. }
  686. let googleToken = data.purchaseToken;
  687. let product_id = data.orderId;
  688. const productId = ProductId + product_id;
  689. let apiUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}?access_token=${access_token}`;
  690. let maxRetries = 5;
  691. let currentRetry = 0;
  692. let isCheck = false;
  693. // 使用 while 循环进行重试
  694. while (currentRetry < maxRetries) {
  695. try {
  696. // // 尝试执行的操作
  697. const googleRes = await axios.get(apiUrl, {
  698. headers: {
  699. "Content-Type": "application/x-www-form-urlencoded",
  700. },
  701. });
  702. console.log(googleRes.data);
  703. // 如果操作成功,退出循环
  704. if (googleRes.data.purchaseState == 0) {
  705. isCheck = true;
  706. break;
  707. }
  708. } catch (error) {
  709. // 如果操作失败,记录错误并继续尝试
  710. console.log(error);
  711. }
  712. currentRetry++;
  713. }
  714. if (!isCheck) {
  715. return ret;
  716. }
  717. return new Promise(async (resolve) => {
  718. let acknowledgeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:acknowledge?access_token=${access_token}`;
  719. console.log(acknowledgeUrl);
  720. const acknowledgeRes = await axios.post(
  721. acknowledgeUrl,
  722. {
  723. developerPayload: "",
  724. },
  725. {
  726. headers: {
  727. "Content-Type": "application/json",
  728. },
  729. }
  730. );
  731. let consumeUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${PackageName}/purchases/products/${productId}/tokens/${googleToken}:consume?access_token=${access_token}`;
  732. const consumeRes = await axios.post(
  733. consumeUrl,
  734. {
  735. developerPayload: "",
  736. },
  737. {
  738. headers: {
  739. "Content-Type": "application/json",
  740. },
  741. }
  742. );
  743. ret.code = 1;
  744. ret.msg = "发货成功";
  745. resolve(ret);
  746. });
  747. };
  748. function splitString(input: string, separator: string): string[] {
  749. return input.split(separator);
  750. }
  751. function extractIPAddresses(text: string): string[] {
  752. // 正则表达式匹配IP地址
  753. const ipRegex = /(?:(?:\d{1,3}\.){3}\d{1,3})/g;
  754. // 使用正则表达式执行匹配并返回结果
  755. return text.match(ipRegex) || [];
  756. }
  757. //验证账号
  758. const checkUserToken = async (ctx) => {
  759. let ret = {
  760. code: 0,
  761. data: {
  762. ip: "",
  763. },
  764. msg: "请求失败",
  765. };
  766. let ip = ctx.request.ip;
  767. if (ip.startsWith("::ffff:")) {
  768. ip = ip.substring("::ffff:".length);
  769. }
  770. if (ip == "127.0.0.1") {
  771. const forwardedIps = ctx.get("X-Forwarded-For")?.split(",");
  772. const clientIP = forwardedIps ? forwardedIps[0].trim() : null;
  773. // 若 X-Forwarded-For 不存在,尝试 X-Real-IP
  774. ip = clientIP || ctx.get("X-Real-IP") || ctx.ip;
  775. }
  776. let {
  777. uid,
  778. channel_id,
  779. device_no,
  780. reg_device,
  781. device_type,
  782. device_model,
  783. device_version,
  784. system_version,
  785. } = ctx.request.body;
  786. const create_time = formatDate(new Date());
  787. const accountInfo = (await User.checkAccountIsExist(uid))[0];
  788. let accountRes = null;
  789. let res = null;
  790. if (!accountInfo) {
  791. accountRes = await User.createAccount(
  792. uid,
  793. channel_id,
  794. ip,
  795. device_no,
  796. reg_device,
  797. create_time
  798. );
  799. if (accountRes.affectedRows <= 0) {
  800. ret.msg = "添加账户失败";
  801. return ret;
  802. }
  803. }
  804. res = await User.logAccountLogin(
  805. uid,
  806. ip,
  807. device_type,
  808. device_no,
  809. device_model,
  810. device_version,
  811. system_version,
  812. create_time
  813. );
  814. if (res.affectedRows <= 0) {
  815. ret.msg = "添加日志失败";
  816. return ret;
  817. }
  818. ret.code = 1;
  819. ret.msg = "请求成功";
  820. ret.data.ip = ip;
  821. return ret;
  822. };
  823. class ApiController {
  824. async createOrder(ctx) {
  825. let { uid, level, amount, role_id, role_name, product_id, server_id } =
  826. ctx.request.body;
  827. logger.info("create params:", { params: ctx.request.body });
  828. if (
  829. !product_id ||
  830. !server_id ||
  831. !role_name ||
  832. !role_id ||
  833. !amount ||
  834. !uid
  835. ) {
  836. ctx.body = { code: -1, message: "参数错误,创建订单失败!!", data: "" };
  837. return;
  838. }
  839. const data = ctx.request.body;
  840. const sign = data.sign;
  841. //签名参数
  842. let signData = Object.keys(data)
  843. .sort()
  844. .filter((key) => key !== "sign");
  845. let signStr = signData.map((key) => `${data[key]}`).join("");
  846. signStr += "q97tvr1yqpum8y2h7d0mhvosffrplwlm";
  847. let newSign = CryptoJS.MD5(signStr).toString();
  848. console.log("signStr:", signStr);
  849. console.log("newSign:", newSign);
  850. if (sign != newSign) {
  851. logger.info(
  852. `签名错误: 签名串 ${signStr} newSign ${newSign} sign ${sign}`
  853. );
  854. ctx.body = {
  855. code: -1,
  856. message: "签名错误,创建订单失败!!",
  857. data: "",
  858. };
  859. return;
  860. }
  861. if (amount < 1) {
  862. ctx.body = {
  863. code: -1,
  864. message: "金额错误,创建订单失败!!",
  865. data: "",
  866. };
  867. return;
  868. }
  869. const orderId = generateOrderNumber(); // 生成一个长度为8的订单号
  870. const create_time = formatDate(new Date());
  871. const res = await Order.createOrder(
  872. orderId,
  873. uid,
  874. level,
  875. amount,
  876. role_id,
  877. role_name,
  878. product_id,
  879. server_id,
  880. create_time
  881. );
  882. if (res.affectedRows > 0) {
  883. ctx.body = { code: 0, message: "创建订单成功", data: orderId };
  884. } else {
  885. ctx.body = { code: -1, message: "创建订单失败", data: "" };
  886. }
  887. logger.info("创建订单返回结果:", { params: ctx.body });
  888. }
  889. async checkUserToken(ctx) {
  890. let data = ctx.request.body;
  891. let platform = "360"; // 默认360
  892. if (ctx.query.platform) {
  893. platform = ctx.query.platform;
  894. }
  895. if (data.platform) {
  896. platform = data.platform;
  897. }
  898. switch (platform) {
  899. case "360":
  900. var result = await checkUserToken(ctx);
  901. ctx.body = result;
  902. break;
  903. case "th":
  904. var result = await checkUserToken(ctx);
  905. ctx.body = result;
  906. break;
  907. case "sanli":
  908. var result = await checkUserToken(ctx);
  909. ctx.body = result;
  910. break;
  911. case "quick":
  912. var result = await checkUserToken(ctx);
  913. ctx.body = result;
  914. break;
  915. default:
  916. ctx.body = {
  917. code: 0,
  918. msg: "渠道错误",
  919. };
  920. }
  921. }
  922. //quick登陆
  923. async quickUserLogin(ctx) {
  924. //sdk参数
  925. let productCode = "40202114039243214268433998697181";
  926. let data = ctx.request.body;
  927. let uid = data.uid;
  928. let token = data.token;
  929. let reqUrl =
  930. "http://checkuser.quickapi.net/v2/checkUserInfo?token=" +
  931. token +
  932. "&uid=" +
  933. uid +
  934. "product_code=" +
  935. productCode;
  936. logger.info("quick登陆验证请求", { params: data, url: reqUrl });
  937. const res = await axios.get(reqUrl);
  938. logger.info("quick req", { res: res.data });
  939. if (res.data == "1") {
  940. ctx.body = {
  941. code: 200,
  942. msg: "success",
  943. };
  944. } else {
  945. ctx.body = {
  946. code: 0,
  947. msg: "fail",
  948. };
  949. }
  950. }
  951. async sanLiUserLogin(ctx) {
  952. let ret = {
  953. code: 0,
  954. msg: "fail",
  955. };
  956. let data = ctx.request.body;
  957. const sign = data.sign;
  958. //签名参数
  959. let signData = Object.keys(data)
  960. .sort()
  961. .filter((key) => key !== "sign");
  962. let signStr = signData
  963. .map((key) => {
  964. return `${key}=${data[key]}`;
  965. })
  966. .join("&");
  967. signStr += "&key=" + AppSecretSanLi;
  968. let newSign = CryptoJS.MD5(signStr).toString();
  969. console.log("signStr:", signStr);
  970. console.log("newSign:", newSign);
  971. if (sign != newSign) {
  972. logger.info(
  973. `签名错误: 签名串 ${signStr} newSign ${newSign} sign ${sign}`
  974. );
  975. ret.msg = `签名错误`;
  976. ctx.body = ret;
  977. } else {
  978. ret.code = 1;
  979. ret.msg = "success";
  980. ctx.body = ret;
  981. }
  982. }
  983. async callPay(ctx) {
  984. console.log(234234234);
  985. let data = ctx.request.body;
  986. let platform = "360"; // 默认360
  987. if (ctx.query.platform) {
  988. platform = ctx.query.platform;
  989. }
  990. if (data.platform) {
  991. platform = data.platform;
  992. }
  993. switch (platform) {
  994. case "google":
  995. var result = await googleCallPay(ctx);
  996. console.log("发货结果", result);
  997. ctx.body = result;
  998. break;
  999. case "apple":
  1000. var result = await appleCallPay(ctx);
  1001. console.log("发货结果", result);
  1002. ctx.body = result;
  1003. break;
  1004. case "360":
  1005. var result = await CallPay360(ctx);
  1006. console.log("发货结果", result);
  1007. ctx.body = result;
  1008. break;
  1009. case "sanli":
  1010. var result = await CallPaySanLi(ctx);
  1011. console.log("发货结果", result);
  1012. ctx.body = result;
  1013. break;
  1014. // case 'testGoogle':
  1015. // var result = await testGoogleCallPay(ctx)
  1016. // console.log('发货结果', result)
  1017. // ctx.body = result
  1018. // break;
  1019. case "quick":
  1020. var result = await CallPayQuick(ctx);
  1021. console.log("发货结果", result);
  1022. if ((result as any).code == 1) {
  1023. ctx.body = "SUCCESS";
  1024. } else {
  1025. ctx.body = "Fail";
  1026. }
  1027. break;
  1028. default:
  1029. ctx.body = {
  1030. code: 0,
  1031. msg: "渠道错误",
  1032. };
  1033. }
  1034. }
  1035. async getServerList(ctx) {
  1036. let tag = ctx.query.tag || "default";
  1037. const servers = await Server.getServerList(tag);
  1038. let data = [];
  1039. let ip = ctx.request.ip;
  1040. if (ip.startsWith("::ffff:")) {
  1041. ip = ip.substring("::ffff:".length);
  1042. }
  1043. logger.info("区服接口", { ip: ctx.request.ip });
  1044. if (servers.length > 0) {
  1045. servers.forEach(function (element) {
  1046. let status = element.status;
  1047. if ((status == 0 || status == 3) && element.white_list) {
  1048. const list = element.white_list.split(",");
  1049. if (list.length > 0) {
  1050. if (list.includes(ip)) {
  1051. status = 1;
  1052. }
  1053. }
  1054. }
  1055. data.push({
  1056. id: element.id,
  1057. name: element.name,
  1058. ip: element.ip,
  1059. port: element.port,
  1060. tips: element.tips,
  1061. status: status,
  1062. });
  1063. });
  1064. }
  1065. ctx.body = data;
  1066. }
  1067. async getAllServerList(ctx) {
  1068. let tag = ctx.query.tag || "default";
  1069. let ip = ctx.request.ip;
  1070. if (ip.startsWith("::ffff:")) {
  1071. ip = ip.substring("::ffff:".length);
  1072. }
  1073. logger.info("getAllServerList 区服接口", { ip: ctx.request.ip });
  1074. const servers = await Server.getAllServerList(tag, ip);
  1075. ctx.body = servers;
  1076. }
  1077. async enterServer(ctx) {
  1078. let ret = {
  1079. code: 0,
  1080. msg: "请求失败",
  1081. };
  1082. let { uid, server_id } = ctx.request.body;
  1083. let url = await getServerList(server_id, "default");
  1084. if (!url) {
  1085. ctx.body = {
  1086. code: -1,
  1087. message: `区服id错误: serverId ${server_id}`,
  1088. data: "",
  1089. };
  1090. return;
  1091. }
  1092. logger.info("create params:", { params: ctx.request.body });
  1093. if (!server_id || !uid) {
  1094. ctx.body = { code: -1, message: "参数错误!!", data: "" };
  1095. return;
  1096. }
  1097. const create_time = formatDate(new Date());
  1098. const serverInfo = (await Server.checkEnterServerByUid(uid, server_id))[0];
  1099. let res = null;
  1100. if (serverInfo) {
  1101. res = await Server.updateEnterServer(serverInfo.id, create_time);
  1102. } else {
  1103. res = await Server.enterServer(uid, server_id, create_time);
  1104. }
  1105. if (res.affectedRows > 0) {
  1106. ctx.body = { code: 0, message: "请求成功", data: "" };
  1107. } else {
  1108. ctx.body = { code: -1, message: "请求失败", data: "" };
  1109. }
  1110. }
  1111. async getLastServerList(ctx) {
  1112. let { uid } = ctx.request.body;
  1113. let tag = "default";
  1114. let data = [];
  1115. let isNewAccount = 1;
  1116. let enterServerList = await Server.getEnterServerListByUid(uid);
  1117. let ip = ctx.request.ip;
  1118. if (ip.startsWith("::ffff:")) {
  1119. ip = ip.substring("::ffff:".length);
  1120. }
  1121. logger.info("getLastServerList 区服接口", { ip: ctx.request.ip });
  1122. if (enterServerList.length > 0) {
  1123. isNewAccount = 0;
  1124. // const servers = (await Server.getServerList(tag, 1))
  1125. const servers = await Server.getAllServerList(tag, ip);
  1126. enterServerList.forEach(function (element) {
  1127. data.push({
  1128. channel: "Thailand", //渠道固定
  1129. minSid: 1, //最小服务器
  1130. maxSid: servers.length, //最大服务器 这里会控制 服务器列表显示的数量
  1131. isNewAccount: isNewAccount, //1为新号 会弹出用户协议
  1132. //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
  1133. sid: element.server_id || 1,
  1134. id: element.server_id || 1,
  1135. name: element.name || "1区",
  1136. tips: element.tips || "",
  1137. server: element.ip ? `ws://${element.ip}:${element.port}` : "",
  1138. status: element.status || 0,
  1139. });
  1140. });
  1141. } else {
  1142. // const servers = (await Server.getServerList(tag, 1))
  1143. const servers = await Server.getAllServerList(tag, ip);
  1144. if (servers.length > 0) {
  1145. const serverInfo = servers[servers.length - 1];
  1146. data.push({
  1147. channel: "Thailand", //渠道固定
  1148. minSid: 1, //最小服务器
  1149. maxSid: servers.length, //最大服务器 这里会控制 服务器列表显示的数量
  1150. isNewAccount: isNewAccount, //1为新号 会弹出用户协议
  1151. //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
  1152. sid: serverInfo.id || 1,
  1153. id: serverInfo.id || 1,
  1154. name: serverInfo.name || "1区",
  1155. tips: serverInfo.tips || "",
  1156. server: serverInfo.ip
  1157. ? `ws://${serverInfo.ip}:${serverInfo.port}`
  1158. : "",
  1159. status: serverInfo.status || 0,
  1160. });
  1161. } else {
  1162. data.push({
  1163. channel: "Thailand", //渠道固定
  1164. minSid: 1, //最小服务器
  1165. maxSid: 10, //最大服务器 这里会控制 服务器列表显示的数量
  1166. isNewAccount: isNewAccount, //1为新号 会弹出用户协议
  1167. //以下是最近登陆的服务器 (不可为空 如果没有参数可以填最后一个区)
  1168. sid: 1,
  1169. id: 1,
  1170. name: "1区",
  1171. tips: "",
  1172. server: "",
  1173. status: 0,
  1174. });
  1175. }
  1176. }
  1177. ctx.body = data;
  1178. }
  1179. async getNotice(ctx) {
  1180. let data = ctx.request.body;
  1181. let platform = "th";
  1182. if (ctx.query.platform) {
  1183. platform = ctx.query.platform;
  1184. }
  1185. let content = "";
  1186. let content_wh = "";
  1187. const system = await System.getSystemConfig();
  1188. if (system) {
  1189. system.forEach((element) => {
  1190. if (element.key == "content") {
  1191. content = element.value;
  1192. }
  1193. if (element.key == "content_wh") {
  1194. content_wh = element.value;
  1195. }
  1196. });
  1197. }
  1198. let notice_data = [
  1199. {
  1200. status: 1,
  1201. content: content,
  1202. content_wh: content_wh,
  1203. },
  1204. ];
  1205. if (notice_data[0].content == "") {
  1206. switch (platform) {
  1207. case "th":
  1208. notice_data = th_notice;
  1209. break;
  1210. case "360":
  1211. notice_data = notice;
  1212. break;
  1213. case "xky":
  1214. notice_data = xky_notice;
  1215. break;
  1216. default:
  1217. notice_data = notice;
  1218. }
  1219. }
  1220. ctx.body = notice_data;
  1221. }
  1222. // 维护服务器,踢掉所有玩家
  1223. async maintenance(ctx) {
  1224. let data = ctx.request.body;
  1225. let url = await getServerList(data.serverId, "default");
  1226. if (!url) {
  1227. ctx.body = {
  1228. code: 1,
  1229. msg: `区服id错误: serverId ${data.serverId}`,
  1230. };
  1231. return;
  1232. }
  1233. let param = JSON.stringify({
  1234. type: "kickAllUser",
  1235. });
  1236. // Msg.connect(url, Account);
  1237. let sendMsg = new Msg();
  1238. sendMsg.connect(url, Account);
  1239. new Promise((resolve) => {
  1240. setTimeout(async () => {
  1241. sendMsg.CG_TEST_PROTO("test", param);
  1242. }, 1000);
  1243. });
  1244. ctx.body = {
  1245. code: 0,
  1246. msg: "success",
  1247. };
  1248. }
  1249. async maintenanceAll(ctx) {
  1250. let data = ctx.request.body;
  1251. const servers = await Server.getServerList("default");
  1252. const serversId = [];
  1253. servers.forEach(function (element) {
  1254. let url = "ws://" + element.ip + ":" + element.port;
  1255. if (!url) {
  1256. ctx.body = {
  1257. code: 1,
  1258. msg: `区服id错误: serverId ${element.id}`,
  1259. };
  1260. return;
  1261. }
  1262. serversId.push(element.id);
  1263. let param = JSON.stringify({
  1264. type: "kickAllUser",
  1265. });
  1266. // Msg.connect(url, Account);
  1267. let sendMsg = new Msg();
  1268. sendMsg.connect(url, Account);
  1269. new Promise((resolve) => {
  1270. setTimeout(async () => {
  1271. sendMsg.CG_TEST_PROTO("test", param);
  1272. }, 1000);
  1273. });
  1274. });
  1275. const res = await Server.updateServerStatus(serversId, 3);
  1276. ctx.body = {
  1277. code: 0,
  1278. msg: "success",
  1279. };
  1280. }
  1281. async sendMail(ctx) {
  1282. let data = ctx.request.body;
  1283. let url = await getServerList(data.serverId, "default");
  1284. if (!url) {
  1285. ctx.body = {
  1286. code: 1,
  1287. msg: `区服id错误: serverId ${data.serverId}`,
  1288. };
  1289. return;
  1290. }
  1291. let param = JSON.stringify({
  1292. type: "sendMail",
  1293. mail: JSON.stringify({
  1294. uuid: data.uuid,
  1295. title: data.title,
  1296. content: data.content,
  1297. items: JSON.parse(data.items),
  1298. expire: data.expire,
  1299. }),
  1300. });
  1301. // Msg.connect(url, Account);
  1302. let sendMsg = new Msg();
  1303. sendMsg.connect(url, Account);
  1304. new Promise((resolve) => {
  1305. setTimeout(async () => {
  1306. sendMsg.CG_TEST_PROTO("test", param);
  1307. }, 1000);
  1308. });
  1309. ctx.body = {
  1310. code: 0,
  1311. msg: "success",
  1312. };
  1313. }
  1314. async sendAllMail(ctx) {
  1315. let data = ctx.request.body;
  1316. if (!data.server_list || data.server_list.length === 0) {
  1317. ctx.body = { code: -1, message: "区服不能为空", data: "" };
  1318. return;
  1319. }
  1320. logger.info("sendAllMail 接口请求 data:", { data: data });
  1321. const server_list = data.server_list;
  1322. const servers = await Server.getServerList("default");
  1323. const filteredServer = servers.filter((item) =>
  1324. server_list.includes(item.id)
  1325. );
  1326. filteredServer.forEach(function (element) {
  1327. let url = "ws://" + element.ip + ":" + element.port;
  1328. if (!url) {
  1329. ctx.body = {
  1330. code: 1,
  1331. msg: `区服id错误: serverId ${element.server_id}`,
  1332. };
  1333. return;
  1334. }
  1335. let param = JSON.stringify({
  1336. type: "sendAllMail",
  1337. mail: JSON.stringify({
  1338. title: data.title,
  1339. content: data.content,
  1340. items: JSON.parse(data.items),
  1341. expire: data.expire,
  1342. }),
  1343. });
  1344. let sendMsg = new Msg();
  1345. sendMsg.connect(url, Account);
  1346. new Promise((resolve) => {
  1347. setTimeout(async () => {
  1348. sendMsg.CG_TEST_PROTO("test", param);
  1349. }, 1000);
  1350. });
  1351. });
  1352. ctx.body = {
  1353. code: 0,
  1354. msg: "success",
  1355. };
  1356. }
  1357. async useCDKV2(ctx) {
  1358. let body = ctx.request.body;
  1359. let data = {
  1360. code: body.code,
  1361. userId: body.account,
  1362. };
  1363. if (body.uuid) {
  1364. data.userId = body.uuid;
  1365. }
  1366. const accountInfo = (await User.checkAccountIsExist(body.account))[0];
  1367. logger.info("api cdk 接口请求 data:", { data: data });
  1368. let serverUrl = await getServerList(body.serverId, "default");
  1369. let err = "";
  1370. if (!serverUrl) {
  1371. ctx.body = {
  1372. code: 1,
  1373. msg: `区服id错误: serverId ${body.serverId}`,
  1374. };
  1375. return;
  1376. }
  1377. let port = 8004;
  1378. // let host = extractIPAddresses(serverUrl)[0]
  1379. let host = "127.0.0.1";
  1380. let url = "http://" + host + ":" + port + "/api/giftCode/exchange";
  1381. try {
  1382. const response = await axios.post(url, data, {
  1383. headers: {
  1384. "Content-Type": "application/json",
  1385. },
  1386. });
  1387. let param: string = "";
  1388. logger.info("api cdk 接口返回 response:", { data: response.data });
  1389. if (response.data.code != 200) {
  1390. // 可能是固定码 ,游戏再去检测一下
  1391. param = JSON.stringify({
  1392. code: data.code,
  1393. type: "UseFixCDK",
  1394. channel_id: accountInfo.channel_id,
  1395. });
  1396. } else {
  1397. const result = splitString(response.data.data, ";");
  1398. // 重构itemList
  1399. let itemList = Array();
  1400. for (let i = 0; i < result.length; i++) {
  1401. let elem = splitString(result[i], ":");
  1402. let output0 = parseInt(elem[0], 10);
  1403. let output1 = parseInt(elem[1], 10);
  1404. itemList.push([output0, output1]);
  1405. }
  1406. param = JSON.stringify({
  1407. type: "UseCDKV2",
  1408. itemList: itemList,
  1409. channel_id: accountInfo.channel_id,
  1410. });
  1411. }
  1412. let sendMsg = new Msg();
  1413. sendMsg.connect(serverUrl, Account);
  1414. logger.info("api cdk 发送服务器 param:", { param: param });
  1415. new Promise((resolve) => {
  1416. setTimeout(async () => {
  1417. sendMsg.CG_TEST_PROTO(body.account, param, body.serverId);
  1418. }, 1000);
  1419. });
  1420. } catch (error) {
  1421. console.log(error);
  1422. }
  1423. ctx.body = {
  1424. code: 0,
  1425. msg: "success",
  1426. };
  1427. }
  1428. }
  1429. module.exports = new ApiController();