FixDataService.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. using Azure;
  2. using Azure.Cosmos;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Text.Json;
  9. using System.Threading.Tasks;
  10. using TEAMModelOS.SDK.DI;
  11. using TEAMModelOS.SDK.Extension;
  12. using TEAMModelOS.SDK;
  13. using HTEXLib.COMM.Helpers;
  14. using TEAMModelOS.SDK.Models.Cosmos.Common;
  15. using System.Dynamic;
  16. using Newtonsoft.Json;
  17. using TEAMModelOS.Models;
  18. using Azure.Storage.Blobs.Models;
  19. using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
  20. using DinkToPdf.Contracts;
  21. namespace TEAMModelOS.SDK.Models.Service
  22. {
  23. public static class FixDataService
  24. {
  25. public static async Task GenOfflineRecordPdf(AzureCosmosFactory _azureCosmos,DingDing _dingDing , AzureStorageFactory _azureStorage,CoreAPIHttpService _coreAPIHttpService, IConverter _converter, JsonElement element, string msg)
  26. {
  27. try
  28. {
  29. var client = _azureCosmos.GetCosmosClient();
  30. /* var jsonMsg = JsonDocument.Parse(msg);
  31. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  32. //jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);*/
  33. element.TryGetProperty("id", out JsonElement ids);
  34. List<string> tIds = ids.ToObject<List<string>>();
  35. element.TryGetProperty("school", out JsonElement _code);
  36. string code = "";
  37. element.TryGetProperty("Key", out JsonElement key);
  38. if (string.IsNullOrWhiteSpace($"{_code}"))
  39. {
  40. code = $"{key}";
  41. }
  42. else
  43. {
  44. code = $"{_code}";
  45. }
  46. if (string.IsNullOrWhiteSpace(code))
  47. {
  48. await _dingDing.SendBotMsg($"校本研修生成PDF时,学校id为空\n{msg}", GroupNames.成都开发測試群組);
  49. return;
  50. }
  51. string sname = string.Empty;
  52. string areaId = string.Empty;
  53. School school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{code}", new PartitionKey("Base"));
  54. sname = school.name;
  55. areaId = school.areaId;
  56. //var scquery = $"SELECT c.name,c.areaId from c where c.id = '{code}'";
  57. //await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: scquery, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  58. //{
  59. // using var json = await JsonDocument.ParseAsync(item.ContentStream);
  60. // if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  61. // {
  62. // var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  63. // while (accounts.MoveNext())
  64. // {
  65. // JsonElement account = accounts.Current;
  66. // sname = account.GetProperty("name").ToString();
  67. // areaId = account.GetProperty("areaId").ToString();
  68. // }
  69. // }
  70. //}
  71. if (string.IsNullOrWhiteSpace(areaId))
  72. {
  73. await _dingDing.SendBotMsg($"校本研修生成PDF时,区级id为空\n{msg}", GroupNames.成都开发測試群組);
  74. return;
  75. }
  76. if (!tIds.Any())
  77. {
  78. return;
  79. }
  80. var blobclient = _azureStorage.GetBlobContainerClient($"teammodelos");
  81. //查询当前学校所有的校本研修活动
  82. List<Study> studies = new();
  83. var query = $"select value(c) FROM c join b in c.teacIds where b in ({string.Join(",", tIds.Select(o => $"'{o}'"))}) and (c.status<>404 or IS_DEFINED(c.status) = false)";
  84. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<Study>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{code}") }))
  85. {
  86. studies.Add(item);
  87. }
  88. //List<string> tcs = new();
  89. //foreach (var item in studies)
  90. //{
  91. // foreach (var td in item.tchLists)
  92. // {
  93. // if (!tcs.Contains(td))
  94. // {
  95. // tcs.Add(td);
  96. // }
  97. // }
  98. //}
  99. HashSet<string> tcs = studies.SelectMany(x => x.tchLists).Where(y => !string.IsNullOrWhiteSpace(y)).ToHashSet();
  100. (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, tcs.ToList(), code, null);
  101. foreach (string id in tIds)
  102. {
  103. StringBuilder stringBuilder = new StringBuilder();
  104. string cname = string.Empty;
  105. string gname = string.Empty;
  106. if (tchList.Exists(c => c.id == id))
  107. {
  108. gname = tchList.Where(c => c.id == id).FirstOrDefault().groupName;
  109. cname = tchList.Where(c => c.id == id).FirstOrDefault().name;
  110. }
  111. List<string> details = new();
  112. foreach (Study study in studies)
  113. {
  114. if (!study.teacIds.Contains(id))
  115. {
  116. continue;
  117. }
  118. var sresponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(study.id, new PartitionKey($"StudyRecord-{id}"));
  119. if (sresponse.Status == 200)
  120. {
  121. var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  122. StudyRecord record = json.ToObject<StudyRecord>();
  123. if (record.status == 1)
  124. {
  125. var start = DateTimeHelper.FromUnixTimestamp(study.startTime).ToString("yyyy/MM/dd");
  126. var end = DateTimeHelper.FromUnixTimestamp(study.endTime).ToString("yyyy/MM/dd");
  127. string tname = string.Empty;
  128. List<string> setName = new();
  129. foreach (string setting in study.settings)
  130. {
  131. if (setting.Equals("sign"))
  132. {
  133. setName.Add("扫码签到");
  134. }
  135. else if (setting.Equals("hw"))
  136. {
  137. setName.Add("作业提交");
  138. }
  139. else if (setting.Equals("survey"))
  140. {
  141. setName.Add("问卷反馈");
  142. }
  143. else if (setting.Equals("exam"))
  144. {
  145. setName.Add("评测活动");
  146. }
  147. }
  148. switch (study.type)
  149. {
  150. case 1:
  151. tname = "信息化教学案例展示与分享";
  152. break;
  153. case 2:
  154. tname = "专家专题培训";
  155. break;
  156. case 3:
  157. tname = "同课同构";
  158. break;
  159. case 4:
  160. tname = "同课异构";
  161. break;
  162. case 5:
  163. tname = "校本2.0培训";
  164. break;
  165. case 6:
  166. tname = "自定义活动";
  167. break;
  168. };
  169. stringBuilder.Append($@"<tr>
  170. <td> {study.topic} </td>
  171. <td> {tname} </td >
  172. <td> {study.hour} </td >
  173. <td> {study.hour} </td >
  174. <td> {start} 到 {end} </td>
  175. <td>{study.desc}</td>
  176. <td> {string.Join("、", setName.Select(x => $"{x}\n"))} </td>
  177. <td> 已完成 </td >
  178. </tr> ");
  179. }
  180. else
  181. {
  182. continue;
  183. }
  184. }
  185. else
  186. {
  187. continue;
  188. }
  189. }
  190. string url = await StudyService.GenPdf(id, areaId, cname, sname, gname, stringBuilder.ToString(), _converter, _azureStorage, _dingDing);
  191. Azure.Response teacherTrainRes = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(id, new PartitionKey($"TeacherTrain-{code}"));
  192. if (teacherTrainRes.Status == 200)
  193. {
  194. TeacherTrain teacherTrain = JsonDocument.Parse(teacherTrainRes.Content).RootElement.Deserialize<TeacherTrain>();
  195. try
  196. {
  197. BlobDownloadInfo blobDownload = await blobclient.GetBlobClient(url).DownloadAsync(range: new HttpRange(0, 4 * 1048576), rangeGetContentHash: true);
  198. if (blobDownload.Details.ContentHash != null)
  199. {
  200. string hash = Md5Hash.GetbyteToString(blobDownload.Details.ContentHash);
  201. teacherTrain.offlineReport = new Attachment
  202. {
  203. hash = hash,
  204. url = url,
  205. blob = $"{blobclient.Uri}/{url}",
  206. extension = "pdf",
  207. name = $"{teacherTrain.nickname}-校本研修汇总报告.pdf",
  208. type = "doc",
  209. size = blobDownload.ContentLength
  210. };
  211. await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync<TeacherTrain>(teacherTrain, id, new PartitionKey($"TeacherTrain-{code}"));
  212. }
  213. }
  214. catch
  215. {
  216. }
  217. }
  218. }
  219. /*var query = $"select c.id,c.name,c.type,c.hour,c.startTime,c.endTime,c.presenter,c.topic from c where (c.status<>404 or IS_DEFINED(c.status) = false and array_contains(c.teacIds, '{id}') )";
  220. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Study>(queryText: query, requestOptions: new QueryRequestOptions() {PartitionKey = new PartitionKey($"Study-{code}") }))
  221. {
  222. studies.Add(item);
  223. }*/
  224. //(List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(element, null, null, _azureCosmos, _azureRedis);
  225. // string blob = await StudyService.GenPdf(cname,sname,gname,"", _converter);
  226. }
  227. catch (CosmosException ex)
  228. {
  229. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,GenPdfFunc()\n{ex.Message}\n{ex.StackTrace}\n\n{msg}", GroupNames.醍摩豆服務運維群組);
  230. }
  231. catch (Exception ex)
  232. {
  233. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,GenPdfFunc()\n{ex.Message}\n{ex.StackTrace}\n\n{msg}", GroupNames.醍摩豆服務運維群組);
  234. }
  235. }
  236. /// <summary>
  237. /// 修复学生数据
  238. /// </summary>
  239. /// <param name="client"></param>
  240. /// <param name="_dingDing"></param>
  241. /// <param name="_azureStorage"></param>
  242. /// <param name="data"></param>
  243. /// <returns></returns>
  244. public static async Task<List<Student>> FixStudentInfo(CosmosClient client, DingDing _dingDing, AzureStorageFactory _azureStorage, JsonElement data)
  245. {
  246. var code = data.GetProperty("code").GetString();
  247. var ids = data.GetProperty("ids").ToObject<List<string>>();
  248. var dict = data.GetProperty("dict").ToObject<Dictionary<string, object>>();
  249. string queryText = $"SELECT VALUE c FROM c WHERE c.id IN ({string.Join(",", ids.Select(o => $"'{o}'"))})";
  250. List<Student> students = new List<Student>();
  251. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student")
  252. .GetItemQueryIterator<Student>(
  253. queryText: queryText,
  254. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{code}") }))
  255. {
  256. foreach (var key in dict.Keys)
  257. {
  258. switch (key)
  259. {
  260. case "classId":
  261. item.classId = $"{ dict[key]}";
  262. break;
  263. case "periodId":
  264. item.periodId = $"{ dict[key]}";
  265. break;
  266. case "schoolId":
  267. item.schoolId = $"{ dict[key]}";
  268. break;
  269. case "year":
  270. int year = DateTime.Now.Year;
  271. int.TryParse($"dict[key]", out year);
  272. item.year = year;
  273. break;
  274. default:
  275. break;
  276. }
  277. await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<Student>(item, item.id, new PartitionKey(item.code));
  278. students.Add(item);
  279. }
  280. }
  281. return students;
  282. }
  283. /// <summary>
  284. /// 修复内容模块数据
  285. /// </summary>
  286. /// <param name="client"></param>
  287. /// <param name="_dingDing"></param>
  288. /// <param name="_azureStorage"></param>
  289. /// <param name="data"></param>
  290. /// <returns></returns>
  291. public static async Task FixBlobContent(CosmosClient client, DingDing _dingDing, AzureStorageFactory _azureStorage, JsonElement data)
  292. {
  293. if (data.TryGetProperty("doPrivate", out JsonElement _doPrivate) && $"{_doPrivate}".Equals("yes", StringComparison.OrdinalIgnoreCase))
  294. {
  295. foreach (var cnt in _azureStorage.GetBlobServiceClient().GetBlobContainers())
  296. {
  297. if (cnt.Name.Length == 10 && int.TryParse(cnt.Name, out _))
  298. {
  299. await doFixBlob(client, _azureStorage, cnt.Name, "private");
  300. }
  301. }
  302. }
  303. List<School> schools = new List<School>();
  304. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: "select value(c) from c", requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
  305. {
  306. schools.Add(item);
  307. }
  308. foreach (var school in schools)
  309. {
  310. await doFixBlob(client, _azureStorage, school.id, "school");
  311. }
  312. }
  313. private static async Task doFixBlob(CosmosClient client, AzureStorageFactory _azureStorage, string name, string scope)
  314. {
  315. List<string> prefixs = new List<string>() { "audio", "doc", "image", "other", "res", "video" };
  316. var ContainerClient = _azureStorage.GetBlobContainerClient($"{name}");
  317. var tb = "Teacher";
  318. if (scope != "private")
  319. {
  320. tb = "School";
  321. }
  322. List<string> ids = new List<string>();
  323. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, tb).GetItemQueryIterator<Bloblog>(queryDefinition: new QueryDefinition("select c.id from c "), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Bloblog-{name}") }))
  324. {
  325. ids.Add(item.id);
  326. }
  327. await client.GetContainer(Constant.TEAMModelOS, tb).DeleteItemsStreamAsync(ids, $"Bloblog-{name}");
  328. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  329. foreach (var prefix in prefixs)
  330. {
  331. if (prefix.Equals("res"))
  332. {
  333. List<string> itemres = await ContainerClient.List(prefix);
  334. if (itemres.IsNotEmpty())
  335. {
  336. HashSet<string> set = new HashSet<string>();
  337. itemres.ForEach(x =>
  338. {
  339. var uri = x.Split("/");
  340. set.Add($"res/{uri[1]}");
  341. });
  342. foreach (var item in set)
  343. {
  344. var urlsSize = await ContainerClient.GetBlobsSize(item);
  345. var url = item;
  346. if (!item.EndsWith(".hte", StringComparison.OrdinalIgnoreCase) && !item.EndsWith(".HTEX", StringComparison.OrdinalIgnoreCase))
  347. {
  348. url += ".HTEX";
  349. }
  350. Bloblog bloblog = new Bloblog { id = Guid.NewGuid().ToString(), code = $"Bloblog-{name}", pk = "Bloblog", time = now, url = url, size = urlsSize != null && urlsSize.HasValue ? urlsSize.Value : 0, type = prefix };
  351. await client.GetContainer(Constant.TEAMModelOS, tb).UpsertItemAsync(bloblog, new Azure.Cosmos.PartitionKey(bloblog.code));
  352. }
  353. }
  354. }
  355. else
  356. {
  357. List<string> items = await ContainerClient.List(prefix);
  358. if (items.IsNotEmpty())
  359. {
  360. foreach (var item in items)
  361. {
  362. var urlsSize = await ContainerClient.GetBlobsSize(item);
  363. Bloblog bloblog = new Bloblog { id = Guid.NewGuid().ToString(), code = $"Bloblog-{name}", pk = "Bloblog", time = now, url = item, size = urlsSize != null && urlsSize.HasValue ? urlsSize.Value : 0, type = prefix };
  364. await client.GetContainer(Constant.TEAMModelOS, tb).UpsertItemAsync(bloblog, new Azure.Cosmos.PartitionKey(bloblog.code));
  365. }
  366. }
  367. }
  368. }
  369. }
  370. /// <summary>
  371. /// 修復學校基本資料
  372. /// </summary>
  373. /// <param name="client"></param>
  374. /// <param name="schoolCode"></param>
  375. /// <returns></returns>
  376. public static async Task<List<string>> FixSchoolPeriodId(CosmosClient client, string schoolCode)
  377. {
  378. List<string> periodIdList = new List<string>();
  379. await foreach (School schinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: $"SELECT value(c) FROM c WHERE c.id = '{schoolCode}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  380. {
  381. int periodIndex = 0;
  382. foreach (Period periodNow in schinfo.period)
  383. {
  384. if (periodNow.id.Equals("上學期") || periodNow.id.Equals("上学期") || periodNow.id.Equals("First semester"))
  385. {
  386. string periodId = Guid.NewGuid().ToString();
  387. schinfo.period[periodIndex].id = periodId;
  388. periodIdList.Add(periodId);
  389. }
  390. periodIndex++;
  391. }
  392. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(schinfo, schinfo.id, new PartitionKey("Base"));
  393. }
  394. return periodIdList;
  395. }
  396. /// <summary>
  397. /// 修復學校班級資料
  398. /// </summary>
  399. /// <param name="client"></param>
  400. /// <param name="schoolCode"></param>
  401. /// <param name="dataDic"></param>
  402. /// <returns></returns>
  403. public static async Task<List<string>> FixClassInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  404. {
  405. List<string> classIdList = new List<string>();
  406. await foreach (Class classinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Class>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schoolCode}") }))
  407. {
  408. foreach (KeyValuePair<string, string> item in dataDic)
  409. {
  410. switch (item.Key)
  411. {
  412. case "periodId":
  413. classinfo.periodId = item.Value;
  414. break;
  415. }
  416. }
  417. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Class>(classinfo, classinfo.id, new PartitionKey($"Class-{schoolCode}"));
  418. classIdList.Add(classinfo.id);
  419. }
  420. return classIdList;
  421. }
  422. /// <summary>
  423. /// 修復學校課程資料
  424. /// </summary>
  425. /// <param name="client"></param>
  426. /// <param name="schoolCode"></param>
  427. /// <param name="dataDic"></param>
  428. /// <returns></returns>
  429. public static async Task<List<string>> FixCourseInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  430. {
  431. List<string> courseIdList = new List<string>();
  432. await foreach (Course courseinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{schoolCode}") }))
  433. {
  434. foreach (KeyValuePair<string, string> item in dataDic)
  435. {
  436. switch (item.Key)
  437. {
  438. case "periodId":
  439. courseinfo.period.id = item.Value;
  440. break;
  441. }
  442. }
  443. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Course>(courseinfo, courseinfo.id, new PartitionKey($"Course-{schoolCode}"));
  444. courseIdList.Add(courseinfo.id);
  445. }
  446. return courseIdList;
  447. }
  448. /// <summary>
  449. /// 修復學校知識點資料
  450. /// </summary>
  451. /// <param name="client"></param>
  452. /// <param name="schoolCode"></param>
  453. /// <param name="dataDic"></param>
  454. /// <returns></returns>
  455. public static async Task<List<string>> FixKnowledgeInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  456. {
  457. List<string> knowledgeIdList = new List<string>();
  458. await foreach (Knowledge knowledgeinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Knowledge>(queryText: $"SELECT value(c) FROM c WHERE c.pk = 'Knowledge' AND c.owner = '{schoolCode}'", requestOptions: new QueryRequestOptions() { }))
  459. {
  460. foreach (KeyValuePair<string, string> item in dataDic)
  461. {
  462. switch (item.Key)
  463. {
  464. case "periodId":
  465. knowledgeinfo.periodId = item.Value;
  466. break;
  467. }
  468. }
  469. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Knowledge>(knowledgeinfo, knowledgeinfo.id, new PartitionKey($"{knowledgeinfo.code}"));
  470. knowledgeIdList.Add(knowledgeinfo.id);
  471. }
  472. return knowledgeIdList;
  473. }
  474. /// <summary>
  475. /// 修復學校試卷資料
  476. /// </summary>
  477. /// <param name="client"></param>
  478. /// <param name="schoolCode"></param>
  479. /// <param name="dataDic"></param>
  480. /// <returns></returns>
  481. public static async Task<List<string>> FixPaperInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  482. {
  483. List<string> paperIdList = new List<string>();
  484. await foreach (Paper paperinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Paper>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{schoolCode}") }))
  485. {
  486. foreach (KeyValuePair<string, string> item in dataDic)
  487. {
  488. switch (item.Key)
  489. {
  490. case "periodId":
  491. paperinfo.periodId = item.Value;
  492. break;
  493. }
  494. }
  495. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Paper>(paperinfo, paperinfo.id, new PartitionKey($"Paper-{schoolCode}"));
  496. paperIdList.Add(paperinfo.id);
  497. }
  498. return paperIdList;
  499. }
  500. /// <summary>
  501. /// 修復學校課綱資料
  502. /// </summary>
  503. /// <param name="client"></param>
  504. /// <param name="schoolCode"></param>
  505. /// <param name="dataDic"></param>
  506. /// <returns></returns>
  507. public static async Task<List<string>> FixVolumeInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  508. {
  509. List<string> volumeIdList = new List<string>();
  510. await foreach (Volume volumeinfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Volume>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Volume-{schoolCode}") }))
  511. {
  512. foreach (KeyValuePair<string, string> item in dataDic)
  513. {
  514. switch (item.Key)
  515. {
  516. case "periodId":
  517. volumeinfo.periodId = item.Value;
  518. break;
  519. }
  520. }
  521. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Volume>(volumeinfo, volumeinfo.id, new PartitionKey($"Volume-{schoolCode}"));
  522. volumeIdList.Add(volumeinfo.id);
  523. }
  524. return volumeIdList;
  525. }
  526. /// <summary>
  527. /// 修復學校試題資料
  528. /// </summary>
  529. /// <param name="client"></param>
  530. /// <param name="schoolCode"></param>
  531. /// <param name="dataDic"></param>
  532. /// <returns></returns>
  533. public static async Task<List<string>> FixItemInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  534. {
  535. List<string> itemIdList = new List<string>();
  536. await foreach (ItemInfo iteminfo in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ItemInfo>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{schoolCode}") }))
  537. {
  538. foreach (KeyValuePair<string, string> item in dataDic)
  539. {
  540. switch (item.Key)
  541. {
  542. case "periodId":
  543. iteminfo.periodId = item.Value;
  544. break;
  545. }
  546. }
  547. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<ItemInfo>(iteminfo, iteminfo.id, new PartitionKey($"Item-{schoolCode}"));
  548. itemIdList.Add(iteminfo.id);
  549. }
  550. return itemIdList;
  551. }
  552. /// <summary>
  553. /// 修復學校評測資料
  554. /// </summary>
  555. /// <param name="client"></param>
  556. /// <param name="schoolCode"></param>
  557. /// <param name="dataDic"></param>
  558. /// <returns></returns>
  559. public static async Task<List<string>> FixExamInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  560. {
  561. List<string> examIdList = new List<string>();
  562. await foreach (ExamInfo examinfo in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamInfo>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{schoolCode}") }))
  563. {
  564. foreach (KeyValuePair<string, string> item in dataDic)
  565. {
  566. switch (item.Key)
  567. {
  568. case "periodId":
  569. examinfo.period.id = item.Value;
  570. break;
  571. }
  572. }
  573. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ExamInfo>(examinfo, examinfo.id, new PartitionKey($"Exam-{schoolCode}"));
  574. examIdList.Add(examinfo.id);
  575. }
  576. return examIdList;
  577. }
  578. /// <summary>
  579. /// 修復學生資料
  580. /// </summary>
  581. /// <param name="client"></param>
  582. /// <param name="schoolCode"></param>
  583. /// <param name="dataDic"></param>
  584. /// <returns></returns>
  585. public static async Task<List<string>> FixStudentInfo(CosmosClient client, string schoolCode, Dictionary<string, string> dataDic)
  586. {
  587. List<string> studentIdList = new List<string>();
  588. await foreach (Student studentinfo in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"SELECT value(c) FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolCode}") }))
  589. {
  590. foreach (KeyValuePair<string, string> item in dataDic)
  591. {
  592. switch (item.Key)
  593. {
  594. case "periodId":
  595. studentinfo.periodId = item.Value;
  596. break;
  597. }
  598. }
  599. await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<Student>(studentinfo, studentinfo.id, new PartitionKey($"Base-{schoolCode}"));
  600. studentIdList.Add(studentinfo.id);
  601. }
  602. return studentIdList;
  603. }
  604. /// <summary>
  605. /// 修復评测内容
  606. /// </summary>
  607. /// <param name="client"></param>
  608. /// <param name="data"></param>
  609. /// <returns></returns>
  610. public static async Task<List<string>> FixExamPublish(CosmosClient client, DingDing _dingDing, JsonElement data, Option _option)
  611. {
  612. List<string> infos = new List<string>();
  613. //var dict = data.GetProperty("publish").GetInt32();
  614. //List<(string id, string code)> ps = new List<(string id, string code)>();
  615. List<object> exams = new List<object>();
  616. List<Task<ItemResponse<ExamInfo>>> tasks = new List<Task<ItemResponse<ExamInfo>>>();
  617. try {
  618. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"SELECT value(c) FROM c where c.pk = 'Exam' and c.publish = '0'" ))
  619. {
  620. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  621. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  622. {
  623. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  624. {
  625. if (obj.TryGetProperty("publish", out JsonElement publish))
  626. {
  627. try
  628. {
  629. if (string.IsNullOrEmpty(publish.GetString()) || publish.GetString().Equals("0"))
  630. {
  631. ExamInfo examInfo = new ExamInfo
  632. {
  633. id = obj.GetProperty("id").GetString(),
  634. owner = obj.TryGetProperty("owner", out JsonElement owner) ? owner.GetString() : "",
  635. code = obj.TryGetProperty("code", out JsonElement code) ? code.GetString() : "",
  636. //examInfo.owner = obj.GetProperty("owner").GetString();
  637. name = obj.GetProperty("name").GetString(),
  638. school = obj.GetProperty("school").GetString(),
  639. creatorId = obj.GetProperty("creatorId").GetString(),
  640. stuCount = obj.TryGetProperty("stuCount", out JsonElement stuCount) ? stuCount.GetInt32() : 0,
  641. createTime = obj.GetProperty("createTime").GetInt64(),
  642. updateTime = obj.TryGetProperty("updateTime", out JsonElement updateTime) ? updateTime.GetInt64() : DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  643. startTime = obj.TryGetProperty("startTime", out JsonElement startTime) ? startTime.GetInt64() : DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  644. endTime = obj.TryGetProperty("endTime", out JsonElement endTime) ? endTime.GetInt64() : DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  645. year = obj.TryGetProperty("year", out JsonElement year) ? year.GetInt32() : 0,
  646. source = obj.TryGetProperty("source", out JsonElement source) ? source.GetString() : "0",
  647. classes = obj.TryGetProperty("classes", out JsonElement classes) ? classes.ToObject<List<string>>() : new List<string>(),
  648. stuLists = obj.TryGetProperty("stuLists", out JsonElement stuLists) ? stuLists.ToObject<List<string>>() : new List<string>(),
  649. //examInfo.stuLists = obj.GetProperty("stuLists").ToObject<List<string>>();
  650. papers = obj.TryGetProperty("papers", out JsonElement papers) ? papers.ToObject<List<PaperSimple>>() : new List<PaperSimple>(),
  651. type = obj.TryGetProperty("type", out JsonElement type) ? type.GetString() : "",
  652. period = obj.TryGetProperty("period", out JsonElement period) ? period.ToObject<PeriodSimple>() : new PeriodSimple(),
  653. grades = obj.TryGetProperty("grades", out JsonElement grades) ? grades.ToObject<List<Grade>>() : new List<Grade>(),
  654. subjects = obj.GetProperty("subjects").ToObject<List<ExamSubject>>(),
  655. progress = obj.TryGetProperty("progress", out JsonElement progress) ? progress.GetString() : "finish",
  656. scope = obj.TryGetProperty("scope", out JsonElement scope) ? scope.GetString() : "school",
  657. examType = obj.TryGetProperty("examType", out JsonElement examType) ? examType.ToObject<Custom>() : new Custom(),
  658. status = obj.TryGetProperty("status", out JsonElement status) ? status.GetInt32() : 0,
  659. average = obj.TryGetProperty("average", out JsonElement average) ? average.GetDouble() : 0,
  660. sRate = obj.TryGetProperty("sRate", out JsonElement sRate) ? sRate.GetDouble() : 0,
  661. lostStu = obj.TryGetProperty("lostStu", out JsonElement lostStu) ? lostStu.ToObject<List<string>>() : new List<string>(),
  662. standard = obj.TryGetProperty("standard", out JsonElement standard) ? standard.GetDouble() : 0,
  663. size = obj.TryGetProperty("size", out JsonElement size) ? size.GetInt64() : 0,
  664. income = obj.TryGetProperty("income", out JsonElement income) ? income.GetInt32() : 0,
  665. touch = obj.TryGetProperty("touch", out JsonElement touch) ? touch.GetInt32() : 0,
  666. publish = 0,
  667. groupLists = obj.TryGetProperty("groupLists", out JsonElement groupLists) ? groupLists.ToObject<List<Dictionary<string, List<string>>>>() : new List<Dictionary<string, List<string>>>(),
  668. targets = obj.TryGetProperty("targets", out JsonElement targets) ? targets.ToObject<List<JsonElement>>() : new List<JsonElement>()
  669. };
  670. tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ExamInfo>(examInfo, examInfo.id, new PartitionKey(examInfo.code)));
  671. infos.Add(examInfo.id);
  672. };
  673. }
  674. catch (Exception ex)
  675. {
  676. await _dingDing.SendBotMsg($"OS,{_option.Location} /fix-data/fix-publish \n {ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  677. }
  678. }
  679. }
  680. }
  681. }
  682. //await Task.WhenAll(tasks);
  683. int pagesize = 50;
  684. if (tasks.Count <= pagesize)
  685. {
  686. await Task.WhenAll(tasks);
  687. }
  688. else
  689. {
  690. int pages = (tasks.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
  691. for (int i = 0; i < pages; i++)
  692. {
  693. var listssb = tasks.Skip((i) * pagesize).Take(pagesize).ToList();
  694. await Task.WhenAll(listssb);
  695. }
  696. }
  697. } catch (Exception e) {
  698. await _dingDing.SendBotMsg($"OS,{_option.Location} /fix-data/fix-publish \n {e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  699. }
  700. /*foreach (var item in exams) {
  701. dynamic dyn = JsonConvert.DeserializeObject(Convert.ToString(item)) ;
  702. foreach (var obj in dyn)
  703. {
  704. if (obj.Name == "publish")
  705. {
  706. obj.Value = 0;
  707. break;
  708. }
  709. }
  710. ExamInfo info = new ExamInfo();
  711. try {
  712. string dy = JsonConvert.SerializeObject(dyn);
  713. info = JsonConvert.DeserializeObject<ExamInfo>(dy);
  714. } catch (Exception e ) {
  715. //string dy = JsonConvert.SerializeObject(dyn);
  716. }
  717. //await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ExamInfo>(dyn, dyn.id, new PartitionKey(dyn.code));
  718. infos.Add(info.id);
  719. }*/
  720. return infos;
  721. }
  722. public static async Task<List<string>> FixExamClassResult(CosmosClient client, JsonElement data, DingDing _dingDing, CoreAPIHttpService _coreAPIHttpService, Option _option)
  723. {
  724. List<ExamClassResult> results = new List<ExamClassResult>();
  725. List<string> ids = new List<string>();
  726. List<Task<ItemResponse<ExamClassResult>>> tasks = new List<Task<ItemResponse<ExamClassResult>>>();
  727. List<Task<ItemResponse<ExamInfo>>> taskInfo = new List<Task<ItemResponse<ExamInfo>>>();
  728. try
  729. {
  730. /*await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(queryText: $"SELECT value(c) FROM c where c.pk = 'ExamClassResult' and c._ts >= 1640966400"))
  731. {
  732. results.Add(item);
  733. //await Task.WhenAll(tasks);
  734. }
  735. HashSet<string> examIds = new HashSet<string>();
  736. foreach (var item in results)
  737. {
  738. ids.Add(item.id);
  739. examIds.Add(item.examId);
  740. List<int> status = new List<int>();
  741. //List<string> classIds = new List<string>();
  742. //classIds.Add(item.info.id);
  743. if (item.status.Count == 0)
  744. {
  745. if (item.studentAnswers.Count > 0)
  746. {
  747. foreach (var answer in item.studentAnswers)
  748. {
  749. if (answer.Count == 0)
  750. {
  751. item.status.Add(1);
  752. }
  753. else
  754. {
  755. item.status.Add(0);
  756. }
  757. }
  758. }
  759. }
  760. else
  761. {
  762. List<int> vs = new();
  763. foreach (int st in item.status)
  764. {
  765. var ans = (st == -2) ? 1 : 0;
  766. vs.Add(ans);
  767. }
  768. item.status = vs;
  769. }
  770. *//*if (item.progress == true) {
  771. int n = 0;
  772. foreach (string sta in item.studentIds)
  773. {
  774. for (int i = 0; i < item.studentScores[n].Count; i++)
  775. {
  776. if (item.studentScores[n][i] == -1)
  777. {
  778. item.studentScores[n][i] = 0;
  779. }
  780. }
  781. n++;
  782. }
  783. }*//*
  784. tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ExamClassResult>(item, item.id, new PartitionKey(item.code)));
  785. }*/
  786. List<ExamInfo> info = new List<ExamInfo>();
  787. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamInfo>(queryText: $"SELECT value(c) FROM c where c.pk = 'Exam' and c.progress = 'finish' and c._ts >= 1640966400"))
  788. {
  789. info.Add(item);
  790. //await Task.WhenAll(tasks);
  791. }
  792. foreach (var item in info) {
  793. item.updateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  794. taskInfo.Add(client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ExamInfo>(item, item.id, new PartitionKey(item.code)));
  795. }
  796. //TODO 数据量过大的时候暂未处理
  797. await Task.WhenAll(taskInfo);
  798. }
  799. catch (Exception ex)
  800. {
  801. await _dingDing.SendBotMsg($"OS,{_option.Location} /fix-data/fix-classIds \n {ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  802. }
  803. return ids;
  804. }
  805. public static async Task<List<string>> FixSchoolType(CosmosClient client, JsonElement data, DingDing _dingDing, CoreAPIHttpService _coreAPIHttpService, Option _option)
  806. {
  807. List<Task<ItemResponse<School>>> tasks = new List<Task<ItemResponse<School>>>();
  808. List<School> info = new List<School>() ;
  809. try
  810. {
  811. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<School>(queryText: $"SELECT value(c) FROM c ",requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  812. {
  813. info.Add(item);
  814. }
  815. foreach (var item in info)
  816. {
  817. foreach (var period in item.period) {
  818. }
  819. tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<School>(item, item.id, new PartitionKey(item.code)));
  820. }
  821. //TODO 数据量过大的时候暂未处理
  822. await Task.WhenAll(tasks);
  823. }
  824. catch (Exception ex)
  825. {
  826. await _dingDing.SendBotMsg($"OS,{_option.Location} /fix-data/fix-type \n {ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  827. }
  828. var ids = info.Select(x => x.id).ToList();
  829. return ids;
  830. }
  831. }
  832. }