Api.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. using DaJiaoYan.Models;
  2. using DaJiaoYan.Utils;
  3. using Newtonsoft.Json;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Net;
  7. using System.Net.Http;
  8. using System.Text.RegularExpressions;
  9. using System.Threading.Tasks;
  10. namespace DaJiaoYan.Services
  11. {
  12. public static class Api
  13. {
  14. public delegate void DeleLogin(bool runAfterLoginFn);
  15. public static DeleLogin LoginFn;
  16. /// <summary>
  17. /// 枚举类型
  18. /// </summary>
  19. public static class Enumerates
  20. {
  21. /// <summary>
  22. /// 考号类型
  23. /// </summary>
  24. public enum ExamNumberType
  25. {
  26. /// <summary>
  27. /// 系统号(云学情学号)
  28. /// </summary>
  29. System = 1,
  30. /// <summary>
  31. /// 学校学号
  32. /// </summary>
  33. School = 2,
  34. }
  35. /// <summary>
  36. /// 是否获取所有有权限参考学生
  37. /// </summary>
  38. public enum AllExamStudentType
  39. {
  40. /// <summary>
  41. /// 是
  42. /// </summary>
  43. Yes = 1,
  44. /// <summary>
  45. /// 只获取考试的学生
  46. /// </summary>
  47. No = 0,
  48. }
  49. /// <summary>
  50. /// 搜索名称类型
  51. /// </summary>
  52. public enum ExamStudentSearchNameType
  53. {
  54. /// <summary>
  55. /// 所有
  56. /// </summary>
  57. All = 0,
  58. /// <summary>
  59. /// 只搜索账号名
  60. /// </summary>
  61. OnlyUserName = 1,
  62. /// <summary>
  63. /// 用户名跟真实姓名
  64. /// </summary>
  65. UserNameAndRealName = 2,
  66. }
  67. }
  68. private const int PAGE_SIZE = 999999;
  69. private const int PAGE_NO = 1;
  70. /// <summary>
  71. /// 获取试卷划分区域信息
  72. /// </summary>
  73. /// <param name="testId">试卷ID</param>
  74. /// <returns></returns>
  75. public static async Task<DividePartitionConfig> GetDividePartitionConfig(int testId, string token = null)
  76. {
  77. DividePartitionConfig res = null;
  78. Dictionary<string, object> keyValuePairs;
  79. var (code, response) = await Fetch(new Http.Request(@"v1/examination/divide-partition", Http.Method.Get, new Dictionary<string, object>()
  80. {
  81. {"test_id", testId },
  82. {"page_size", 99 },
  83. {"page_no", 1 },
  84. {"correct_type", 0 },
  85. }), token);
  86. if (!string.IsNullOrEmpty(response) && code == 200)
  87. {
  88. res = Json.Decode<DividePartitionConfig>(response);
  89. keyValuePairs = Json.Decode<Dictionary<string, object>>(response);
  90. keyValuePairs.TryGetValue("template_info", out object templateInfoObj);
  91. if (templateInfoObj != null)
  92. {
  93. Dictionary<string, object> templateInfo = Json.Decode<Dictionary<string, object>>(Json.Encode(templateInfoObj));
  94. templateInfo.TryGetValue("temp_rect", out object tempRect);
  95. if (tempRect != null)
  96. {
  97. res.Template.TemplateRect = new TemplateRect(res.Template.ParsedVersion, Json.Encode(tempRect));
  98. }
  99. }
  100. }
  101. return res;
  102. }
  103. /// <summary>
  104. /// 获取静态文件流
  105. /// </summary>
  106. /// <param name="fileName"></param>
  107. /// <returns></returns>
  108. public static async Task<byte[]> GetStaticFileBytes(string fileName)
  109. {
  110. byte[] result = null;
  111. fileName = Regex.Replace(fileName, @"^[\/\\]*", "");
  112. long begin = Functions.GetTimeStamp(), end;
  113. Http.Request request = new Http.Request($"{Variables.Const.HTTP_STATIC_HOST}{fileName}", Http.Method.Get);
  114. end = Functions.GetTimeStamp();
  115. Log.WriteLine($"request static file create http: {end - begin}");
  116. begin = end;
  117. using (HttpResponseMessage response = await Http.Fetch(request))
  118. {
  119. end = Functions.GetTimeStamp();
  120. Log.WriteLine($"request static file fetch http: {end - begin}");
  121. begin = end;
  122. if (response != null && response.StatusCode == HttpStatusCode.OK)
  123. {
  124. result = response.Content.ReadAsByteArrayAsync().Result;
  125. end = Functions.GetTimeStamp();
  126. Log.WriteLine($"request static file read byte: {end - begin}");
  127. begin = end;
  128. }
  129. }
  130. return result;
  131. }
  132. /// <summary>
  133. /// 获取升级信息
  134. /// </summary>
  135. /// <returns></returns>
  136. public static async Task<Models.UpdateInfo> GetUpdateInfo()
  137. {
  138. UpdateInfo info = new UpdateInfo();
  139. try
  140. {
  141. string url = Regex.Replace(Variables.Const.HTTP_UPDATE_FILE, "\\.[^.]{2,5}$", ".txt", RegexOptions.IgnoreCase);
  142. HttpResponseMessage response = await Http.Fetch(new Http.Request(url, Http.Method.Get));
  143. if (response.IsSuccessStatusCode)
  144. {
  145. string txt = await response.Content.ReadAsStringAsync();
  146. info = Utils.Json.Decode<UpdateInfo>(txt);
  147. }
  148. }
  149. catch
  150. {
  151. }
  152. return info;
  153. }
  154. /// <summary>
  155. /// 获取阿里云OSS STS 权限
  156. /// </summary>
  157. /// <returns></returns>
  158. public static async Task<Models.AliyunAccessModel> GetAliyunAccess(string token = null)
  159. {
  160. var (_, response) = await Fetch(new Http.Request(@"v1/oss/authorize", Http.Method.Post, null), token);
  161. Models.AliyunAccessModel res = null;
  162. if (response != null)
  163. {
  164. res = Json.Decode<Models.AliyunAccessModel>(response);
  165. }
  166. return res;
  167. }
  168. public static async Task<(int, string)> PostExaminationScanResult(Models.ScanResultPost p, string token = null)
  169. {
  170. var req = new Http.Request(@"v1/examination/scan-result", Http.Method.Post)
  171. {
  172. data = Json.Decode<Dictionary<string, object>>(Json.Encode(p))
  173. };
  174. return await Fetch(req, token);
  175. }
  176. /// <summary>
  177. /// 获取系统返回的内容
  178. /// </summary>
  179. /// <typeparam name="T"></typeparam>
  180. /// <param name="url"></param>
  181. /// <param name="method"></param>
  182. /// <param name="data"></param>
  183. /// <returns></returns>
  184. private static async Task<T> GetResponse<T>(string url, Http.Method method, Dictionary<string, object> data)
  185. {
  186. T res = default;
  187. var (_, response) = await Fetch(new Http.Request(url, method, data));
  188. if (!string.IsNullOrEmpty(response))
  189. {
  190. var tmp = Json.Decode<Dictionary<string, object>>(response);
  191. if (tmp != null && tmp.ContainsKey("result"))
  192. {
  193. res = Json.Decode<T>(tmp["result"].ToString());
  194. }
  195. }
  196. return res;
  197. }
  198. #region 私有方法
  199. /// <summary>
  200. /// 请求
  201. /// </summary>
  202. /// <param name="request"></param>
  203. /// <returns></returns>
  204. private static async Task<(int, string)> Fetch(Http.Request request, string token = null)
  205. {
  206. foreach (var item in Variables.Vars.RequestHeaders)
  207. {
  208. // 添加请求头
  209. request.headers.Add(item.Key, item.Value);
  210. }
  211. if (!string.IsNullOrEmpty(token))
  212. {
  213. request.headers["Authorization"] = $"Bearer {token}";
  214. request.headers["AppName"] = "com.teacherUploadMark.web";
  215. }
  216. // 请求地址
  217. #if DEBUG
  218. if (request.uri.IndexOf("/oss/") >= 0 && Variables.Const.HTTP_HOST.IndexOf("local") >= 0)
  219. {
  220. request.uri = string.Concat("http://local.api.dajiaoyan.com/", request.uri);
  221. }
  222. else
  223. {
  224. request.uri = string.Concat(Variables.Const.HTTP_HOST, request.uri);
  225. }
  226. #else
  227. // 请求地址
  228. request.uri = string.Concat(Variables.Const.HTTP_HOST, request.uri);
  229. #endif
  230. string apiResponse = null;
  231. int code = 200;
  232. Dictionary<string, object> resp;
  233. using (HttpResponseMessage response = await Http.Fetch(request))
  234. {
  235. if (response != null)
  236. {
  237. switch (response.StatusCode)
  238. {
  239. case HttpStatusCode.OK:
  240. // 正常响应
  241. resp = JsonConvert.DeserializeObject<Dictionary<string, object>>(await response.Content.ReadAsStringAsync());
  242. code = Convert.ToInt32(resp["code"]);
  243. switch (code)
  244. {
  245. case 400:
  246. Response400();
  247. apiResponse = resp["errors"] != null ? resp["errors"].ToString() : "接口错误";
  248. break;
  249. case 401:
  250. Response401();
  251. break;
  252. case 4000:
  253. Response401();
  254. break;
  255. case 404:
  256. Response404();
  257. break;
  258. case 500:
  259. Response500();
  260. apiResponse = resp["errors"].ToString();
  261. break;
  262. case 502:
  263. Response500();
  264. break;
  265. default:
  266. apiResponse = resp["data"] != null ? resp["data"].ToString() : "";
  267. break;
  268. }
  269. break;
  270. case HttpStatusCode.NotFound:
  271. // 页面不存在
  272. Response404();
  273. break;
  274. case HttpStatusCode.Unauthorized:
  275. // 无权限
  276. if (string.IsNullOrEmpty(token))
  277. {
  278. Response401();
  279. }
  280. break;
  281. case HttpStatusCode.BadRequest:
  282. // 页面错误
  283. Response400();
  284. break;
  285. default:
  286. // 其它错误
  287. Response500();
  288. break;
  289. }
  290. }
  291. else
  292. {
  293. // 没有网络
  294. }
  295. }
  296. return (code, apiResponse);
  297. }
  298. private static void Response400()
  299. {
  300. }
  301. private static void Response401()
  302. {
  303. LoginFn?.Invoke(false);
  304. }
  305. private static void Response404()
  306. {
  307. }
  308. private static void Response500()
  309. {
  310. }
  311. #endregion
  312. }
  313. }