IndexController.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using IES.ExamServer.Models;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Caching.Memory;
  4. using System.Diagnostics;
  5. using System.Text.Json.Nodes;
  6. using System.Text.Json;
  7. using IES.ExamServer.Helper;
  8. using System.DrawingCore.Imaging;
  9. using System.DrawingCore;
  10. using System.IdentityModel.Tokens.Jwt;
  11. using IES.ExamServer.Services;
  12. using IES.ExamServer.DI;
  13. using IES.ExamLib.Models;
  14. namespace IES.ExamServer.Controllers
  15. {
  16. [ApiController]
  17. [Route("index")]
  18. public class IndexController : BaseController
  19. {
  20. private readonly IConfiguration _configuration;
  21. private readonly IHttpClientFactory _httpClientFactory;
  22. private readonly IMemoryCache _memoryCache;
  23. private readonly ILogger<IndexController> _logger;
  24. private readonly DataCenterConnectionService _connectionService;
  25. private readonly LiteDBFactory _liteDBFactory;
  26. public IndexController(ILogger<IndexController> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory, IMemoryCache memoryCache,DataCenterConnectionService connectionService, LiteDBFactory liteDBFactory)
  27. {
  28. _logger = logger;
  29. _configuration=configuration;
  30. _httpClientFactory=httpClientFactory;
  31. _memoryCache=memoryCache;
  32. _connectionService=connectionService;
  33. _liteDBFactory=liteDBFactory;
  34. }
  35. [HttpPost("device")]
  36. public IActionResult Device(JsonElement json )
  37. {
  38. try
  39. {
  40. string ip= GetIP();
  41. json.TryGetProperty("fp", out JsonElement fp);
  42. var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache);
  43. int hybrid = 0;
  44. _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data);
  45. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  46. if (data!=null)
  47. {
  48. hybrid=1;
  49. msg="云端服务连接成功!";
  50. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = data["centerUrl"], region = data["region"],ip= data["ip"] , nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  51. }
  52. else {
  53. msg="云端服务未连接!";
  54. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = "", region = "局域网·内网", ip = ip, nowtime= DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  55. }
  56. }
  57. catch (Exception ex)
  58. {
  59. code=500;
  60. msg="服务端异常!";
  61. }
  62. return Ok(new { code, msg });
  63. }
  64. /**
  65. {
  66. "type":"sms",//qrcode二维码扫码登录:randomCode必传; sms 短信验证登录:randomCode必传,mobile必传
  67. "randomCode",
  68. "mobile":"1528377****"
  69. }
  70. **/
  71. /// <summary>
  72. /// 登录验证
  73. /// </summary>
  74. /// <param name="randomCode"></param>
  75. /// <returns></returns>
  76. [HttpPost("login-check")]
  77. public async Task<IActionResult> LoginCheck(JsonNode json)
  78. {
  79. try
  80. {
  81. var type = json["type"];
  82. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  83. if (!string.IsNullOrWhiteSpace($"{type}"))
  84. {
  85. TmdidImplicit? token = null;
  86. string x_auth_token = string.Empty;
  87. List<School>? schools = null;
  88. JsonNode? jsonNode = null;
  89. long time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  90. switch (true)
  91. {
  92. //跳过忽略,但是仍然要以访客身份登录
  93. case bool when $"{type}".Equals(ExamConstant.ScopeVisitor):
  94. {
  95. string id = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}";
  96. string name = $"访客教师-{Random.Shared.Next(100, 999)}";
  97. x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn",id ,name,null
  98. ,ExamConstant.JwtSecretKey,ExamConstant.ScopeVisitor,8,null,new string[] { "visitor" }, expire: 1);
  99. // _memoryCache.Set($"Teacher:{id}", new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token });
  100. _liteDBFactory.GetLiteDatabase().GetCollection<Teacher>().Upsert(new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token,loginTime=time });
  101. return Ok(new { code = 200,x_auth_token = x_auth_token });
  102. }
  103. case bool when $"{type}".Equals("qrcode"):
  104. {
  105. string randomCode = $"{json["randomCode"]}";
  106. System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
  107. var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/hita/check-login?code={randomCode}");
  108. if (response.IsSuccessStatusCode)
  109. {
  110. string content = await response.Content.ReadAsStringAsync();
  111. if (!string.IsNullOrWhiteSpace(content))
  112. {
  113. jsonNode = content.ToObject<JsonNode>();
  114. }
  115. else
  116. {
  117. code=400;
  118. msg="随机码验证失败";
  119. }
  120. }
  121. else
  122. {
  123. code=400;
  124. msg="随机码验证错误";
  125. }
  126. break;
  127. }
  128. case bool when $"{type}".Equals("smspin"):
  129. {
  130. string pin_code = $"{json["pin_code"]}";
  131. string account = $"{json["account"]}";
  132. var response = await _httpClientFactory.CreateClient().PostAsJsonAsync($"{CenterUrl}/core/sendsms/check", new { pin_code, account });
  133. if (response.IsSuccessStatusCode)
  134. {
  135. string content = await response.Content.ReadAsStringAsync();
  136. if (!string.IsNullOrWhiteSpace(content))
  137. {
  138. jsonNode = content.ToObject<JsonNode>();
  139. }
  140. else
  141. {
  142. code=400;
  143. msg="短信验证返回结果为空";
  144. }
  145. }
  146. else
  147. {
  148. code=400;
  149. msg="短信验证错误";
  150. }
  151. break;
  152. }
  153. }
  154. if (jsonNode != null && $"{jsonNode["code"]}".Equals("200"))
  155. {
  156. token =jsonNode["implicit_token"]?.ToObject<TmdidImplicit>();
  157. x_auth_token = $"{jsonNode["x_auth_token"]}";
  158. schools =jsonNode["schools"]?.ToObject<List<School>>();
  159. var jwt = new JwtSecurityToken(token?.id_token);
  160. var id = jwt.Payload.Sub;
  161. jwt.Payload.TryGetValue("name", out object? name);
  162. jwt.Payload.TryGetValue("picture", out object? picture);
  163. //_memoryCache.Set($"Teacher:{id}", new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token });
  164. _liteDBFactory.GetLiteDatabase().GetCollection<Teacher>().Upsert(new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token ,loginTime=time });
  165. return Ok(new { code=200,/* implicit_token = token, schools = schools , */ x_auth_token = x_auth_token });
  166. }
  167. else
  168. {
  169. code=400;
  170. msg="验证失败";
  171. }
  172. }
  173. else
  174. {
  175. code=400;
  176. msg="参数错误";
  177. }
  178. }
  179. catch (Exception ex)
  180. {
  181. code=500;
  182. msg="异常错误";
  183. }
  184. return Ok(new { code = code,msg });
  185. }
  186. /*
  187. */
  188. /// <summary>
  189. /// 登录模式初始化
  190. /// </summary>
  191. /// <returns></returns>
  192. [HttpPost("login-init")]
  193. public async Task<IActionResult> LoginInit(JsonNode json)
  194. {
  195. var type = json["type"];
  196. string qrcode = string.Empty;
  197. string randomCode = "";
  198. switch (true)
  199. {
  200. case bool when $"{type}".Equals("qrcode"):
  201. {
  202. //.NET Core使用SkiaSharp快速生成二维码 https://cloud.tencent.com/developer/article/2336486
  203. // 生成二维码图片
  204. Random random = new Random();
  205. randomCode = $"{random.Next(1000, 9999)}";
  206. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  207. string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1";
  208. var str= QRCodeHelper.GenerateQRCode(content, 300, 300,QRCodeHelper.logo);
  209. qrcode = $"data:image/png;base64,{str}";
  210. return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
  211. }
  212. case bool when $"{type}".Equals("xqrcode"):
  213. {
  214. // 生成二维码图片
  215. Random random = new Random();
  216. randomCode = $"{random.Next(1000, 9999)}";
  217. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  218. string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1";
  219. Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200);
  220. using (MemoryStream stream = new MemoryStream())
  221. {
  222. qrCodeImage.Save(stream, ImageFormat.Png);
  223. byte[] data = stream.ToArray();
  224. qrcode=$"data:image/png;base64,{Convert.ToBase64String(data)}";
  225. }
  226. return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
  227. }
  228. case bool when $"{type}".Equals("smspin"):
  229. {
  230. int send = 0;
  231. if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}"))
  232. {
  233. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  234. string url = $"{CenterUrl}/core/sendsms/pin";
  235. HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area=json["area"], to = json["to"], lang="zh-cn" });
  236. if (message.IsSuccessStatusCode)
  237. {
  238. string content = await message.Content.ReadAsStringAsync();
  239. JsonNode? jsonNode = content?.ToObject<JsonNode>();
  240. if (jsonNode!=null && int.TryParse($"{jsonNode["send"]}", out int s))
  241. {
  242. send = s;
  243. }
  244. }
  245. }
  246. return Ok(new { code = 200, send, type });
  247. }
  248. }
  249. return Ok(new { code = 400 });
  250. }
  251. }
  252. }