TkController.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. using molilian.core;
  2. using dodohold.core;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Org.BouncyCastle.Ocsp;
  5. using System.Text.Json;
  6. using System.Runtime.InteropServices;
  7. using System.Net;
  8. using System.Security.Cryptography;
  9. using Microsoft.AspNetCore.Authentication;
  10. using TencentCloud.Ecm.V20190719.Models;
  11. using COSXML.Network;
  12. using System.Linq;
  13. using static dodohold.core.ZTOExpress.CreateOrderArgs;
  14. namespace molilian.api.Controllers
  15. {
  16. [ApiController]
  17. [Route("[controller]/[action]")]
  18. public class TkController : ControllerBase
  19. {
  20. protected IHttpContextAccessor _accessor;
  21. public TkController(IHttpContextAccessor accessor)
  22. {
  23. _accessor = accessor;
  24. }
  25. /// <summary>
  26. /// oppo调用
  27. /// </summary>
  28. /// <param name="s">正文</param>
  29. /// <param name="c">渠道。tb/jd</param>
  30. /// <param name="a">分配的客户端账号</param>
  31. /// <param name="t">11位时间戳</param>
  32. /// <param name="sign">签名</param>
  33. /// <param name="ip">客户的IP</param>
  34. /// <param name="oaid">客户的唯一ID</param>
  35. /// <returns></returns>
  36. [HttpPost]
  37. public async Task<ActionResult> unionParse([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  38. {
  39. //正文
  40. var content = form.Read("s", string.Empty);
  41. var channel = form.Read("c", string.Empty);
  42. var ip = form.Read("ip", string.Empty);
  43. var oaid = form.Read("oaid", string.Empty);
  44. //验证签名
  45. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  46. {
  47. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  48. }
  49. DateTime time1 = t.Convert2Datetime();
  50. if (time1 < DateTime.Now.AddMinutes(-10))
  51. {
  52. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  53. }
  54. var account = ApiAccountCore.GetOne(a);
  55. if (account == null)
  56. {
  57. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  58. }
  59. string app_sign = $"{account.api_secret}@{t}".MD5();
  60. if (sign != app_sign)
  61. {
  62. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  63. }
  64. return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid);
  65. }
  66. [HttpPost]
  67. public async Task<ActionResult> unsafeParse([FromBody] JsonElement form)
  68. {
  69. var content = form.Read("s", string.Empty);
  70. var channel = form.Read("c", string.Empty);
  71. var ip = form.Read("ip", string.Empty);
  72. var oaid = form.Read("oaid", string.Empty);
  73. int accountid = form.Read("aid", 0);
  74. #if DEBUG
  75. ip = "127.0.0.1";
  76. oaid = "test-oaid";
  77. #endif
  78. return await UnionParseCore.UnionParseAsync(content, channel, ip, oaid, accountid);
  79. }
  80. //[HttpGet]
  81. //public async Task<ActionResult> testParse()
  82. //{
  83. // var ip = "127.0.0.1";
  84. // var oaid = "test-oaid";
  85. // var list = new DBContext.Table("tk_parse_logs")
  86. // .Where("success=1", null)
  87. // .Order("ID DESC")
  88. // .Limit(1000)
  89. // .Select<TkDataDTO>();
  90. // int success_total = 0, error_total = 0;
  91. // foreach (var item in list)
  92. // {
  93. // var result = UnionParseCore.testTaobaoParseAsync(item.rawContent, ip, oaid);
  94. // if (result.success)
  95. // {
  96. // success_total++;
  97. // }
  98. // else
  99. // {
  100. // Console.Write(result);
  101. // }
  102. // }
  103. // var list2 = new DBContext.Table("tk_parse_logs")
  104. // .Where("success=0", null)
  105. // .Order("ID DESC")
  106. // .Limit(100)
  107. // .Select<TkDataDTO>();
  108. // foreach (var item in list2)
  109. // {
  110. // var result = UnionParseCore.testTaobaoParseAsync(item.rawContent, ip, oaid);
  111. // if (result.success)
  112. // {
  113. // Console.Write(result);
  114. // }
  115. // else
  116. // {
  117. // error_total++;
  118. // }
  119. // }
  120. // return new APIResult(new { success_total, error_total });
  121. //}
  122. [HttpPost]
  123. public async Task<ActionResult> unionCoupon([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  124. {
  125. //正文
  126. var content = form.Read("s", string.Empty);
  127. var channel = form.Read("c", string.Empty);
  128. var ip = form.Read("ip", string.Empty);
  129. var oaid = form.Read("oaid", string.Empty);
  130. //验证签名
  131. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  132. {
  133. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  134. }
  135. DateTime time1 = t.Convert2Datetime();
  136. if (time1 < DateTime.Now.AddMinutes(-10))
  137. {
  138. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  139. }
  140. var account = ApiAccountCore.GetOne(a);
  141. if (account == null)
  142. {
  143. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  144. }
  145. string app_sign = $"{account.api_secret}@{t}".MD5();
  146. if (sign != app_sign)
  147. {
  148. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  149. }
  150. return await UnionCouponCore.UnionCouponAsync(content, channel, ip, oaid);
  151. }
  152. [HttpPost]
  153. public async Task<ActionResult> unsafeCoupon([FromBody] JsonElement form)
  154. {
  155. var content = form.Read("s", string.Empty);
  156. var channel = form.Read("c", string.Empty);
  157. var ip = form.Read("ip", string.Empty);
  158. var oaid = form.Read("oaid", string.Empty);
  159. #if DEBUG
  160. ip = "127.0.0.1";
  161. oaid = "test-oaid";
  162. #endif
  163. return await UnionCouponCore.UnionCouponAsync(content, channel, ip, oaid);
  164. }
  165. /// <summary>
  166. /// 第三方调用
  167. /// </summary>
  168. /// <param name="s"></param>
  169. /// <param name="s2"></param>
  170. /// <returns></returns>
  171. [HttpGet]
  172. public async Task<ActionResult> parse(string s, string s2 = "", string ip = "", string oaid = "")
  173. {
  174. AlimamaPlus alimama = null;
  175. ip = AlimamaPlus.OppoDecode(ip);
  176. oaid = AlimamaPlus.OppoDecode(oaid);
  177. var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
  178. string body = "";
  179. string content = s.UrlDecode();
  180. string content2 = s2.UrlDecode();
  181. string account_name = string.Empty;
  182. result.rawContent = content;
  183. result.rawContent2 = content2;
  184. try
  185. {
  186. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  187. {
  188. result.success = false;
  189. result.message = "放弃转链";
  190. result.reason = reason;
  191. _ = TkLogCore.LogAsync(result);
  192. return new APIResult(new
  193. {
  194. result.success,
  195. result.message,
  196. result.content,
  197. result.couponAmount,
  198. result.taoToken,
  199. result.shortLinkurl,
  200. result.deeplink_url,
  201. });
  202. }
  203. var account = TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  204. if (account == null)
  205. {
  206. result.success = false;
  207. result.message = "放弃转链";
  208. result.reason = "没有匹配账号";
  209. _ = TkLogCore.LogAsync(result);
  210. return new APIResult(new
  211. {
  212. result.success,
  213. result.message,
  214. result.content,
  215. result.couponAmount,
  216. result.taoToken,
  217. result.shortLinkurl,
  218. result.deeplink_url,
  219. });
  220. }
  221. result.accountId = account.id;
  222. account_name = account.name;
  223. alimama = new AlimamaPlus(account);
  224. if (alimama.ShouldIgnoreOtherAff(s2))
  225. {
  226. result.success = false;
  227. result.message = "放弃转链";
  228. result.reason = "其他推广链接";
  229. _ = TkLogCore.LogAsync(result);
  230. return new APIResult(new
  231. {
  232. result.success,
  233. result.message,
  234. result.content,
  235. result.couponAmount,
  236. result.taoToken,
  237. result.shortLinkurl,
  238. result.deeplink_url,
  239. });
  240. }
  241. result = await alimama.UnionParseAsync(content, result);
  242. }
  243. catch (Exception ex)
  244. {
  245. if (ex.Message.Contains("was canceled"))
  246. {
  247. result.success = false;
  248. result.message = "放弃转链";
  249. result.reason = "请求超时";
  250. }
  251. else
  252. {
  253. //new LoggerLibrary("api_error", "parse")
  254. //.Info(s, s2)
  255. //.Info($"【taobao】{account_name}", body)
  256. //.Info(ex.Message, ex.StackTrace)
  257. //.SaveAsync();
  258. NotifyCore.Notify(new NifyMessage
  259. {
  260. message = $"【转链接口异常】{account_name}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  261. priority = NifyMessagePriority.high,
  262. tags = ["red_circle"]
  263. });
  264. result.success = false;
  265. result.message = "放弃转链";
  266. result.reason = "转链接口异常";
  267. }
  268. }
  269. _ = TkLogCore.LogAsync(result, alimama);
  270. return new APIResult(new
  271. {
  272. result.success,
  273. result.message,
  274. result.content,
  275. result.couponAmount,
  276. result.taoToken,
  277. result.shortLinkurl,
  278. result.deeplink_url,
  279. });
  280. }
  281. [HttpGet]
  282. public ActionResult parse2(string s, string s2 = "", string ip = "", string oaid = "")
  283. {
  284. AlimamaPlus alimama = null;
  285. ip = AlimamaPlus.OppoDecode(ip);
  286. oaid = AlimamaPlus.OppoDecode(oaid);
  287. var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
  288. string body = "";
  289. string content = s.UrlDecode();
  290. string content2 = s2.UrlDecode();
  291. string account_name = string.Empty;
  292. result.rawContent = content;
  293. result.rawContent2 = content2;
  294. try
  295. {
  296. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  297. {
  298. result.success = false;
  299. result.message = "放弃转链";
  300. result.reason = reason;
  301. _ = TkLogCore.LogAsync(result);
  302. return new APIResult(new
  303. {
  304. result.success,
  305. result.message,
  306. result.content,
  307. result.couponAmount,
  308. result.taoToken,
  309. result.shortLinkurl,
  310. result.deeplink_url,
  311. });
  312. }
  313. var account = TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  314. if (account == null)
  315. {
  316. result.success = false;
  317. result.message = "放弃转链";
  318. result.reason = "没有匹配账号";
  319. _ = TkLogCore.LogAsync(result);
  320. return new APIResult(new
  321. {
  322. result.success,
  323. result.message,
  324. result.content,
  325. result.couponAmount,
  326. result.taoToken,
  327. result.shortLinkurl,
  328. result.deeplink_url,
  329. });
  330. }
  331. account_name = account.name;
  332. alimama = new AlimamaPlus(account);
  333. if (alimama.ShouldIgnoreOtherAff(s2))
  334. {
  335. result.success = false;
  336. result.message = "放弃转链";
  337. result.reason = "其他推广链接";
  338. _ = TkLogCore.LogAsync(result);
  339. return new APIResult(new
  340. {
  341. result.success,
  342. result.message,
  343. result.content,
  344. result.couponAmount,
  345. result.taoToken,
  346. result.shortLinkurl,
  347. result.deeplink_url,
  348. });
  349. }
  350. alimama.UnionParse(content, ref result);
  351. //result.ip = ip;
  352. //result.oaid = oaid;
  353. }
  354. catch (Exception ex)
  355. {
  356. _ = new LoggerLibrary("api_error", "parse")
  357. .Info(s, s2)
  358. .Info($"【taobao】{account_name}", body)
  359. .Info(ex.Message, ex.StackTrace)
  360. .SaveAsync();
  361. NotifyCore.Notify(new NifyMessage
  362. {
  363. message = $"【转链接口异常】{account_name}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  364. priority = NifyMessagePriority.high,
  365. tags = ["red_circle"]
  366. });
  367. result.success = false;
  368. result.message = "放弃转链";
  369. result.reason = "转链接口异常";
  370. }
  371. _ = TkLogCore.LogAsync(result, alimama);
  372. return new APIResult(new
  373. {
  374. result.success,
  375. result.message,
  376. result.content,
  377. result.couponAmount,
  378. result.taoToken,
  379. result.shortLinkurl,
  380. result.deeplink_url,
  381. });
  382. }
  383. [HttpGet]
  384. public ActionResult jd_parse(string s, string s2 = "", string ip = "", string oaid = "")
  385. {
  386. var result = JdUnionPlus.GetFormattedObject(s, ip, oaid);
  387. string body = "";
  388. string content = s.UrlDecode();
  389. string content2 = s2.UrlDecode();
  390. try
  391. {
  392. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  393. {
  394. result.success = false;
  395. result.message = "放弃转链";
  396. result.reason = reason;
  397. result.rawContent = content;
  398. result.rawContent2 = content2;
  399. _ = TkLogCore.LogAsync(result);
  400. return new APIResult(result);
  401. }
  402. var api = DataokeCore.GetOne();
  403. if (api == null)
  404. {
  405. result.success = false;
  406. result.message = "放弃转链";
  407. result.reason = "没有匹配账号";
  408. result.rawContent = content;
  409. result.rawContent2 = content2;
  410. _ = TkLogCore.LogAsync(result);
  411. return new APIResult(result);
  412. }
  413. var account = JdPoolCore.GetOne();
  414. if (account == null)
  415. {
  416. result.success = false;
  417. result.message = "放弃转链";
  418. result.reason = "没有匹配账号";
  419. result.rawContent = content;
  420. result.rawContent2 = content2;
  421. _ = TkLogCore.LogAsync(result);
  422. return new APIResult(result);
  423. }
  424. result = DataokeCore.JdParse(result, api, account, content);
  425. }
  426. catch (Exception ex)
  427. {
  428. _ = new LoggerLibrary("api_error")
  429. .Info(s, s2)
  430. .Info("【jd】", body)
  431. .Info(ex.Message, ex.StackTrace)
  432. .SaveAsync();
  433. NotifyCore.Notify(new NifyMessage
  434. {
  435. message = $"【转链接口异常】\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  436. priority = NifyMessagePriority.high,
  437. tags = ["red_circle"]
  438. });
  439. result.success = false;
  440. result.message = "放弃转链";
  441. result.reason = "转链接口异常";
  442. }
  443. result.rawContent = content;
  444. result.rawContent2 = content2;
  445. _ = TkLogCore.LogAsync(result);
  446. return new APIResult(new
  447. {
  448. result.success,
  449. result.message,
  450. result.shortLinkurl,
  451. result.itemId,
  452. result.itemName,
  453. result.deeplink_url,
  454. });
  455. }
  456. //[HttpGet]
  457. //public Task<ActionResult> parse3(string s, string s2, string ip = "", string oaid = "")
  458. //{
  459. // var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
  460. // string body = "";
  461. // string content = s.UrlDecode();
  462. // string content2 = s2.UrlDecode();
  463. // try
  464. // {
  465. // if (AlimamaPlus.ShouldIgnoreRequest("", ""))
  466. // {
  467. // result.success = false;
  468. // result.message = "放弃转链";
  469. // }
  470. // else
  471. // {
  472. // var account = VeapiPoolCore.GetOne();
  473. // if (account == null)
  474. // {
  475. // result.success = false;
  476. // result.message = "内部错误(500)";
  477. // }
  478. // else
  479. // {
  480. // var core = new VeapiPlus(account.name, account.key, account.sessionKey);
  481. // result = core.UnionParse(content);
  482. // }
  483. // }
  484. // }
  485. // catch (Exception ex)
  486. // {
  487. // NotifyCore.Notify(new NifyMessage
  488. // {
  489. // message = $"【转链接口异常】\n{body}",
  490. // priority = NifyMessagePriority.high,
  491. // tags = ["red_circle"]
  492. // });
  493. // result.success = false;
  494. // result.message = "转链接口异常";
  495. // }
  496. // _ = TkLogCore.Log(content, content2, result);
  497. // return Task.FromResult<ActionResult>(new APIResult(result));
  498. //}
  499. [HttpGet("{ignorePercentage}")]
  500. public ActionResult set_ignore(int ignorePercentage = 0)
  501. {
  502. TkConfigCore.Update(ignorePercentage);
  503. return new APIResult(new { success = true, message = "ok" });
  504. }
  505. [HttpGet("{ignorePercentage}")]
  506. public ActionResult set_jd_ignore(int ignorePercentage = 0)
  507. {
  508. TkConfigCore.JdUpdate(ignorePercentage);
  509. return new APIResult(new { success = true, message = "ok" });
  510. }
  511. [HttpGet]
  512. public async Task<ActionResult> Reload()
  513. {
  514. await EndPointCore.NotifyReload();
  515. return new APIResult(new
  516. {
  517. success = true,
  518. message = "ok",
  519. });
  520. }
  521. [HttpGet]
  522. public async Task<ActionResult> dplist([FromQuery] string query = "", [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  523. {
  524. #if DEBUG
  525. #else
  526. //验证签名
  527. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  528. {
  529. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  530. }
  531. DateTime time1 = t.Convert2Datetime();
  532. if (time1 < DateTime.Now.AddMinutes(-10))
  533. {
  534. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  535. }
  536. var account = ApiAccountCore.GetOne(a);
  537. if (account == null)
  538. {
  539. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  540. }
  541. string app_sign = $"{account.api_secret}@{t}".MD5();
  542. if (sign != app_sign)
  543. {
  544. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  545. }
  546. if (string.IsNullOrEmpty(query))
  547. {
  548. return new APIResult(new { success = false, message = "查询条件不能为空" });
  549. }
  550. #endif
  551. string filter = $"batchId=@query";
  552. var account_list = TkPoolCore.List();
  553. List<int> account_ids = [];
  554. if (account_list.Any())
  555. {
  556. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  557. filter += $" AND accountId IN @account_ids";
  558. }
  559. string orderBy = "paid_time ASC";
  560. var data = new DBContext.Table("tk_order_tracking")
  561. .Where(filter, new { query, account_ids })
  562. .Order(orderBy)
  563. .Select<TkOrderTrackingDTO>();
  564. List<object> list = [];
  565. foreach (var item in data)
  566. {
  567. list.Add(new { url = item.deeplinkUrl, count = item.click_num, time = item.exp_time });
  568. }
  569. var clientIp = _accessor.HttpContext.GetUserIp();
  570. LoggerLibrary log = new LoggerLibrary("api", "dplist");
  571. log.Info($"{clientIp}\t{query}\tcount:{list.Count}");
  572. var ids = data.Select(e => e.Id).ToArray();
  573. log.Info(string.Join(',', ids));
  574. _ = log.SaveAsync();
  575. return new APIResult(new
  576. {
  577. success = true,
  578. message = list.Count == 0 ? "none" : "ok",
  579. count = list.Count,
  580. data = list,
  581. });
  582. }
  583. [HttpGet]
  584. public async Task<ActionResult> unsafeParseDpList([FromQuery] string query = "")
  585. {
  586. string filter = $"batchId=@query";
  587. var account_list = TkPoolCore.List();
  588. List<int> account_ids = [];
  589. if (account_list.Any())
  590. {
  591. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  592. filter += $" AND accountId IN @account_ids";
  593. }
  594. string orderBy = "paid_time ASC";
  595. var data = new DBContext.Table("tk_order_tracking")
  596. .Where(filter, new { query, account_ids })
  597. .Order(orderBy)
  598. .Select<TkOrderTrackingDTO>();
  599. List<object> list = [];
  600. foreach (var item in data)
  601. {
  602. list.Add(new { url = item.deeplinkUrl, count = item.click_num, time = item.exp_time });
  603. }
  604. var clientIp = _accessor.HttpContext.GetUserIp();
  605. LoggerLibrary log = new LoggerLibrary("api", "unsafeParseDpList");
  606. log.Info($"{clientIp}\t{query}\tcount:{list.Count}");
  607. var ids = data.Select(e => e.Id).ToArray();
  608. log.Info(string.Join(',', ids));
  609. _ = log.SaveAsync();
  610. return new APIResult(new
  611. {
  612. success = true,
  613. message = list.Count == 0 ? "none" : "ok",
  614. count = list.Count,
  615. data = list,
  616. });
  617. }
  618. }
  619. }