ChangeController.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. using DocumentFormat.OpenXml.Office2010.ExcelAc;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Newtonsoft.Json.Linq;
  5. using OpenXmlPowerTools;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using TEAMModelOS.Helper.Common.FileHelper;
  11. using TEAMModelOS.SDK;
  12. using TEAMModelOS.SDK.DI;
  13. using TEAMModelOS.SDK.Extension;
  14. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  15. using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
  16. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  17. using TEAMModelOS.SDK.Helper.Common.JsonHelper.JsonPath;
  18. using TEAMModelOS.SDK.Helper.Security.ShaHash;
  19. using TEAMModelOS.SDK.Module.AzureBlob.Container;
  20. using TEAMModelOS.Service.Models;
  21. namespace TEAMModelOS.Controllers.Analysis
  22. {
  23. [Route("api/[controller]")]
  24. [ApiController]
  25. public class ChangeController : Controller
  26. {
  27. private readonly SnowflakeId _snowflakeId;
  28. private readonly IWebHostEnvironment _hostingEnvironment;
  29. public readonly AzureCosmosFactory _azureCosmos;
  30. public readonly AzureStorageFactory _azureStorage;
  31. private const string CacheCosmosPrefix = "Analysis:";
  32. public ChangeController(IWebHostEnvironment hostingEnvironment, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, SnowflakeId snowflakeId)
  33. {
  34. _snowflakeId= snowflakeId;
  35. _hostingEnvironment = hostingEnvironment;
  36. _azureCosmos = azureCosmos;
  37. _azureStorage = azureStorage;
  38. }
  39. [HttpGet("SaveObjectAdas")]
  40. public async Task<BaseResponse> SaveObjectAdasAsync(string identity)
  41. {
  42. // 获取系统路径
  43. string contentRootPath = _hostingEnvironment.ContentRootPath;
  44. identity = "IES/20200716";
  45. //string query = "$.info";
  46. //int countClasses = 0;
  47. //string queryClass = "$member.1.item_answer[*]";
  48. string query = "$.exercises[*]";
  49. string queryInfo = "$.info";
  50. string queryPoint = "$.testpaper.items[*]";
  51. string querySchoolInfo = "$.exercises[0].info";
  52. string data = FileTool.getJson(contentRootPath, identity);
  53. data = FileTool.UnicodeToString(data);
  54. JObject parsedJson = JObject.Parse(data);
  55. JsonPathContext context = new JsonPathContext
  56. { ValueSystem = new JsonApiValueSystem() };
  57. //解析试卷作答详情
  58. List<dynamic> papers = context.SelectNodes(parsedJson,
  59. query).Select(node => node.Value).ToList();
  60. //解析试卷基本信息
  61. List<dynamic> info = context.SelectNodes(parsedJson,
  62. queryInfo).Select(node => node.Value).ToList();
  63. //解析题库信息
  64. List<dynamic> Itempoint = context.SelectNodes(parsedJson,
  65. queryPoint).Select(node => node.Value).ToList();
  66. //解析学校信息
  67. List<dynamic> SchoolInfo = context.SelectNodes(parsedJson,
  68. querySchoolInfo).Select(node => node.Value).ToList();
  69. int m = 0;
  70. //人数总和
  71. int Count = 0;
  72. //起始坐标
  73. int Strat = 0;
  74. // 初始化学生人数
  75. int Stus = 0;
  76. ExamResult simple = new ExamResult();
  77. ExamAnswer examAnswer = new ExamAnswer();
  78. List<Student> students = new List<Student>();
  79. List<Classroom> classrooms = new List<Classroom>();
  80. //List<ExamAnswer> examAnswers = new List<ExamAnswer>();
  81. List<List<List<int>>> ClassPoint = new List<List<List<int>>>();
  82. List<List<double>> StuPoint = new List<List<double>>();
  83. List<string> StuIds = new List<string>();
  84. List<List<string>> stuAnswers = new List<List<string>>();
  85. List<Dictionary<string, int[]>> Classes = new List<Dictionary<string, int[]>>();
  86. Dictionary<object, object> ListInfo = new Dictionary<object, object>();
  87. List<double> points = new List<double>();
  88. //配分数组
  89. Paper paper = new Paper();
  90. List<ItemInfo> items = new List<ItemInfo>();
  91. int k = 0;
  92. Itempoint.ForEach(p =>
  93. {
  94. string pt = p.point;
  95. string OpenTracing = p + "";
  96. JObject jArray = JObject.Parse(OpenTracing);
  97. string queryOptions = "$.options[*]";
  98. List<dynamic> itemOption = context.SelectNodes(jArray,
  99. queryOptions).Select(node => node.Value).ToList();
  100. List<CodeValue> codeValues = new List<CodeValue>();
  101. itemOption.ToList<dynamic>().ForEach(i =>
  102. {
  103. CodeValue code = new CodeValue
  104. {
  105. code = i.data,
  106. value = i.type
  107. };
  108. codeValues.Add(code);
  109. });
  110. //题序
  111. string order = p.itemindex;
  112. string ans = p.answer;
  113. string knowlege = p.idx_desc;
  114. ItemInfo item = new ItemInfo
  115. {
  116. question = p.content,
  117. score = double.Parse(pt),
  118. answer = new List<string> {
  119. ans
  120. },
  121. type = p.type,
  122. order = int.Parse(order),
  123. //level = p.edu_goal,
  124. option = codeValues,
  125. points = new List<string> {
  126. knowlege
  127. }
  128. };
  129. items.Add(item);
  130. k++;
  131. points.Add(double.Parse(pt.Trim()));
  132. });
  133. //处理试卷信息
  134. paper.item = items;
  135. paper.subjectCode = "Subject_Math";
  136. //基本信息
  137. info.ForEach(e =>
  138. {
  139. simple.name = e.test_name;
  140. simple.time = e.test_date;
  141. paper.name = e.test_name;
  142. });
  143. School sc = null;
  144. ExamInfo examInfo = null;
  145. SchoolInfo.ForEach(s =>
  146. {
  147. string count = s.stucount;
  148. string st = s.ex_time;
  149. string ed = s.ex_endtime;
  150. DateTime.TryParse(st, out DateTime tt);
  151. DateTime.TryParse(ed, out DateTime etime);
  152. long time = DateTimeHelper.ToUnixTimestamp(tt);
  153. long edtime = DateTimeHelper.ToUnixTimestamp(etime);
  154. sc = new School
  155. {
  156. schoolCode = "88924E4C-F00D-4A1D-B2C3-234F930F29D4",
  157. schoolName = s.school_name,
  158. period = new List<Period> { new Period {periodName = "小学" , periodCode = "c3e1e95a-561e-fabf-cce3-3a564782e443",grades= new List<Grade> {
  159. new Grade { gradeName = "四年级" ,gradeCode = "4"} } } }
  160. };
  161. //考试基本信息
  162. examInfo = new ExamInfo
  163. {
  164. id = _snowflakeId.NextId()+"",
  165. code = "88924E4C-F00D-4A1D-B2C3-234F930F29D4",
  166. name = s.ex_name,
  167. type = s.ex_type,
  168. examCode = "QCSCS",
  169. startTime = time,
  170. endTime = edtime,
  171. stuCount = int.Parse(count),
  172. conditions = new Condition
  173. {
  174. period = "c3e1e95a-561e-fabf-cce3-3a564782e443",
  175. grade = s.grade_name,
  176. semester = s.semester,
  177. subject = new List<string> { "Subject_Math" }
  178. }
  179. };
  180. });
  181. papers.ForEach(x =>
  182. {
  183. //var c = papers[i].member;
  184. string stu = x.info.stucount;
  185. int k = int.Parse(stu);
  186. string key = x.info.class_name;
  187. string schoolName = x.info.school_name;
  188. Classroom classInfo = new Classroom
  189. {
  190. id = _snowflakeId.NextId() + "",
  191. classroomName = key,
  192. //classroomType = schoolName,
  193. studentCount = k,
  194. classroomCode = "qcs"
  195. };
  196. classrooms.Add(classInfo);
  197. Classroom classInfoOfStudent = new Classroom
  198. {
  199. classroomName = key,
  200. //schoolCode = schoolName,
  201. //studentCount = k,
  202. classroomCode = "qcs"
  203. };
  204. Dictionary<string, int[]> map = new Dictionary<string, int[]>();
  205. int[] Range = new int[2];
  206. //处理学生作答数据
  207. for (int j = 0; j < 22; j++)
  208. {
  209. Student stus = new Student
  210. {
  211. type = 2,
  212. //schoolCode = schoolName
  213. };
  214. string men = x.members[j] + "";
  215. JObject jArray = JObject.Parse(men);
  216. string queryClass = "$.item_answers[*]";
  217. string queryStu = "$.info";
  218. List<string> ans = new List<string>();
  219. List<dynamic> answers = context.SelectNodes(jArray,
  220. queryClass).Select(node => node.Value).ToList();
  221. //学生ID集合
  222. List<dynamic> studentIds = context.SelectNodes(jArray,
  223. queryStu).Select(node => node.Value).ToList();
  224. List<double> point = new List<double>();
  225. if (answers.Count == 0)
  226. {
  227. StuIds.Add("0");
  228. k++;
  229. }
  230. else
  231. {
  232. //处理学生信息
  233. studentIds.ToList<dynamic>().ForEach(s =>
  234. {
  235. string id = s.student_id;
  236. //id = System.Guid.NewGuid().ToString();
  237. stus.id = id.Trim();
  238. stus.name = s.name;
  239. stus.studentId = id.Trim();
  240. string sno = s.seatno;
  241. if (sno.Equals(""))
  242. {
  243. stus.seatNo = 0;
  244. }
  245. else
  246. {
  247. stus.seatNo = int.Parse(sno);
  248. }
  249. //stus.classroom = classInfoOfStudent;
  250. StuIds.Add(id.Trim());
  251. });
  252. students.Add(stus);
  253. }
  254. answers.ToList<dynamic>().ForEach(p =>
  255. {
  256. string pt = p.real_point;
  257. string ansContent = p.ans_content;
  258. if (ans.Equals(""))
  259. {
  260. ansContent = "无";
  261. }
  262. ans.Add(ansContent);
  263. point.Add(double.Parse(pt.Trim()));
  264. });
  265. stuAnswers.Add(ans);
  266. StuPoint.Add(point);
  267. Stus++;
  268. }
  269. //每次人数累加得到实际总人数
  270. Count += Stus;
  271. if (m == 0)
  272. {
  273. Strat = Stus;
  274. Range[0] = 0;
  275. Range[1] = Stus - 1;
  276. }
  277. else
  278. {
  279. Range[0] = Count - Stus;
  280. Range[1] = Count - 1;
  281. }
  282. map.Add(key, Range);
  283. Classes.Add(map);
  284. m++;
  285. //初始化每个班级人数
  286. Stus = 0;
  287. //ClassPoint.Add(StuPoint);
  288. });
  289. examAnswer.answer = stuAnswers;
  290. examAnswer.code = examInfo.examCode;
  291. paper.code = examInfo.examCode;
  292. simple.code = examInfo.examCode;
  293. simple.classes = Classes;
  294. simple.ids = StuIds;
  295. simple.point = points;
  296. simple.result = StuPoint;
  297. simple.subjectCode = paper.subjectCode;
  298. ResponseBuilder builder = ResponseBuilder.custom();
  299. Dictionary<string, object> keyValues = new Dictionary<string, object> {
  300. { "schoolInfo",sc},
  301. { "classInfo",classrooms},
  302. { "examInfo",examInfo},
  303. { "students",students},
  304. { "paperInfo",paper},
  305. { "examResult",simple},
  306. { "examAnswer",examAnswer}
  307. };
  308. AzureBlobModel modle = await _azureStorage.UploadFileByContainer("hbcn", keyValues.ToJsonString(), "exam", sc.schoolCode + examInfo.examCode + paper.subjectCode + ".json");
  309. //examInfo.blobUrl = modle.BlobUrl;
  310. //判定是否存储考试基本信息
  311. Dictionary<string, object> sub = new Dictionary<string, object>
  312. {
  313. { "examCode", examInfo.examCode}
  314. };
  315. List<ExamInfo> eInfo = await _azureCosmos.FindByDict<ExamInfo>(sub);
  316. if (eInfo.Count > 0)
  317. {
  318. eInfo.ForEach(e =>
  319. {
  320. if (e.conditions.subject.Contains(paper.subjectCode))
  321. {
  322. builder.Data("").build();
  323. }
  324. else
  325. {
  326. e.conditions.subject = new List<string>{ paper.subjectCode };
  327. e.blobUrl = new List<string> { modle.BlobUrl };
  328. }
  329. });
  330. }
  331. else {
  332. examInfo.blobUrl = new List<string> { modle.BlobUrl };
  333. await _azureCosmos.Save(examInfo);
  334. }
  335. //Redis处理考试结果数据集合
  336. if (RedisHelper.Instance != null)
  337. {
  338. await RedisHelper.HSetAsync(CacheCosmosPrefix + "examResult" + simple.subjectCode, ShaHashHelper.GetSHA1(examInfo.examCode), simple);
  339. await RedisHelper.HSetAsync(CacheCosmosPrefix + "students", ShaHashHelper.GetSHA1(sc.schoolCode), students);
  340. await RedisHelper.HSetAsync(CacheCosmosPrefix + "paperInfo" + simple.subjectCode, ShaHashHelper.GetSHA1(examInfo.examCode), paper);
  341. await RedisHelper.HSetAsync(CacheCosmosPrefix + "examAnswer" + simple.subjectCode, ShaHashHelper.GetSHA1(examInfo.examCode), examAnswer);
  342. await RedisHelper.HSetAsync(CacheCosmosPrefix + "classInfo", ShaHashHelper.GetSHA1(sc.schoolCode), classrooms);
  343. await RedisHelper.HSetAsync(CacheCosmosPrefix + "schoolInfo", ShaHashHelper.GetSHA1(sc.schoolCode), sc);
  344. }
  345. //_examInfoService.SaveToCosmos(simple);
  346. //_cosmosrepository.Save(sc);
  347. /*_cosmosrepository.Save(simple);
  348. _cosmosrepository.Save(examAnswer);*/
  349. //_cosmosrepository.SaveAll(classrooms);
  350. //_cosmosrepository.SaveOrUpdateAll(students);
  351. //_examInfoService.SaveListToCosmos(students);
  352. return builder.Data(sc).build();
  353. //return builder.build();
  354. }
  355. [HttpGet("SaveExamToBlob")]
  356. public async Task<BaseResponse> SendExam(JosnRequest<Dictionary<string, object>> request)
  357. {
  358. ResponseBuilder builder = ResponseBuilder.custom();
  359. Student student = null;
  360. List<Student> AnalysisStudents = new List<Student>();
  361. ExamInfo examInfo = null;
  362. ExamResult result = null;
  363. if (request.@params.TryGetValue("id", out object id) && request.@params.TryGetValue("pk", out object pk))
  364. {
  365. examInfo = await _azureCosmos.FindByIdPk<ExamInfo>(id.ToString(), pk.ToString());
  366. //获取发布对象
  367. if (request.@params.TryGetValue("schoolCode", out object schoolCode))
  368. {
  369. List<string> targetCode = examInfo.target;
  370. List<ClassStudent> classroomStudents = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", targetCode } });
  371. List<Student> students = await _azureCosmos.FindByDict<Student>(
  372. new Dictionary<string, object>() { { "classroomCode", targetCode }, { "code", schoolCode } },
  373. new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
  374. List<dynamic> stus = new List<dynamic>();
  375. List<ClassStudent> newClassStudents = new List<ClassStudent>();
  376. ///新增的学生
  377. if (students.IsNotEmpty())
  378. {
  379. students.ForEach(x =>
  380. {
  381. if (!classroomStudents.Select(m => m.code).Contains(x.studentId))
  382. {
  383. newClassStudents.Add(new ClassStudent() { id = x.classroomCode, code = x.studentId });
  384. }
  385. var stu = new { x.id, x.name, x.code, x.seatNo, x.studentId, x.classroomCode };
  386. stus.Add(stu);
  387. });
  388. }
  389. ///反射已存在的id信息
  390. if (classroomStudents.IsNotEmpty())
  391. {
  392. ///处理冗余的id查询
  393. List<string> ids = new List<string>();
  394. classroomStudents.ForEach(x =>
  395. {
  396. if (!students.Select(m => m.studentId).Contains(x.code))
  397. {
  398. ids.Add(x.code);
  399. }
  400. });
  401. var sts = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids.ToArray() } });
  402. if (sts.IsNotEmpty())
  403. {
  404. sts.ForEach(x =>
  405. {
  406. var stu = new { x.id, x.name, x.code, x.seatNo, x.studentId, x.classroomCode };
  407. stus.Add(stu);
  408. });
  409. }
  410. }
  411. //保存新增学生
  412. if (newClassStudents.IsNotEmpty())
  413. {
  414. classroomStudents.AddRange(await _azureCosmos.SaveOrUpdateAll(newClassStudents));
  415. }
  416. //处理学生信息以便学情使用
  417. int n = 1;
  418. stus.ForEach(s => {
  419. student = new Student
  420. {
  421. id = s[0],
  422. name = s[1],
  423. studentId = s[4],
  424. seatNo = n,
  425. classroomCode = s[5]
  426. };
  427. n++;
  428. AnalysisStudents.Add(student);
  429. });
  430. //依次处理班级信息
  431. targetCode.ForEach(c =>
  432. {
  433. int count = 0;
  434. AnalysisStudents.ForEach(s => {
  435. if (c.Equals(s.classroomCode))
  436. {
  437. count++;
  438. }
  439. //处理学生作答以及学生得分记录
  440. });
  441. });
  442. result = new ExamResult
  443. {
  444. code = examInfo.id,
  445. name = examInfo.name,
  446. };
  447. //return builder.Data(classroomStudents).Extend(new Dictionary<string, object> { { "students", stus }, { "count", stus.Count } }).build();
  448. }
  449. else {
  450. return builder.build();
  451. }
  452. }
  453. else
  454. {
  455. return builder.build();
  456. }
  457. return builder.Data("").build();
  458. }
  459. }
  460. }