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. result.accountName = account.company;
  223. account_name = account.name;
  224. alimama = new AlimamaPlus(account);
  225. if (alimama.ShouldIgnoreOtherAff(s2))
  226. {
  227. result.success = false;
  228. result.message = "放弃转链";
  229. result.reason = "其他推广链接";
  230. _ = TkLogCore.LogAsync(result);
  231. return new APIResult(new
  232. {
  233. result.success,
  234. result.message,
  235. result.content,
  236. result.couponAmount,
  237. result.taoToken,
  238. result.shortLinkurl,
  239. result.deeplink_url,
  240. });
  241. }
  242. result = await alimama.UnionParseAsync(content, result);
  243. }
  244. catch (Exception ex)
  245. {
  246. if (ex.Message.Contains("was canceled"))
  247. {
  248. result.success = false;
  249. result.message = "放弃转链";
  250. result.reason = "请求超时";
  251. }
  252. else
  253. {
  254. //new LoggerLibrary("api_error", "parse")
  255. //.Info(s, s2)
  256. //.Info($"【taobao】{account_name}", body)
  257. //.Info(ex.Message, ex.StackTrace)
  258. //.SaveAsync();
  259. NotifyCore.Notify(new NifyMessage
  260. {
  261. message = $"【转链接口异常】{result.accountName}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  262. priority = NifyMessagePriority.high,
  263. tags = ["red_circle"]
  264. });
  265. result.success = false;
  266. result.message = "放弃转链";
  267. result.reason = "转链接口异常";
  268. }
  269. }
  270. _ = TkLogCore.LogAsync(result, alimama);
  271. return new APIResult(new
  272. {
  273. result.success,
  274. result.message,
  275. result.content,
  276. result.couponAmount,
  277. result.taoToken,
  278. result.shortLinkurl,
  279. result.deeplink_url,
  280. });
  281. }
  282. [HttpGet]
  283. public ActionResult parse2(string s, string s2 = "", string ip = "", string oaid = "")
  284. {
  285. AlimamaPlus alimama = null;
  286. ip = AlimamaPlus.OppoDecode(ip);
  287. oaid = AlimamaPlus.OppoDecode(oaid);
  288. var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
  289. string body = "";
  290. string content = s.UrlDecode();
  291. string content2 = s2.UrlDecode();
  292. string account_name = string.Empty;
  293. result.rawContent = content;
  294. result.rawContent2 = content2;
  295. try
  296. {
  297. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  298. {
  299. result.success = false;
  300. result.message = "放弃转链";
  301. result.reason = reason;
  302. _ = TkLogCore.LogAsync(result);
  303. return new APIResult(new
  304. {
  305. result.success,
  306. result.message,
  307. result.content,
  308. result.couponAmount,
  309. result.taoToken,
  310. result.shortLinkurl,
  311. result.deeplink_url,
  312. });
  313. }
  314. var account = TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  315. if (account == null)
  316. {
  317. result.success = false;
  318. result.message = "放弃转链";
  319. result.reason = "没有匹配账号";
  320. _ = TkLogCore.LogAsync(result);
  321. return new APIResult(new
  322. {
  323. result.success,
  324. result.message,
  325. result.content,
  326. result.couponAmount,
  327. result.taoToken,
  328. result.shortLinkurl,
  329. result.deeplink_url,
  330. });
  331. }
  332. account_name = account.name;
  333. alimama = new AlimamaPlus(account);
  334. if (alimama.ShouldIgnoreOtherAff(s2))
  335. {
  336. result.success = false;
  337. result.message = "放弃转链";
  338. result.reason = "其他推广链接";
  339. _ = TkLogCore.LogAsync(result);
  340. return new APIResult(new
  341. {
  342. result.success,
  343. result.message,
  344. result.content,
  345. result.couponAmount,
  346. result.taoToken,
  347. result.shortLinkurl,
  348. result.deeplink_url,
  349. });
  350. }
  351. alimama.UnionParse(content, ref result);
  352. //result.ip = ip;
  353. //result.oaid = oaid;
  354. }
  355. catch (Exception ex)
  356. {
  357. _ = new LoggerLibrary("api_error", "parse")
  358. .Info(s, s2)
  359. .Info($"【taobao】{account_name}", body)
  360. .Info(ex.Message, ex.StackTrace)
  361. .SaveAsync();
  362. NotifyCore.Notify(new NifyMessage
  363. {
  364. message = $"【转链接口异常】{account_name}\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  365. priority = NifyMessagePriority.high,
  366. tags = ["red_circle"]
  367. });
  368. result.success = false;
  369. result.message = "放弃转链";
  370. result.reason = "转链接口异常";
  371. }
  372. _ = TkLogCore.LogAsync(result, alimama);
  373. return new APIResult(new
  374. {
  375. result.success,
  376. result.message,
  377. result.content,
  378. result.couponAmount,
  379. result.taoToken,
  380. result.shortLinkurl,
  381. result.deeplink_url,
  382. });
  383. }
  384. [HttpGet]
  385. public ActionResult jd_parse(string s, string s2 = "", string ip = "", string oaid = "")
  386. {
  387. var result = JdUnionPlus.GetFormattedObject(s, ip, oaid);
  388. string body = "";
  389. string content = s.UrlDecode();
  390. string content2 = s2.UrlDecode();
  391. try
  392. {
  393. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  394. {
  395. result.success = false;
  396. result.message = "放弃转链";
  397. result.reason = reason;
  398. result.rawContent = content;
  399. result.rawContent2 = content2;
  400. _ = TkLogCore.LogAsync(result);
  401. return new APIResult(result);
  402. }
  403. var api = DataokeCore.GetOne();
  404. if (api == null)
  405. {
  406. result.success = false;
  407. result.message = "放弃转链";
  408. result.reason = "没有匹配账号";
  409. result.rawContent = content;
  410. result.rawContent2 = content2;
  411. _ = TkLogCore.LogAsync(result);
  412. return new APIResult(result);
  413. }
  414. var account = JdPoolCore.GetOne();
  415. if (account == null)
  416. {
  417. result.success = false;
  418. result.message = "放弃转链";
  419. result.reason = "没有匹配账号";
  420. result.rawContent = content;
  421. result.rawContent2 = content2;
  422. _ = TkLogCore.LogAsync(result);
  423. return new APIResult(result);
  424. }
  425. result = DataokeCore.JdParse(result, api, account, content);
  426. }
  427. catch (Exception ex)
  428. {
  429. _ = new LoggerLibrary("api_error")
  430. .Info(s, s2)
  431. .Info("【jd】", body)
  432. .Info(ex.Message, ex.StackTrace)
  433. .SaveAsync();
  434. NotifyCore.Notify(new NifyMessage
  435. {
  436. message = $"【转链接口异常】\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  437. priority = NifyMessagePriority.high,
  438. tags = ["red_circle"]
  439. });
  440. result.success = false;
  441. result.message = "放弃转链";
  442. result.reason = "转链接口异常";
  443. }
  444. result.rawContent = content;
  445. result.rawContent2 = content2;
  446. _ = TkLogCore.LogAsync(result);
  447. return new APIResult(new
  448. {
  449. result.success,
  450. result.message,
  451. result.shortLinkurl,
  452. result.itemId,
  453. result.itemName,
  454. result.deeplink_url,
  455. });
  456. }
  457. //[HttpGet]
  458. //public Task<ActionResult> parse3(string s, string s2, string ip = "", string oaid = "")
  459. //{
  460. // var result = AlimamaPlus.GetFormattedObject(s, ip, oaid);
  461. // string body = "";
  462. // string content = s.UrlDecode();
  463. // string content2 = s2.UrlDecode();
  464. // try
  465. // {
  466. // if (AlimamaPlus.ShouldIgnoreRequest("", ""))
  467. // {
  468. // result.success = false;
  469. // result.message = "放弃转链";
  470. // }
  471. // else
  472. // {
  473. // var account = VeapiPoolCore.GetOne();
  474. // if (account == null)
  475. // {
  476. // result.success = false;
  477. // result.message = "内部错误(500)";
  478. // }
  479. // else
  480. // {
  481. // var core = new VeapiPlus(account.name, account.key, account.sessionKey);
  482. // result = core.UnionParse(content);
  483. // }
  484. // }
  485. // }
  486. // catch (Exception ex)
  487. // {
  488. // NotifyCore.Notify(new NifyMessage
  489. // {
  490. // message = $"【转链接口异常】\n{body}",
  491. // priority = NifyMessagePriority.high,
  492. // tags = ["red_circle"]
  493. // });
  494. // result.success = false;
  495. // result.message = "转链接口异常";
  496. // }
  497. // _ = TkLogCore.Log(content, content2, result);
  498. // return Task.FromResult<ActionResult>(new APIResult(result));
  499. //}
  500. [HttpGet("{ignorePercentage}")]
  501. public ActionResult set_ignore(int ignorePercentage = 0)
  502. {
  503. TkConfigCore.Update(ignorePercentage);
  504. return new APIResult(new { success = true, message = "ok" });
  505. }
  506. [HttpGet("{ignorePercentage}")]
  507. public ActionResult set_jd_ignore(int ignorePercentage = 0)
  508. {
  509. TkConfigCore.JdUpdate(ignorePercentage);
  510. return new APIResult(new { success = true, message = "ok" });
  511. }
  512. [HttpGet]
  513. public async Task<ActionResult> Reload()
  514. {
  515. await EndPointCore.NotifyReload();
  516. return new APIResult(new
  517. {
  518. success = true,
  519. message = "ok",
  520. });
  521. }
  522. [HttpGet]
  523. public async Task<ActionResult> dplist([FromQuery] string query = "", [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  524. {
  525. #if DEBUG
  526. #else
  527. //验证签名
  528. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  529. {
  530. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  531. }
  532. DateTime time1 = t.Convert2Datetime();
  533. if (time1 < DateTime.Now.AddMinutes(-10))
  534. {
  535. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  536. }
  537. var account = ApiAccountCore.GetOne(a);
  538. if (account == null)
  539. {
  540. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  541. }
  542. string app_sign = $"{account.api_secret}@{t}".MD5();
  543. if (sign != app_sign)
  544. {
  545. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  546. }
  547. if (string.IsNullOrEmpty(query))
  548. {
  549. return new APIResult(new { success = false, message = "查询条件不能为空" });
  550. }
  551. #endif
  552. string filter = $"batchId=@query";
  553. var account_list = TkPoolCore.List();
  554. List<int> account_ids = [];
  555. if (account_list.Any())
  556. {
  557. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  558. filter += $" AND accountId IN @account_ids";
  559. }
  560. string orderBy = "paid_time ASC";
  561. var data = new DBContext.Table("tk_order_tracking")
  562. .Where(filter, new { query, account_ids })
  563. .Order(orderBy)
  564. .Select<TkOrderTrackingDTO>();
  565. List<object> list = [];
  566. foreach (var item in data)
  567. {
  568. list.Add(new { url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
  569. }
  570. var clientIp = _accessor.HttpContext.GetUserIp();
  571. LoggerLibrary log = new LoggerLibrary("api", "dplist");
  572. log.Info($"{clientIp}\t{query}\tcount:{list.Count}");
  573. var ids = data.Select(e => e.Id).ToArray();
  574. log.Info(string.Join(',', ids));
  575. _ = log.SaveAsync();
  576. return new APIResult(new
  577. {
  578. success = true,
  579. message = list.Count == 0 ? "none" : "ok",
  580. count = list.Count,
  581. data = list,
  582. });
  583. }
  584. [HttpGet]
  585. public async Task<ActionResult> unsafeParseDpList([FromQuery] string query = "")
  586. {
  587. string filter = $"batchId=@query";
  588. var account_list = TkPoolCore.List();
  589. List<int> account_ids = [];
  590. if (account_list.Any())
  591. {
  592. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  593. filter += $" AND accountId IN @account_ids";
  594. }
  595. string orderBy = "paid_time ASC";
  596. var data = new DBContext.Table("tk_order_tracking")
  597. .Where(filter, new { query, account_ids })
  598. .Order(orderBy)
  599. .Select<TkOrderTrackingDTO>();
  600. List<object> list = [];
  601. foreach (var item in data)
  602. {
  603. list.Add(new { url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
  604. }
  605. var clientIp = _accessor.HttpContext.GetUserIp();
  606. LoggerLibrary log = new LoggerLibrary("api", "unsafeParseDpList");
  607. log.Info($"{clientIp}\t{query}\tcount:{list.Count}");
  608. var ids = data.Select(e => e.Id).ToArray();
  609. log.Info(string.Join(',', ids));
  610. _ = log.SaveAsync();
  611. return new APIResult(new
  612. {
  613. success = true,
  614. message = list.Count == 0 ? "none" : "ok",
  615. count = list.Count,
  616. data = list,
  617. });
  618. }
  619. }
  620. }