MoofenController.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. using Microsoft.AspNetCore.Authorization;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Configuration;
  5. using Microsoft.IdentityModel.Tokens;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IdentityModel.Tokens.Jwt;
  9. using System.Security.Claims;
  10. using System.Text;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using System.Web;
  14. using TEAMModelOS.Filter;
  15. using TEAMModelOS.SDK;
  16. using TEAMModelOS.SDK.Models;
  17. using TEAMModelOS.SDK.Extension;
  18. using DocumentFormat.OpenXml.Wordprocessing;
  19. using System.Linq;
  20. using System.Net.Http;
  21. using System.Net.Http.Json;
  22. using System.Net;
  23. using System.Net.Http.Headers;
  24. using HTEXLib.COMM.Helpers;
  25. using TEAMModelOS.SDK.DI;
  26. using HTEXLib.Helpers.ShapeHelpers;
  27. using HtmlAgilityPack;
  28. using Top.Api.Util;
  29. using DocumentFormat.OpenXml.Drawing.Charts;
  30. using DocumentFormat.OpenXml.Spreadsheet;
  31. using TEAMModelOS.SDK.Models.Cosmos.School;
  32. using OfficeOpenXml;
  33. using System.IO.Packaging;
  34. using Microsoft.Azure.Amqp.Framing;
  35. using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
  36. using DocumentFormat.OpenXml.Office2010.Excel;
  37. using TEAMModelOS.SDK.Models.Service;
  38. namespace TEAMModelOS.Controllers.Third.Moofen
  39. {
  40. [ProducesResponseType(StatusCodes.Status200OK)]
  41. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  42. [ApiController]
  43. public class MoofenController : ControllerBase
  44. {
  45. private readonly CoreAPIHttpService _coreAPIHttpService;
  46. private readonly IConfiguration _configuration;
  47. private readonly IHttpClientFactory _httpClient;
  48. private readonly DingDing _dingDing;
  49. private readonly AzureCosmosFactory _azureCosmos;
  50. private readonly AzureStorageFactory _azureStorage;
  51. public MoofenController(AzureCosmosFactory azureCosmos,CoreAPIHttpService coreAPIHttpService, IConfiguration configuration, IHttpClientFactory httpClient, DingDing dingDing,AzureStorageFactory azureStorage)
  52. {
  53. _coreAPIHttpService=coreAPIHttpService;
  54. _configuration=configuration;
  55. _httpClient=httpClient;
  56. _dingDing=dingDing;
  57. _azureCosmos=azureCosmos;
  58. _azureStorage=azureStorage;
  59. }
  60. [HttpPost("moofen/read-excel-knowledge-point")]
  61. [RequestSizeLimit(102_400_000_00)] //最大10000m左右
  62. public async Task<IActionResult> ReadExcelKnowledgePoint([FromForm] IFormFile[] file)
  63. {
  64. ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
  65. List<dynamic> period_subject = new List<dynamic>();
  66. foreach (var f in file)
  67. {
  68. List<MoofenKnowledgePointDto> pointDtos = new List<MoofenKnowledgePointDto>();
  69. string[] parts = f.FileName.Split(']');
  70. string[] periodp = parts[0].Split('[');
  71. string[] subjectp = parts[1].Split('[');
  72. string period = periodp[1].Trim();
  73. string subject = subjectp[1].Trim();
  74. List<string> titles = new List<string>();
  75. List<List<string>> datas = new List<List<string>>();
  76. using (ExcelPackage package = new ExcelPackage(f.OpenReadStream()))
  77. {
  78. ExcelWorksheets sheets = package.Workbook.Worksheets;
  79. var sheet = sheets.FirstOrDefault();
  80. if (sheet!= null)
  81. {
  82. var rows = sheet.Dimension.Rows;
  83. var columns = sheet.Dimension.Columns;
  84. for (int r = 1; r <= rows; r++)
  85. {
  86. List<string> data = new List<string>();
  87. for (int c = 1; c <= columns; c++)
  88. {
  89. var value = sheet .GetValue(r, c);
  90. if (r == 1)
  91. {
  92. if (!string.IsNullOrWhiteSpace($"{value}"))
  93. {
  94. titles.Add($"{value}");
  95. }
  96. else
  97. {
  98. break;
  99. }
  100. }
  101. else
  102. {
  103. if (c > titles.Count)
  104. {
  105. break;
  106. }
  107. else
  108. {
  109. data.Add($"{value}");
  110. }
  111. }
  112. }
  113. if (data.Any())
  114. {
  115. datas.Add(data);
  116. }
  117. }
  118. }
  119. }
  120. foreach ( var data in datas )
  121. {
  122. MoofenKnowledgePointDto knowledgePointDto = new MoofenKnowledgePointDto { kp1 = data[0] , kp2= data[1], kp3 = data[2], kp4= data[3], id= data[4] };
  123. if (!string.IsNullOrWhiteSpace(knowledgePointDto.kp1)) {
  124. knowledgePointDto.level=1;
  125. knowledgePointDto.name=knowledgePointDto.kp1;
  126. }
  127. if (!string.IsNullOrWhiteSpace(knowledgePointDto.kp2))
  128. {
  129. knowledgePointDto.level=2;
  130. knowledgePointDto.name=knowledgePointDto.kp2;
  131. }
  132. if (!string.IsNullOrWhiteSpace(knowledgePointDto.kp3))
  133. {
  134. knowledgePointDto.level=3;
  135. knowledgePointDto.name=knowledgePointDto.kp3;
  136. }
  137. if (!string.IsNullOrWhiteSpace(knowledgePointDto.kp4))
  138. {
  139. knowledgePointDto.level=4;
  140. knowledgePointDto.name=knowledgePointDto.kp4;
  141. }
  142. pointDtos.Add( knowledgePointDto );
  143. }
  144. // 构建树形结构
  145. var tree =KnowledgeService. BuildTree(pointDtos);
  146. tree.name=$"{period}-{subject}";
  147. var json= tree.children.ToJsonString();
  148. string subjectId = string.Empty;
  149. string periodId = string.Empty;
  150. switch (period)
  151. {
  152. case "小学": periodId="primary"; break;
  153. case "初中": periodId="junior"; break;
  154. case "高中": periodId="senior"; break;
  155. }
  156. switch (subject)
  157. {
  158. case "语文":
  159. subjectId="subject_chinese";
  160. break;
  161. case "数学":
  162. subjectId="subject_math";
  163. break;
  164. case "英语":
  165. subjectId="subject_english";
  166. break;
  167. case "物理":
  168. subjectId="subject_physics";
  169. break;
  170. case "化学":
  171. subjectId="subject_chemistry";
  172. break;
  173. case "生物":
  174. subjectId="subject_biology";
  175. break;
  176. case "政治":
  177. subjectId="subject_politics";
  178. break;
  179. case "历史":
  180. subjectId="subject_history";
  181. break;
  182. case "地理":
  183. subjectId="subject_geography";
  184. break;
  185. }
  186. period_subject.Add(new { period,subject, periodId,subjectId }) ;
  187. await _azureStorage.GetBlobContainerClient(Constant.teammodelos_blob).UploadFileByContainer(json,"third",$"moofen/kp-{periodId}-{subjectId}.json",true);
  188. }
  189. return Ok(new { period_subject });
  190. }
  191. [HttpPost("moofen/question")]
  192. [AuthToken(Roles = "teacher,admin")]
  193. #if !DEBUG
  194. [Authorize(Roles = "IES")]
  195. #endif
  196. public async Task<IActionResult> Question(JsonElement json)
  197. {
  198. var tokenData= HttpContext.GetAuthTokenInfo();
  199. string content = string.Empty;
  200. try {
  201. School school = null;
  202. Dictionary<string, string> dict = new Dictionary<string, string>();
  203. if (json.TryGetProperty("search", out JsonElement search) && !string.IsNullOrWhiteSpace($"{search}"))
  204. {
  205. dict.Add("search", $"{search}");
  206. }
  207. if (json.TryGetProperty("isSchoolItem", out JsonElement schoolItem) && schoolItem.ValueKind.Equals(JsonValueKind.True) &&!string.IsNullOrWhiteSpace(tokenData.school))
  208. {
  209. dict.Add("exSchId", $"{tokenData.school}");
  210. school= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(tokenData.school, new Azure.Cosmos.PartitionKey("Base"));
  211. }
  212. if (json.TryGetProperty("subject", out JsonElement subject) && !string.IsNullOrWhiteSpace($"{subject}"))
  213. {
  214. dict.Add("subject", $"{subject}");
  215. }
  216. if (json.TryGetProperty("kpIds", out JsonElement kpIds) && kpIds.ValueKind.Equals(JsonValueKind.Array))
  217. {
  218. //对方接口数据参数是"kpIds": "[\"221206\"]",
  219. dict.Add("kpIds", $"{kpIds.ToJsonString()}");
  220. }
  221. if (json.TryGetProperty("grades", out JsonElement grades) && !string.IsNullOrWhiteSpace($"{grades}"))
  222. {
  223. dict.Add("grades", $"{grades}");
  224. }
  225. if (json.TryGetProperty("type", out JsonElement type) && !string.IsNullOrWhiteSpace($"{type}"))
  226. {
  227. dict.Add("type", $"{type}");
  228. }
  229. if (json.TryGetProperty("difficulty", out JsonElement difficulty) && !string.IsNullOrWhiteSpace($"{difficulty}"))
  230. {
  231. dict.Add("difficulty", $"{difficulty}");
  232. }
  233. if (json.TryGetProperty("year", out JsonElement year) && !string.IsNullOrWhiteSpace($"{year}"))
  234. {
  235. dict.Add("year", $"{year}");
  236. }
  237. if (json.TryGetProperty("hasKps", out JsonElement hasKps) && !string.IsNullOrWhiteSpace($"{hasKps}"))
  238. {
  239. dict.Add("hasKps", $"{hasKps}");
  240. }
  241. if (json.TryGetProperty("hasAnswer", out JsonElement hasAnswer) && !string.IsNullOrWhiteSpace($"{hasAnswer}"))
  242. {
  243. dict.Add("hasAnswer", $"{hasAnswer}");
  244. }
  245. if (json.TryGetProperty("pageSize", out JsonElement pageSize) && !string.IsNullOrWhiteSpace($"{pageSize}"))
  246. {
  247. dict.Add("pageSize", $"{pageSize}");
  248. }
  249. if (json.TryGetProperty("currentPage", out JsonElement currentPage) && !string.IsNullOrWhiteSpace($"{currentPage}"))
  250. {
  251. dict.Add("currentPage", $"{currentPage}");
  252. }
  253. dict.Add("signKey", "TMD");
  254. var keys = dict.Keys.OrderBy(x => x);
  255. var parmas = string.Join("&", keys.Select(x => $"{x}={dict[x]}"));
  256. var signtime = DateTimeOffset.UtcNow.GetGMTTime(8).ToUnixTimeSeconds();
  257. parmas=$"{parmas}&signtime={signtime}";
  258. string sign = Md5Hash.Encrypt(parmas);
  259. dict.Add("signtime", $"{signtime}");
  260. dict.Add("sign", $"{sign}");
  261. dict.Remove("signKey");
  262. var pkeys = dict.Keys;
  263. string url = "http://www.moofen.net/esi/tmd/question/list";
  264. parmas= string.Join("&", pkeys.Select(x => $"{x}={dict[x]}"));
  265. var httpClient = _httpClient.CreateClient();
  266. var request = new HttpRequestMessage();
  267. request.Method = new HttpMethod("POST");
  268. request.RequestUri = new Uri(url);
  269. request.Content = new FormUrlEncodedContent(dict);
  270. // 设置请求头中的Content-Type
  271. // httpClient.DefaultRequestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
  272. var mediaTypeHeader = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
  273. mediaTypeHeader.CharSet = "UTF-8";
  274. request.Content.Headers.ContentType=mediaTypeHeader;
  275. HttpResponseMessage response = await _httpClient.CreateClient().SendAsync(request);
  276. List<MoofenItemInfo> items = new List<MoofenItemInfo>();
  277. if (response.StatusCode.Equals(HttpStatusCode.OK))
  278. {
  279. content = await response.Content.ReadAsStringAsync();
  280. var data = content.ToObject<JsonElement>();
  281. int count = 0;
  282. if (data.TryGetProperty("data", out JsonElement _data) )
  283. {
  284. if (_data.TryGetProperty("total", out JsonElement _total) && int.TryParse($"{_total}", out count))
  285. {
  286. if (_data.TryGetProperty("data", out JsonElement __data))
  287. {
  288. List<MoofenQuestion> questions = __data.ToObject<List<MoofenQuestion>>();
  289. items = MoofenQS(questions, $"{subject}", schoolId: $"{tokenData.school}", pquestion: null,level:-1);
  290. //foreach (var item in items)
  291. //{
  292. // //break;
  293. // string urlAI = "https://appraisal-test.teammodel.cn/ai/chat/completion";
  294. // ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
  295. // var contentAI = new StringContent(JsonSerializer.Serialize(new
  296. // {
  297. // // appId = "5ac43c20-221e-4564-829d-15680ad761df",
  298. // appId = "eef773fd-85e7-4c2b-a6f7-e667af2f4f45",
  299. // sessionId = "",
  300. // text = item.description,
  301. // }), Encoding.UTF8, "application/json");
  302. // var httpreq = new HttpRequestMessage(HttpMethod.Post, urlAI) { Content = contentAI };
  303. // var authtoken = HttpContext.GetXAuth("AuthToken");
  304. // if (!httpClient.DefaultRequestHeaders.Contains("X-Auth-Authtoken"))
  305. // {
  306. // httpClient.DefaultRequestHeaders.Add("X-Auth-Authtoken", authtoken);
  307. // }
  308. // var AuthorizationToken = HttpContext.GetAuthorization();
  309. // if (httpClient.DefaultRequestHeaders.Contains("Authorization"))
  310. // {
  311. // httpClient.DefaultRequestHeaders.Remove("Authorization");
  312. // }
  313. // httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {AuthorizationToken}");
  314. // httpClient.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
  315. // var responseAI = await httpClient.SendAsync(httpreq, HttpCompletionOption.ResponseHeadersRead);
  316. // if (responseAI.StatusCode==HttpStatusCode.OK)
  317. // {
  318. // StringBuilder dataAI = new StringBuilder();
  319. // // 读取响应内容的异步流
  320. // using (var responseStream = await responseAI.Content.ReadAsStreamAsync())
  321. // {
  322. // //Debug.Print("============start response use minseconds=" + (DateTime.Now - d).TotalMilliseconds + " =================\r\n");
  323. // // 逐块读取并处理响应内容
  324. // var buffer = new byte[1024];
  325. // int bytesRead;
  326. // while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
  327. // {
  328. // // 处理响应内容
  329. // string contentData = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
  330. // if (contentData.Contains("data:"))
  331. // {
  332. // contentData = contentData.Replace("data:", "").Replace("[DONE]", "");
  333. // }
  334. // if (contentData.Contains("[DONE]"))
  335. // {
  336. // contentData = contentData.Replace("data:", "").Replace("[DONE]", "");
  337. // }
  338. // dataAI.Append(contentData);
  339. // }
  340. // }
  341. // item.explain=dataAI.ToString();
  342. // }
  343. //}
  344. }
  345. }
  346. }
  347. return Ok(new { code = 200, data, items , count });
  348. }
  349. else
  350. {
  351. content = await response.Content.ReadAsStringAsync();
  352. return Ok(new { code = response.StatusCode, data = content }) ;
  353. }
  354. } catch (Exception ex) {
  355. await _dingDing.SendBotMsg($"多分题目异常{ex.Message}\n{ex.StackTrace}",GroupNames.成都开发測試群組);
  356. return Ok(new { code = 500,msg=$"{ex.Message}",data= content });
  357. }
  358. }
  359. private List<MoofenItemInfo> MoofenQS(List<MoofenQuestion> questions, string subject,string pquestion,string schoolId, int level, string pid = null)
  360. {
  361. List<MoofenItemInfo> items = new List<MoofenItemInfo>();
  362. if (questions.IsNotEmpty())
  363. {
  364. //综合题 子题id处理
  365. if (!string.IsNullOrWhiteSpace(pid)) {
  366. int index = 1;
  367. foreach (MoofenQuestion question in questions) {
  368. question.questionCode= $"{pid}_{index}";
  369. question.difficulty=level;
  370. index++;
  371. }
  372. }
  373. foreach(var x in questions) {
  374. MoofenItemInfo item = new MoofenItemInfo()
  375. {
  376. id=x.questionCode,
  377. source=4,
  378. question=x.trunk,
  379. option=x.options?.Select(x => new CodeValue { code=x.label, value=x.content }).ToList(),
  380. level=x.difficulty,
  381. knowledge=x.kps?.Select(x => x.kpName).ToList(),
  382. grade=x.scope?.grade?.code,
  383. gradeName=x.scope?.grade?.name,
  384. subject=subject,
  385. pid=pid,
  386. code=!string.IsNullOrWhiteSpace(schoolId)?$"{schoolId}":null,
  387. pk="Item",
  388. scope=!string.IsNullOrWhiteSpace(schoolId) ? "school" : null,
  389. };
  390. //
  391. StringBuilder description = new StringBuilder($"科目:{subject}") ;
  392. if (!string.IsNullOrWhiteSpace(pquestion)) {
  393. description.AppendLine($";综合题:{pquestion}");
  394. }
  395. //处理年级转换
  396. if (!string.IsNullOrWhiteSpace(x.scope?.grade?.code) ) {
  397. item.gradeIds= new List<string>() { x.scope?.grade?.code };
  398. }
  399. if (!string.IsNullOrWhiteSpace(x.type?.code))
  400. {
  401. switch (x.type.code)
  402. {
  403. //选择
  404. case "C":
  405. var lables = x.options?.Where(y => y.correct==true).Select(v => v.label);
  406. if (lables!=null)
  407. {
  408. item.answer=lables.ToList();
  409. }
  410. item.objective=true;
  411. item.type="single";
  412. if (item.answer!=null && item.answer.Count()>1)
  413. {
  414. item.type="multiple";
  415. }
  416. if (x.options.IsNotEmpty())
  417. {
  418. item.opts=x.options.Count();
  419. }
  420. item.field=1;
  421. description.AppendLine(";题型:选择题");
  422. break;
  423. //填空
  424. case "F":
  425. var fills = x.items?.Select(b => b.content);
  426. if (fills!=null)
  427. {
  428. item.answer=fills.ToList();
  429. item.blankCount=fills.Count();
  430. }
  431. item.type="complete";
  432. item.field=2;
  433. description.AppendLine(";题型:填空题");
  434. break;
  435. //问答
  436. case "Q":
  437. if (!string.IsNullOrWhiteSpace(x.content))
  438. {
  439. item.answer=new List<string>() { x.content };
  440. }
  441. item.type="subjective";
  442. description.AppendLine(";题型:问答题");
  443. item.field=4;
  444. break;
  445. //写作
  446. case "W":
  447. if (!string.IsNullOrWhiteSpace(x.content))
  448. {
  449. item.answer=new List<string>() { x.content };
  450. }
  451. item.type="subjective";
  452. description.AppendLine(";题型:写作题");
  453. item.field=6;
  454. break;
  455. //综合
  456. case "S":
  457. item.type="compose";
  458. item.field=3;
  459. if (x.questions.IsNotEmpty() && x.questions.Count>0) {
  460. item.children.AddRange(MoofenQS(x.questions,subject: subject,pquestion: item.question,schoolId:schoolId,pid: item.id,level:x.difficulty));
  461. }
  462. description.AppendLine(";题型:综合题");
  463. break;
  464. }
  465. }
  466. StringBuilder sb = new StringBuilder($"{item.question}");
  467. if (item.option.IsNotEmpty()) {
  468. foreach (var option in item.option)
  469. {
  470. sb.Append(option.value);
  471. }
  472. }
  473. if (item.children.IsNotEmpty()) {
  474. foreach(var child in item.children)
  475. {
  476. sb.Append(child.question);
  477. if (child.option.IsNotEmpty())
  478. {
  479. foreach (var option in child.option)
  480. {
  481. sb.Append(option.value);
  482. }
  483. }
  484. }
  485. }
  486. string unhtml = HtmlHelper.DoUselessTag(sb.ToString());
  487. description.AppendLine($";题干:{item.question}");
  488. if (item.option.IsNotEmpty())
  489. {
  490. description.AppendLine($";选项:");
  491. foreach (var option in item.option) {
  492. description.AppendLine($"{option.code}:{option.value}");
  493. }
  494. }
  495. if(item.answer.IsNotEmpty())
  496. {
  497. description.AppendLine($";答案:{string.Join(",",item.answer)}");
  498. }
  499. if (item.knowledge.IsNotEmpty()) {
  500. description.AppendLine($";知识点:{string.Join(",", item.knowledge)}");
  501. }
  502. //HtmlDocument doc = new HtmlDocument();
  503. //doc.LoadHtml(description.ToString());
  504. item.description = description.ToString().Replace("\r\n","").Replace("&nbsp;","").Replace("\n\n","").Replace("&ldquo;","").Replace("&rdquo;","").Replace("<br />","").Replace("<!--EA-->","").Replace("<!--BA-->","")
  505. .Replace("</sup>","").Replace("<sup>", "").Replace("<u>", "").Replace("</u>", "");
  506. item.shaCode= ShaHashHelper.GetSHA1(unhtml);
  507. items.Add(item);
  508. }
  509. }
  510. return items;
  511. }
  512. [HttpPost("moofen/sso")]
  513. [AuthToken(Roles = "teacher,admin")]
  514. [Authorize(Roles = "IES")]
  515. public async Task<IActionResult> Sso(JsonElement json)
  516. {
  517. (string _id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  518. CoreUser core = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string>()
  519. { { "key",$"{_id}" }
  520. }, "China", _configuration
  521. );
  522. if ( !string.IsNullOrWhiteSpace(core?.mobile))
  523. {
  524. string key = "U@vY42qlgq9ASXLXNqfze%Jj-NQ!ZKrX$iKonXy1u^8F021c7bzo@t5$ANwWCor#";
  525. string code = core?.mobile; //手机号码
  526. var claims = new[]
  527. {
  528. new Claim("code",code)
  529. };
  530. var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
  531. var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
  532. var jwt = new JwtSecurityToken(
  533. claims: claims,
  534. expires: DateTime.Now.AddMinutes(5),
  535. signingCredentials: signinCredentials
  536. );
  537. var tokenString = new JwtSecurityTokenHandler().WriteToken(jwt);
  538. string url = $"http://www.moofen.net/sso/tmodel/login?a={HttpUtility.UrlEncode(tokenString)}&c=doofen&t={DateTimeOffset.Now.ToUnixTimeSeconds()}";
  539. return Ok(new {code=200,url });
  540. }
  541. return Ok(new { code = 400 });
  542. }
  543. }
  544. }