You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
6.6 KiB

  1. using Apewer;
  2. using Apewer.Internals.QrCode;
  3. using Apewer.Network;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Collections.Specialized;
  7. namespace Apewer.Web
  8. {
  9. /// <summary></summary>
  10. public class ApiClient
  11. {
  12. private const int DefaultTimeout = 30000;
  13. /// <summary></summary>
  14. public string ApiUrl { get; set; }
  15. /// <summary></summary>
  16. public string Random { get; set; }
  17. /// <summary></summary>
  18. public string Ticket { get; set; }
  19. /// <summary></summary>
  20. public string Session { get; set; }
  21. /// <summary></summary>
  22. public string Page { get; set; }
  23. /// <summary></summary>
  24. public string UserAgent { get; set; }
  25. /// <summary></summary>
  26. public int Timeout { get; set; } = DefaultTimeout;
  27. /// <summary></summary>
  28. public static Result<Json> Return(byte[] bytes, Action<Json> succeed = null, Action<string> failed = null)
  29. {
  30. var text = TextUtility.FromBinary(bytes);
  31. var json = Json.Parse(text);
  32. return Return(json, succeed, failed);
  33. }
  34. /// <summary>解析响应并返回。</summary>
  35. public static Result<Json> Return(Json json, Action<Json> succeed = null, Action<string> failed = null)
  36. {
  37. if (json != null && json.Available)
  38. {
  39. var status = json["status"];
  40. if (status == "ok")
  41. {
  42. var data = json.GetProperty("data") ?? Json.NewObject();
  43. succeed?.Invoke(data);
  44. return new Result<Json>(data);
  45. }
  46. else
  47. {
  48. var message = json["message"];
  49. return Return(message, failed);
  50. }
  51. }
  52. return Return("响应为空。", failed);
  53. }
  54. /// <summary>返回错误。</summary>
  55. public static Result<Json> Return(string error, Action<string> failed = null)
  56. {
  57. var error2 = error.IsEmpty() ? "未知错误。" : error;
  58. failed?.Invoke(error2);
  59. return Result<Json>.Error(error2);
  60. }
  61. /// <summary>发起请求。</summary>
  62. public Result<Json> Send(string url, byte[] body = null, Action<Json> succeed = null, Action<string> failed = null, int timeout = DefaultTimeout)
  63. {
  64. if (url.IsEmpty()) return Return("参数 URL 无效。", failed);
  65. var client = new HttpClient();
  66. client.Request.Url = url;
  67. if (UserAgent.NotEmpty()) client.Request.UserAgent = UserAgent;
  68. if (body == null || body.Length < 1)
  69. {
  70. client.Request.Method = HttpMethod.GET;
  71. }
  72. else
  73. {
  74. client.Request.Method = HttpMethod.POST;
  75. client.Request.Data = body;
  76. }
  77. var ex = client.Send();
  78. return ex == null ? Return(client.Response.Data, succeed, failed) : Return(ex.Message);
  79. }
  80. private string MergeUrl(string application = null, string function = null, IEnumerable<KeyValuePair<string, string>> args = null)
  81. {
  82. var ts = new TextSet(true);
  83. ts["application"] = application;
  84. ts["function"] = function;
  85. if (Random.NotEmpty()) ts["random"] = Random;
  86. if (Page.NotEmpty()) ts["page"] = Random;
  87. if (Session.NotEmpty()) ts["session"] = Random;
  88. if (Ticket.NotEmpty()) ts["ticket"] = Random;
  89. if (args != null)
  90. {
  91. foreach (var i in args)
  92. {
  93. if (i.Key.IsEmpty()) continue;
  94. if (i.Key == "application") continue;
  95. if (i.Key == "function") continue;
  96. if (i.Value.IsEmpty()) continue;
  97. ts[i.Key] = i.Value;
  98. }
  99. }
  100. var url = TextUtility.AssureEnds(ApiUrl, true, "/");
  101. var query = HttpClient.MergeForm(ts);
  102. if (query.NotEmpty()) url = url.Append("?", query);
  103. return url;
  104. }
  105. private Json MergePost(string application = null, string function = null, Json data = null)
  106. {
  107. var json = Json.NewObject();
  108. json.SetProperty("application", application);
  109. json.SetProperty("function", function);
  110. json.SetProperty("random", Random);
  111. json.SetProperty("page", Page);
  112. json.SetProperty("session", Session);
  113. json.SetProperty("ticket", Ticket);
  114. json.SetProperty("data", data);
  115. return json;
  116. }
  117. // GET
  118. /// <summary></summary>
  119. public Result<Json> Get(string application = null, string function = null, IEnumerable<KeyValuePair<string, string>> args = null, Action<Json> succeed = null, Action<string> failed = null)
  120. {
  121. var url = MergeUrl(application, function, args);
  122. return Send(url, null, succeed, failed, Timeout);
  123. }
  124. /// <summary></summary>
  125. public Result<Json> Get(string application = null, string function = null, TextSet args = null, Action<Json> succeed = null, Action<string> failed = null)
  126. {
  127. var url = MergeUrl(application, function, args == null ? null : args.Origin);
  128. return Send(url, null, succeed, failed, Timeout);
  129. }
  130. // POST
  131. /// <summary></summary>
  132. public Result<Json> Post(string application = null, string function = null, IEnumerable<KeyValuePair<string, string>> args = null, byte[] body = null, Action<Json> succeed = null, Action<string> failed = null)
  133. {
  134. var url = MergeUrl(application, function, args);
  135. return Send(url, body, succeed, failed, Timeout);
  136. }
  137. /// <summary></summary>
  138. public Result<Json> Post(string application = null, string function = null, TextSet args = null, byte[] body = null, Action<Json> succeed = null, Action<string> failed = null)
  139. {
  140. var url = MergeUrl(application, function, args == null ? null : args.Origin);
  141. return Send(url, body, succeed, failed, Timeout);
  142. }
  143. /// <summary></summary>
  144. public Result<Json> Post(string application = null, string function = null, Json data = null, Action<Json> succeed = null, Action<string> failed = null)
  145. {
  146. var json = MergePost(application, function, data);
  147. var bytes = json.ToString().GetBytes();
  148. return Send(ApiUrl, bytes, succeed, failed, Timeout);
  149. }
  150. }
  151. }