FixDataService.cs 46 KB

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