FixDataService.cs 46 KB

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