using IES.ExamServer.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using System.Diagnostics; using System.Text.Json.Nodes; using System.Text.Json; using IES.ExamServer.Helper; using System.DrawingCore.Imaging; using System.DrawingCore; using System.IdentityModel.Tokens.Jwt; using IES.ExamServer.Services; using IES.ExamServer.DI; using IES.ExamLib.Models; namespace IES.ExamServer.Controllers { [ApiController] [Route("index")] public class IndexController : BaseController { private readonly IConfiguration _configuration; private readonly IHttpClientFactory _httpClientFactory; private readonly IMemoryCache _memoryCache; private readonly ILogger _logger; private readonly DataCenterConnectionService _connectionService; private readonly LiteDBFactory _liteDBFactory; public IndexController(ILogger logger, IConfiguration configuration, IHttpClientFactory httpClientFactory, IMemoryCache memoryCache,DataCenterConnectionService connectionService, LiteDBFactory liteDBFactory) { _logger = logger; _configuration=configuration; _httpClientFactory=httpClientFactory; _memoryCache=memoryCache; _connectionService=connectionService; _liteDBFactory=liteDBFactory; } [HttpPost("device")] public IActionResult Device(JsonElement json ) { try { string ip= GetIP(); json.TryGetProperty("fp", out JsonElement fp); var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache); int hybrid = 0; _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data); _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server); if (data!=null) { hybrid=1; msg="云端服务连接成功!"; return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = data["centerUrl"], region = data["region"],ip= data["ip"] , nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } }); } else { msg="云端服务未连接!"; return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = "", region = "局域网·内网", ip = ip, nowtime= DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } }); } } catch (Exception ex) { code=500; msg="服务端异常!"; } return Ok(new { code, msg }); } /** { "type":"sms",//qrcode二维码扫码登录:randomCode必传; sms 短信验证登录:randomCode必传,mobile必传 "randomCode", "mobile":"1528377****" } **/ /// /// 登录验证 /// /// /// [HttpPost("login-check")] public async Task LoginCheck(JsonNode json) { try { var type = json["type"]; string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); if (!string.IsNullOrWhiteSpace($"{type}")) { TmdidImplicit? token = null; string x_auth_token = string.Empty; List? schools = null; JsonNode? jsonNode = null; long time = DateTimeOffset.Now.ToUnixTimeMilliseconds(); switch (true) { //跳过忽略,但是仍然要以访客身份登录 case bool when $"{type}".Equals(ExamConstant.ScopeVisitor): { string id = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}"; string name = $"访客教师-{Random.Shared.Next(100, 999)}"; x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn",id ,name,null ,ExamConstant.JwtSecretKey,ExamConstant.ScopeVisitor,8,null,new string[] { "visitor" }, expire: 1); // _memoryCache.Set($"Teacher:{id}", new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token }); _liteDBFactory.GetLiteDatabase().GetCollection().Upsert(new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token,loginTime=time }); return Ok(new { code = 200,x_auth_token = x_auth_token }); } case bool when $"{type}".Equals("qrcode"): { string randomCode = $"{json["randomCode"]}"; System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/hita/check-login?code={randomCode}"); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrWhiteSpace(content)) { jsonNode = content.ToObject(); } else { code=400; msg="随机码验证失败"; } } else { code=400; msg="随机码验证错误"; } break; } case bool when $"{type}".Equals("smspin"): { string pin_code = $"{json["pin_code"]}"; string account = $"{json["account"]}"; var response = await _httpClientFactory.CreateClient().PostAsJsonAsync($"{CenterUrl}/core/sendsms/check", new { pin_code, account }); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrWhiteSpace(content)) { jsonNode = content.ToObject(); } else { code=400; msg="短信验证返回结果为空"; } } else { code=400; msg="短信验证错误"; } break; } } if (jsonNode != null && $"{jsonNode["code"]}".Equals("200")) { token =jsonNode["implicit_token"]?.ToObject(); x_auth_token = $"{jsonNode["x_auth_token"]}"; schools =jsonNode["schools"]?.ToObject>(); var jwt = new JwtSecurityToken(token?.id_token); var id = jwt.Payload.Sub; jwt.Payload.TryGetValue("name", out object? name); jwt.Payload.TryGetValue("picture", out object? picture); //_memoryCache.Set($"Teacher:{id}", new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token }); _liteDBFactory.GetLiteDatabase().GetCollection().Upsert(new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token ,loginTime=time }); return Ok(new { code=200,/* implicit_token = token, schools = schools , */ x_auth_token = x_auth_token }); } else { code=400; msg="验证失败"; } } else { code=400; msg="参数错误"; } } catch (Exception ex) { code=500; msg="异常错误"; } return Ok(new { code = code,msg }); } /* */ /// /// 登录模式初始化 /// /// [HttpPost("login-init")] public async Task LoginInit(JsonNode json) { var type = json["type"]; string qrcode = string.Empty; string randomCode = ""; switch (true) { case bool when $"{type}".Equals("qrcode"): { //.NET Core使用SkiaSharp快速生成二维码 https://cloud.tencent.com/developer/article/2336486 // 生成二维码图片 Random random = new Random(); randomCode = $"{random.Next(1000, 9999)}"; string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1"; var str= QRCodeHelper.GenerateQRCode(content, 300, 300,QRCodeHelper.logo); qrcode = $"data:image/png;base64,{str}"; return Ok(new { code = 200, randomCode = randomCode, qrcode, type }); } case bool when $"{type}".Equals("xqrcode"): { // 生成二维码图片 Random random = new Random(); randomCode = $"{random.Next(1000, 9999)}"; string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1"; Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200); using (MemoryStream stream = new MemoryStream()) { qrCodeImage.Save(stream, ImageFormat.Png); byte[] data = stream.ToArray(); qrcode=$"data:image/png;base64,{Convert.ToBase64String(data)}"; } return Ok(new { code = 200, randomCode = randomCode, qrcode, type }); } case bool when $"{type}".Equals("smspin"): { int send = 0; if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}")) { string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); string url = $"{CenterUrl}/core/sendsms/pin"; HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area=json["area"], to = json["to"], lang="zh-cn" }); if (message.IsSuccessStatusCode) { string content = await message.Content.ReadAsStringAsync(); JsonNode? jsonNode = content?.ToObject(); if (jsonNode!=null && int.TryParse($"{jsonNode["send"]}", out int s)) { send = s; } } } return Ok(new { code = 200, send, type }); } } return Ok(new { code = 400 }); } } }