ApiController.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. using TencentCloud.Lighthouse.V20200324.Models;
  15. using TencentCloud.Ame.V20190916.Models;
  16. using TencentCloud.Omics.V20221128.Models;
  17. using System.Threading.Channels;
  18. namespace molilian.api.Controllers
  19. {
  20. [ApiController]
  21. [Route("api/[action]")]
  22. public class ApiController : ControllerBase
  23. {
  24. protected IHttpContextAccessor _accessor;
  25. TaokeOpenCore core;
  26. public ApiController(IHttpContextAccessor accessor)
  27. {
  28. _accessor = accessor;
  29. core = new TaokeOpenCore();
  30. }
  31. //[HttpGet]
  32. //public async Task<ActionResult> RequestAsync([FromQuery] string url, [FromQuery] int proxyId)
  33. //{
  34. // if (string.IsNullOrEmpty(url))
  35. // {
  36. // return BadRequest("URL cannot be empty");
  37. // }
  38. // var proxy = ProxyNodesCore.GetOne(proxyId);
  39. // if (proxy == null)
  40. // {
  41. // return Unauthorized("Invalid proxy configuration");
  42. // }
  43. // WebClientUtility cli = new()
  44. // {
  45. // Proxy = proxy
  46. // };
  47. // await cli.RequestAsync(url);
  48. // var content = cli.Body();
  49. // var contentType = cli.ResponseMessage.Content.Headers.ContentType?.MediaType ?? "text/plain";
  50. // return Content(content, contentType);
  51. //}
  52. [HttpGet]
  53. public async Task<ActionResult> RequestAsync([FromQuery] string url, [FromQuery] string proxy)
  54. {
  55. if (string.IsNullOrEmpty(url))
  56. {
  57. return BadRequest("URL cannot be empty");
  58. }
  59. WebProxy _proxy = ProxyManager.Parse(proxy);
  60. WebClientUtility cli = new();
  61. cli.Proxy = _proxy;
  62. cli.Timeout = TimeSpan.FromSeconds(10);
  63. await cli.RequestAsync(url);
  64. if (cli.Successed)
  65. {
  66. var content = cli.Body();
  67. var contentType = cli.ResponseMessage.Content.Headers.ContentType?.MediaType ?? "text/plain";
  68. return Content(content, contentType);
  69. }
  70. throw cli.ResponseException;
  71. }
  72. [HttpGet]
  73. public ActionResult enable_sampling([FromQuery] int count = 1000)
  74. {
  75. int requestedCount = count;
  76. int remainingCount = PromotionQuerySamplingCore.EnableSampling(count);
  77. return new APIResult(new
  78. {
  79. success = true,
  80. message = remainingCount > 0 ? "ok" : "stopped",
  81. requestedCount,
  82. count = remainingCount,
  83. remainingCount
  84. });
  85. }
  86. [HttpPost]
  87. public async Task<ActionResult> PromotionQuery([FromBody] JsonElement form, [FromQuery] string a = "", [FromQuery] int t = 0, [FromQuery] string sign = "")
  88. {
  89. var img = form.Read("img", string.Empty);
  90. var url = form.Read("url", string.Empty);
  91. var ip = form.Read("ip", string.Empty);
  92. var oaid = form.Read("oaid", string.Empty);
  93. var scene = form.Read("scene", string.Empty);
  94. var recommand = form.Read("recommand", true);
  95. var useCouponLinkFirst = form.Read("useCouponLinkFirst", true);
  96. var aid = form.Read("aid", 0);
  97. //验证签名
  98. if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(sign))
  99. {
  100. return new APIResult(new { success = false, message = "验证错误" }, APIResultCodeEnum.Unauthorized);
  101. }
  102. DateTime time1 = t.Convert2Datetime();
  103. if (time1 < DateTime.Now.AddMinutes(-10))
  104. {
  105. return new APIResult(new { success = false, message = "验证错误2" }, APIResultCodeEnum.Unauthorized);
  106. }
  107. var account = await ApiAccountCore.GetOneAsync(a);
  108. if (account == null)
  109. {
  110. return new APIResult(new { success = false, message = "验证错误3" }, APIResultCodeEnum.Unauthorized);
  111. }
  112. string app_sign = $"{account.api_secret}@{t}".MD5();
  113. if (sign != app_sign)
  114. {
  115. return new APIResult(new { success = false, message = "验证错误4" }, APIResultCodeEnum.Unauthorized);
  116. }
  117. if (!string.IsNullOrEmpty(url))
  118. {
  119. var bytes = new WebClientUtility().Request(url).ResponseBody;
  120. img = Convert.ToBase64String(bytes);
  121. }
  122. var response = await core.PromotionQueryAsync(img, oaid, ip, scene, recommand, false, aid, useCouponLinkFirst);
  123. _ = PromotionQuerySamplingCore.TrySampleAsync(img, ip, oaid, ExtractActionResultPayload(response));
  124. return response;
  125. }
  126. [HttpPost]
  127. public async Task<ActionResult> unsafePromotionQuery([FromBody] JsonElement form)
  128. {
  129. var img = form.Read("img", string.Empty);
  130. var url = form.Read("url", string.Empty);
  131. var tkl = form.Read("tkl", string.Empty);
  132. var itemid = form.Read("itemid", string.Empty);
  133. var ip = form.Read("ip", string.Empty);
  134. var oaid = form.Read("oaid", string.Empty);
  135. var scene = form.Read("scene", string.Empty);
  136. var recommand = form.Read("recommand", true);
  137. var debug = form.Read("debug", false);
  138. var useCouponLinkFirst = form.Read("useCouponLinkFirst", true);
  139. var aid = form.Read("aid", 0);
  140. int count = form.Read("count", 0);
  141. if (!string.IsNullOrEmpty(url))
  142. {
  143. var bytes = new WebClientUtility().Request(url).ResponseBody;
  144. img = Convert.ToBase64String(bytes);
  145. }
  146. if (string.IsNullOrEmpty(oaid))
  147. {
  148. Random rand = new Random();
  149. oaid = $"{rand.Next(100000, 999999)}-{rand.Next(100000, 999999)}-{rand.Next(100000, 999999)}";
  150. }
  151. if (count > 1)
  152. {
  153. for (int i = 0; i < count; i++)
  154. {
  155. _ = core.PromotionQueryAsync(img, oaid, ip, scene, recommand, debug, aid, useCouponLinkFirst);
  156. }
  157. return new APIResult(new { msg = "ok" });
  158. }
  159. // 从口令解析商品图 临时需求
  160. if (!string.IsNullOrEmpty(tkl))
  161. {
  162. string goods_url = AlimamaPlus.GetLink(tkl);
  163. (bool successed, string itemUrl) = AlimamaPlus.GetItemUrl(goods_url);
  164. if (successed && !string.IsNullOrEmpty(itemUrl))
  165. {
  166. itemid = AlimamaPlus.ExtractItemId(itemUrl);
  167. (APIResult target, PromotionQueryDTO data) = await core.PromotionQueryByItemIdAsync(itemid, oaid, ip, scene, recommand, debug, aid);
  168. if (data != null)
  169. {
  170. url = data.PromotionImg[0].pic;
  171. if (!string.IsNullOrEmpty(url))
  172. {
  173. var bytes = new WebClientUtility().Request(url).ResponseBody;
  174. img = Convert.ToBase64String(bytes);
  175. }
  176. }
  177. return await core.PromotionQueryAsync(img, oaid, ip, scene, recommand, debug, aid, useCouponLinkFirst);
  178. }
  179. if (!string.IsNullOrEmpty(itemid))
  180. {
  181. (APIResult result, PromotionQueryDTO data) = await core.PromotionQueryByItemIdAsync(itemid, oaid, ip, scene, recommand, debug, aid, useCouponLinkFirst);
  182. return result;
  183. }
  184. }
  185. return await core.PromotionQueryAsync(img, oaid, ip, scene, recommand, debug, aid, useCouponLinkFirst);
  186. }
  187. [HttpGet]
  188. public async Task<ActionResult> PromotionQuerySampleLogs([FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] int n = 0, [FromQuery] string keyword = "")
  189. {
  190. int resolvedPageSize = n > 0 ? n : pageSize;
  191. try
  192. {
  193. var result = await PromotionQuerySamplingCore.QueryLogsAsync(page, resolvedPageSize, keyword);
  194. return new APIResult(new
  195. {
  196. success = true,
  197. count = result.logs.Count,
  198. page = result.page,
  199. pageSize = result.pageSize,
  200. totalCount = result.totalCount,
  201. totalPages = result.totalPages,
  202. remainingCount = PromotionQuerySamplingCore.GetRemainingCount(),
  203. logs = result.logs
  204. });
  205. }
  206. catch (Exception ex)
  207. {
  208. _ = new LoggerLibrary("promotion_query_samples", "query_error")
  209. .Info(ex.Message, ex.StackTrace)
  210. .SaveAsync();
  211. return new APIResult(new
  212. {
  213. success = false,
  214. message = ex.Message,
  215. count = 0,
  216. page = Math.Max(page, 1),
  217. pageSize = Math.Clamp(resolvedPageSize, 1, PromotionQuerySamplingCore.MaxQueryCount),
  218. totalCount = 0,
  219. totalPages = 0,
  220. remainingCount = PromotionQuerySamplingCore.GetRemainingCount(),
  221. logs = Array.Empty<object>()
  222. });
  223. }
  224. }
  225. private static string ExtractActionResultPayload(ActionResult response)
  226. {
  227. var jsonOptions = new JsonSerializerOptions
  228. {
  229. Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
  230. };
  231. if (response is ContentResult contentResult && !string.IsNullOrWhiteSpace(contentResult.Content))
  232. {
  233. return contentResult.Content;
  234. }
  235. if (response is JsonResult jsonResult && jsonResult.Value != null)
  236. {
  237. return JsonSerializer.Serialize(jsonResult.Value, jsonOptions);
  238. }
  239. if (response is ObjectResult objectResult && objectResult.Value != null)
  240. {
  241. return JsonSerializer.Serialize(objectResult.Value, jsonOptions);
  242. }
  243. var responseType = response.GetType();
  244. var contentProperty = responseType.GetProperty("Content");
  245. if (contentProperty?.GetValue(response) is string rawContent && !string.IsNullOrWhiteSpace(rawContent))
  246. {
  247. return rawContent;
  248. }
  249. var valueProperty = responseType.GetProperty("Value");
  250. var value = valueProperty?.GetValue(response);
  251. if (value != null)
  252. {
  253. return JsonSerializer.Serialize(value, jsonOptions);
  254. }
  255. return string.Empty;
  256. }
  257. }
  258. }