TkController.cs 25 KB

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