TkController.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. using molilian.core;
  2. using dodohold.core;
  3. using Microsoft.AspNetCore.Mvc;
  4. using System.Text.Json;
  5. using TencentCloud.Ecm.V20190719.Models;
  6. using YunhuiKit;
  7. namespace molilian.api.Controllers
  8. {
  9. [ApiController]
  10. [Route("[controller]/[action]")]
  11. public class TkController : ControllerBase
  12. {
  13. protected IHttpContextAccessor _accessor;
  14. public TkController(IHttpContextAccessor accessor)
  15. {
  16. _accessor = accessor;
  17. }
  18. /// <summary>
  19. /// oppo调用
  20. /// </summary>
  21. /// <param name="s">正文</param>
  22. /// <param name="c">渠道。tb/jd</param>
  23. /// <param name="a">分配的客户端账号</param>
  24. /// <param name="t">11位时间戳</param>
  25. /// <param name="sign">签名</param>
  26. /// <param name="ip">客户的IP</param>
  27. /// <param name="oaid">客户的唯一ID</param>
  28. /// <returns></returns>
  29. [HttpPost]
  30. public async Task<ActionResult> unionParse([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  31. {
  32. //正文
  33. var content = form.Read("s", string.Empty);
  34. var channel = form.Read("c", string.Empty);
  35. var ip = form.Read("ip", string.Empty);
  36. var oaid = form.Read("oaid", string.Empty);
  37. var type = form.Read("type", string.Empty);
  38. var clickId = form.Read("clickId", string.Empty);
  39. var commerceType = form.Read<int>("commerceType", 0);
  40. var riskStrategy = form.Read("riskStrategy", string.Empty);
  41. var launchScene = form.Read<int>("launchScene", -1);
  42. var special_text = form.Read<int>("special_text", -1);
  43. var query_text = form.Read("query_text", 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 = await ApiAccountCore.GetOneAsync(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. var request = new UnionParseRequest
  65. {
  66. Content = content,
  67. Channel = channel,
  68. CommerceType = commerceType,
  69. Ip = ip,
  70. Oaid = oaid,
  71. RiskStrategy = riskStrategy,
  72. LaunchScene = launchScene,
  73. AccountId = 0,
  74. SpecialText = special_text,
  75. QueryText = query_text,
  76. ClickId = clickId,
  77. Type = type
  78. };
  79. return await UnionParseCore.UnionParseAsync(request);
  80. }
  81. [HttpPost]
  82. public async Task<ActionResult> unsafeParse([FromBody] JsonElement form)
  83. {
  84. var content = form.Read("s", string.Empty);
  85. var channel = form.Read("c", string.Empty);
  86. var ip = form.Read("ip", string.Empty);
  87. var oaid = form.Read("oaid", string.Empty);
  88. var clickId = form.Read("clickId", string.Empty);
  89. var type = form.Read("type", string.Empty);
  90. int accountid = form.Read("aid", 0);
  91. var commerceType = form.Read<int>("commerceType", 0);
  92. var riskStrategy = form.Read("riskStrategy", string.Empty);
  93. var launchScene = form.Read<int>("launchScene", -1);
  94. var special_text = form.Read<int>("special_text", -1);
  95. var query_text = form.Read("query_text", string.Empty);
  96. #if DEBUG
  97. //ip = "127.0.0.1";
  98. //oaid = "test-oaid";
  99. #endif
  100. var request = new UnionParseRequest
  101. {
  102. Content = content,
  103. Channel = channel,
  104. CommerceType = commerceType,
  105. Ip = ip,
  106. Oaid = oaid,
  107. RiskStrategy = riskStrategy,
  108. LaunchScene = launchScene,
  109. AccountId = accountid,
  110. SpecialText = special_text,
  111. QueryText = query_text,
  112. ClickId = clickId,
  113. Type = type
  114. };
  115. return await UnionParseCore.UnionParseAsync(request);
  116. }
  117. [HttpPost]
  118. public async Task<ActionResult> unsafeBatchParse([FromBody] JsonElement form)
  119. {
  120. var content = form.PathReadArray("s[]", string.Empty);
  121. var channel = form.Read("c", string.Empty);
  122. var ip = form.Read("ip", string.Empty);
  123. var oaid = form.Read("oaid", string.Empty);
  124. var clickId = form.Read("clickId", string.Empty);
  125. var type = form.Read("type", string.Empty);
  126. int accountid = form.Read("aid", 0);
  127. int count = form.Read("count", 0);
  128. var commerceType = form.Read<int>("commerceType", 0);
  129. //入参参数。brw-浏览器,qapp-快应用
  130. var riskStrategy = form.Read("riskStrategy", string.Empty);
  131. var launchScene = form.Read<int>("launchScene", -1);
  132. var special_text = form.Read<int>("special_text", -1);
  133. var query_text = form.Read("query_text", string.Empty);
  134. #if DEBUG
  135. //ip = "127.0.0.1";
  136. //oaid = "test-oaid";
  137. #endif
  138. for (int i = 0; i < count; i++)
  139. {
  140. var request = new UnionParseRequest
  141. {
  142. Content = content[i],
  143. Channel = channel,
  144. CommerceType = commerceType,
  145. Ip = ip,
  146. Oaid = oaid,
  147. RiskStrategy = riskStrategy,
  148. LaunchScene = launchScene,
  149. AccountId = accountid,
  150. SpecialText = special_text,
  151. QueryText = query_text,
  152. ClickId = clickId,
  153. Type = type
  154. };
  155. _ = await UnionParseCore.UnionParseAsync(request);
  156. }
  157. return new APIResult(new { msg = "ok" });
  158. }
  159. [HttpPost]
  160. public async Task<ActionResult> unionCoupon([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  161. {
  162. //正文
  163. var content = form.Read("s", string.Empty);
  164. var dplink = form.Read("dp", string.Empty);
  165. var channel = form.Read("c", string.Empty);
  166. var ip = form.Read("ip", string.Empty);
  167. var oaid = form.Read("oaid", string.Empty);
  168. var clickId = form.Read("clickId", string.Empty);
  169. var style = form.Read("style", string.Empty);
  170. //验证签名
  171. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  172. {
  173. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  174. }
  175. DateTime time1 = t.Convert2Datetime();
  176. if (time1 < DateTime.Now.AddMinutes(-10))
  177. {
  178. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  179. }
  180. var account = await ApiAccountCore.GetOneAsync(a);
  181. if (account == null)
  182. {
  183. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  184. }
  185. string app_sign = $"{account.api_secret}@{t}".MD5();
  186. if (sign != app_sign)
  187. {
  188. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  189. }
  190. return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, style, ip, oaid, clickId);
  191. }
  192. [HttpPost]
  193. public async Task<ActionResult> unsafeCoupon([FromBody] JsonElement form)
  194. {
  195. var content = form.Read("s", string.Empty);
  196. var dplink = form.Read("dp", string.Empty);
  197. var channel = form.Read("c", string.Empty);
  198. var ip = form.Read("ip", string.Empty);
  199. var oaid = form.Read("oaid", string.Empty);
  200. var style = form.Read("style", string.Empty);
  201. var clickId = form.Read("clickId", string.Empty);
  202. #if DEBUG
  203. ip = "127.0.0.1";
  204. oaid = "test-oaid";
  205. #endif
  206. return await UnionCouponCore.UnionCouponAsync(content, dplink, channel, style, ip, oaid, clickId);
  207. }
  208. [HttpGet]
  209. public async Task<ActionResult> jd_parse(string s, string s2 = "", string ip = "", string oaid = "")
  210. {
  211. UnionParseRequest request = new()
  212. {
  213. Content = s,
  214. Ip = ip,
  215. Oaid = oaid
  216. };
  217. var result = JdUnionPlus.GetFormattedObject(request);
  218. string body = "";
  219. string content = s.UrlDecode();
  220. string content2 = s2.UrlDecode();
  221. try
  222. {
  223. if (AlimamaPlus.ShouldIgnoreRequest(ip, oaid, string.Empty, 0, out string reason))
  224. {
  225. result.success = false;
  226. result.message = "放弃转链";
  227. result.reason = reason;
  228. result.rawContent = content;
  229. result.rawContent2 = content2;
  230. _ = TkLogCore.LogAsync(result);
  231. return new APIResult(result);
  232. }
  233. var api = DataokeCore.GetOne();
  234. if (api == null)
  235. {
  236. result.success = false;
  237. result.message = "放弃转链";
  238. result.reason = "没有匹配账号";
  239. result.rawContent = content;
  240. result.rawContent2 = content2;
  241. _ = TkLogCore.LogAsync(result);
  242. return new APIResult(result);
  243. }
  244. var account = await JdPoolCore.GetOneAsync();
  245. if (account == null)
  246. {
  247. result.success = false;
  248. result.message = "放弃转链";
  249. result.reason = "没有匹配账号";
  250. result.rawContent = content;
  251. result.rawContent2 = content2;
  252. _ = TkLogCore.LogAsync(result);
  253. return new APIResult(result);
  254. }
  255. result = DataokeCore.JdParse(result, api, account, content);
  256. }
  257. catch (Exception ex)
  258. {
  259. _ = new LoggerLibrary("api_error")
  260. .Info(s, s2)
  261. .Info("【jd】", body)
  262. .Info(ex.Message, ex.StackTrace)
  263. .SaveAsync();
  264. NotifyCore.Notify(new NifyMessage
  265. {
  266. message = $"【转链接口异常】\n{content}\n{content2}\n{body}\n\n{ex.Message}\n{ex.StackTrace}",
  267. priority = NifyMessagePriority.high,
  268. tags = ["red_circle"]
  269. });
  270. result.success = false;
  271. result.message = "放弃转链";
  272. result.reason = "转链接口异常";
  273. }
  274. result.rawContent = content;
  275. result.rawContent2 = content2;
  276. _ = TkLogCore.LogAsync(result);
  277. return new APIResult(new
  278. {
  279. result.success,
  280. result.message,
  281. result.shortLinkurl,
  282. result.itemId,
  283. result.itemName,
  284. result.deeplink_url,
  285. });
  286. }
  287. [HttpGet]
  288. public async Task<ActionResult> Reload()
  289. {
  290. await EndPointCore.NotifyReload();
  291. return new APIResult(new
  292. {
  293. success = true,
  294. message = "ok",
  295. });
  296. }
  297. [HttpGet]
  298. public async Task<ActionResult> dplist([FromQuery] string query = "", [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  299. {
  300. var clientIp = _accessor.HttpContext.GetUserIp();
  301. //验证签名
  302. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  303. {
  304. _ = new LoggerLibrary("api", "dplist_error")
  305. .Info($"{clientIp}\t{query}")
  306. .Info($"{a}\t{sign}\t{t}")
  307. .Info("验证错误")
  308. .SaveAsync();
  309. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  310. }
  311. DateTime time1 = t.Convert2Datetime();
  312. if (time1 < DateTime.Now.AddMinutes(-10))
  313. {
  314. _ = new LoggerLibrary("api", "dplist_error")
  315. .Info($"{clientIp}\t{query}")
  316. .Info($"{a}\t{sign}\t{t}")
  317. .Info("验证错误2")
  318. .SaveAsync();
  319. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  320. }
  321. var account = await ApiAccountCore.GetOneAsync(a);
  322. if (account == null)
  323. {
  324. _ = new LoggerLibrary("api", "dplist_error")
  325. .Info($"{clientIp}\t{query}")
  326. .Info($"{a}\t{sign}\t{t}")
  327. .Info("验证错误3")
  328. .SaveAsync();
  329. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  330. }
  331. string app_sign = $"{account.api_secret}@{t}".MD5();
  332. if (sign != app_sign)
  333. {
  334. _ = new LoggerLibrary("api", "dplist_error")
  335. .Info($"{clientIp}\t{query}")
  336. .Info($"{a}\t{sign}\t{t}")
  337. .Info("验证错误4")
  338. .SaveAsync();
  339. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  340. }
  341. if (string.IsNullOrEmpty(query))
  342. {
  343. _ = new LoggerLibrary("api", "dplist_error")
  344. .Info($"{clientIp}\t{query}")
  345. .Info($"{a}\t{sign}\t{t}")
  346. .Info("查询条件不能为空")
  347. .SaveAsync();
  348. return new APIResult(new { success = false, message = "查询条件不能为空" });
  349. }
  350. int[] report_account_ids = account.report_account_ids.TryToArray<int>(',');
  351. int[] report_exclude_account_ids = account.report_exclude_account_ids.TryToArray<int>(',');
  352. string filter = $"batchId=@query";
  353. var account_list = await TkPoolCore.ListAsync();
  354. List<int> account_ids = [];
  355. if (account_list.Any())
  356. {
  357. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  358. if (report_account_ids.Length > 0)
  359. {
  360. account_ids = account_ids.Intersect(report_account_ids).ToList();
  361. }
  362. if (report_exclude_account_ids.Length > 0)
  363. {
  364. account_ids = account_ids.Except(report_exclude_account_ids).ToList();
  365. }
  366. filter += $" AND accountId IN @account_ids";
  367. }
  368. string orderBy = "paid_time ASC";
  369. var data = new DBContext.Table("tk_order_tracking")
  370. .Where(filter, new { query, account_ids })
  371. .Order(orderBy)
  372. .Select<TkOrderTrackingDTO>();
  373. //fake_click_link_type
  374. List<object> list = [];
  375. foreach (var item in data)
  376. {
  377. list.Add(new { pid = item.accountId, url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
  378. }
  379. var ids = data.Select(e => e.Id).ToArray();
  380. _ = new LoggerLibrary("api", "dplist")
  381. .Info($"{clientIp}\t{query}\tcount:{list.Count}")
  382. .Info(string.Join(',', ids))
  383. .SaveAsync();
  384. var update = new DBContext.Table("tk_order_tracking")
  385. .Add("last_pull_time", DateTime.Now)
  386. .Add("last_pull_account", account.name)
  387. .Add("clicked_num:", "clicked_num+1")
  388. .Where("id IN @ids", new { ids })
  389. .Update();
  390. return new APIResult(new
  391. {
  392. success = true,
  393. message = list.Count == 0 ? "none" : "ok",
  394. count = list.Count,
  395. data = list,
  396. });
  397. }
  398. [HttpGet]
  399. public async Task<ActionResult> unsafeParseDpList([FromQuery] string a = "", [FromQuery] string query = "")
  400. {
  401. if (string.IsNullOrEmpty(a))
  402. {
  403. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  404. }
  405. var account = await ApiAccountCore.GetOneAsync(a);
  406. if (account == null || !account.enable_report)
  407. {
  408. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  409. }
  410. if (string.IsNullOrEmpty(query))
  411. {
  412. return new APIResult(new { success = false, message = "查询条件不能为空" });
  413. }
  414. int[] report_account_ids = account.report_account_ids.TryToArray<int>(',');
  415. int[] report_exclude_account_ids = account.report_exclude_account_ids.TryToArray<int>(',');
  416. string filter = $"batchId=@query";
  417. var account_list = await TkPoolCore.ListAsync();
  418. List<int> account_ids = [];
  419. if (account_list.Any())
  420. {
  421. account_ids = account_list.Where(e => e.enable_fake_click).Select(e => e.id).ToList();
  422. if (report_account_ids.Length > 0)
  423. {
  424. account_ids = account_ids.Intersect(report_account_ids).ToList();
  425. }
  426. if (report_exclude_account_ids.Length > 0)
  427. {
  428. account_ids = account_ids.Except(report_exclude_account_ids).ToList();
  429. }
  430. filter += $" AND accountId IN @account_ids";
  431. }
  432. string orderBy = "paid_time ASC";
  433. var data = new DBContext.Table("tk_order_tracking")
  434. .Where(filter, new { query, account_ids })
  435. .Order(orderBy)
  436. .Select<TkOrderTrackingDTO>();
  437. List<object> list = [];
  438. foreach (var item in data)
  439. {
  440. list.Add(new { pid = item.accountId, url = item.deeplinkUrl, item.shortLinkUrl, count = item.click_num, time = item.exp_time });
  441. }
  442. var clientIp = _accessor.HttpContext.GetUserIp();
  443. LoggerLibrary log = new LoggerLibrary("api", "unsafeParseDpList");
  444. log.Info($"{clientIp}\t{query}\tcount:{list.Count}");
  445. var ids = data.Select(e => e.Id).ToArray();
  446. log.Info(string.Join(',', ids));
  447. _ = log.SaveAsync();
  448. return new APIResult(new
  449. {
  450. success = true,
  451. message = list.Count == 0 ? "none" : "ok",
  452. count = list.Count,
  453. data = list,
  454. });
  455. }
  456. [HttpPost]
  457. public async Task<ActionResult> dataReport([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  458. {
  459. bool debug = form.Read("debug", false);
  460. var clientIp = _accessor.HttpContext.GetUserIp();
  461. var log = new LoggerLibrary("ApiReportCore", "dataReport");
  462. log.Info(clientIp);
  463. //验证签名
  464. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  465. {
  466. _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误")
  467. .Info(form.GetRawText())
  468. .SaveAsync();
  469. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  470. }
  471. DateTime time1 = t.Convert2Datetime();
  472. if (time1 < DateTime.Now.AddMinutes(-10))
  473. {
  474. _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误2")
  475. .Info(form.GetRawText())
  476. .SaveAsync();
  477. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  478. }
  479. var account = await ApiAccountCore.GetOneAsync(a);
  480. if (account == null)
  481. {
  482. _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\t", $"message:验证错误3")
  483. .Info(form.GetRawText())
  484. .SaveAsync();
  485. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  486. }
  487. string app_sign = $"{account.api_secret}@{t}".MD5();
  488. if (sign != app_sign)
  489. {
  490. _ = log.Info($"a:{a}\tt:{t}\tsign:{sign}\tapp_sign:{app_sign}", $"message:验证错误4")
  491. .Info(form.GetRawText())
  492. .SaveAsync();
  493. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  494. }
  495. try
  496. {
  497. //0:全分销类型;-1:各分销类型,1:goods 2: live 3:video 4: profile 5: unknown
  498. int distributiontype = form.Read("distributiontype", 0);
  499. //0:全平台;-1:各平台;1:淘宝 2:京东 2:多多
  500. int platform = form.Read("platform", 0);
  501. var data = await ApiReportCore.ReportDailysAsync(form, clientIp, debug);
  502. _ = log.Info(form.GetRawText(), data.Convert2Json()).SaveAsync();
  503. return new APIResult(new { success = true, platform, distributiontype, data });
  504. }
  505. catch (Exception ex)
  506. {
  507. _ = log.Info(form.GetRawText()).Info(ex.Message, ex.StackTrace).SaveAsync();
  508. return new APIResult(new { success = false, message = "内部错误" });
  509. }
  510. }
  511. [HttpPost]
  512. public async Task<ActionResult> unsafeDataReport([FromBody] JsonElement form)
  513. {
  514. bool debug = form.Read("debug", false);
  515. var clientIp = _accessor.HttpContext.GetUserIp();
  516. var log = new LoggerLibrary("ApiReportCore", "unsafeDataReport");
  517. log.Info(clientIp);
  518. try
  519. {
  520. //0:全分销类型;-1:各分销类型,1:goods 2: live 3:video 4: profile 5: unknown
  521. int distributiontype = form.Read("distributiontype", 0);
  522. //0:全平台;-1:各平台;1:淘宝 2:京东
  523. int platform = form.Read("platform", 0);
  524. var data = await ApiReportCore.ReportDailysAsync(form, clientIp, debug);
  525. _ = log.Info(form.GetRawText(), data.Convert2Json()).SaveAsync();
  526. return new APIResult(new { success = true, platform, distributiontype, data });
  527. }
  528. catch (Exception ex)
  529. {
  530. _ = log.Info(form.GetRawText()).Info(ex.Message, ex.StackTrace).SaveAsync();
  531. return new APIResult(new { success = false, message = "内部错误" });
  532. }
  533. }
  534. }
  535. }