StatisticsService.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. using Azure.Cosmos;
  2. using Azure.Messaging.ServiceBus;
  3. using HTEXLib.COMM.Helpers;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.Extensions.Configuration;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.SDK.DI;
  12. using TEAMModelOS.SDK.Extension;
  13. using TEAMModelOS.SDK.Models;
  14. namespace TEAMModelOS.SDK
  15. {
  16. public static class StatisticsService
  17. {
  18. /// <summary>
  19. /// 教师能力点操作
  20. /// </summary>
  21. public const string TeacherAility = "TeacherAility";
  22. /// <summary>
  23. /// 课堂实录
  24. /// </summary>
  25. public const string TeacherClass = "TeacherClass";
  26. /// <summary>
  27. /// 线下研修
  28. /// </summary>
  29. public const string OfflineRecord = "OfflineRecord";
  30. /// <summary>
  31. /// 教师投票活动
  32. /// </summary>
  33. public const string TeacherVote = "TeacherVote";
  34. /// <summary>
  35. /// 教师作业活动
  36. /// </summary>
  37. public const string TeacherHomework = "TeacherHomework";
  38. /// <summary>
  39. /// 教师问卷活动
  40. /// </summary>
  41. public const string TeacherSurvey = "TeacherSurvey";
  42. /// <summary>
  43. /// 教师评测活动
  44. /// </summary>
  45. public const string TeacherExamLite = "TeacherExamLite";
  46. public static async Task SendServiceBus(string standard,string tmdid,string school,string update,int statistics, IConfiguration _configuration, AzureServiceBusFactory _serviceBus) {
  47. TeacherTrainChange change = new TeacherTrainChange
  48. {
  49. standard = standard,
  50. tmdid =tmdid,
  51. school =school,
  52. update = new HashSet<string>(new List<string> { update }),
  53. statistics = statistics
  54. };
  55. var messageChange = new ServiceBusMessage(change.ToJsonString());
  56. messageChange.ApplicationProperties.Add("name", "TeacherTrainChange");
  57. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  58. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  59. }
  60. public static async Task GetAreaAndAreaSetting( string schoolId, string _standard, CosmosClient client, HttpContext httpContext)
  61. {
  62. School school = null;
  63. AreaSetting setting = null;
  64. string standard = "";
  65. if (string.IsNullOrEmpty(_standard))
  66. {
  67. standard = _standard;
  68. }
  69. else if(!string.IsNullOrEmpty(schoolId)) {
  70. //优先找校级
  71. setting = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<AreaSetting>(schoolId, new PartitionKey("AreaSetting"));
  72. //优先找校级
  73. school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(schoolId, new PartitionKey("Base"));
  74. }
  75. }
  76. public static async Task<List<(List<TeacherTrain> trains, List<RGroupList> yxtrain)>> StatisticsArea(AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet<string> updates)
  77. {
  78. List<(List<TeacherTrain> trains, List<RGroupList> yxtrain)> teacherTrains = new List<(List<TeacherTrain> trains, List<RGroupList> yxtrain)>() ;
  79. List<School> schools = new List<School>();
  80. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School")
  81. .GetItemQueryIterator<School>(queryText: $"select value(c) from c where c.areaId='{area.id}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  82. {
  83. schools.Add(item);
  84. }
  85. await foreach ((List<TeacherTrain> trains, List<RGroupList> yxtrain) tarain in GetStatisticsSchool(schools, setting, area, client,_dingDing,updates))
  86. {
  87. teacherTrains.Add(tarain);
  88. }
  89. return teacherTrains;
  90. }
  91. private static async IAsyncEnumerable<(List<TeacherTrain> trains, List<RGroupList> yxtrain)> GetStatisticsSchool(List<School> schools, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet<string> updates)
  92. {
  93. foreach (var school in schools)
  94. {
  95. yield return await StatisticsSchool(school.id, setting, area, client,_dingDing,updates);
  96. }
  97. }
  98. public static async Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain)> StatisticsSchool(string school, AreaSetting setting, Area area, CosmosClient client,DingDing _dingDing,HashSet<string> updates) {
  99. List<RGroupList> yxtrain = await GroupListService.GetGroupListMemberByType(client, "yxtrain", new List<string> { "school" }, $"{school}", _dingDing);
  100. List<TeacherTrain> trains = new List<TeacherTrain>();
  101. var members = yxtrain.SelectMany(x => x.members).ToList();
  102. if (members.Count <= 0)
  103. {
  104. return (trains, yxtrain);
  105. }
  106. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher")
  107. .GetItemQueryIterator<TeacherTrain>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"TeacherTrain-{school}") })) {
  108. trains.Add(item);
  109. }
  110. if (updates != null) {
  111. foreach (var up in updates)
  112. {
  113. trains.ForEach(x => x.updateProperty.Add(up));
  114. }
  115. }
  116. var update = trains.FindAll(x => x.updateProperty.Count() > 0);
  117. var noupdate = trains.FindAll(x => x.updateProperty.Count() <=0);
  118. var unStatistics = members.Select(x => x.id).Except(trains.Select(x => x.id));
  119. List<TeacherTrain> teacherTrains = new List<TeacherTrain>();
  120. List<TeacherTrain> returnTrains = new List<TeacherTrain>();
  121. if (update.IsNotEmpty()) {
  122. teacherTrains.AddRange(update);
  123. }
  124. if (unStatistics != null) {
  125. foreach (string x in unStatistics) {
  126. var member = members.Find(y => y.id.Equals(x));
  127. teacherTrains.Add(new TeacherTrain
  128. {
  129. pk = "TeacherTrain",
  130. id = x,
  131. code = $"TeacherTrain-{school}",
  132. tmdid = x,
  133. name = member.name,
  134. picture=member.picture,
  135. school = school,
  136. updateProperty = new HashSet<string> { TeacherAility,TeacherClass,OfflineRecord }
  137. });
  138. }
  139. }
  140. List<Study> studies = new List<Study>();
  141. await foreach (var item in client.GetContainer("TEAMModelOS", "Common")
  142. .GetItemQueryIterator<Study>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{school}") }))
  143. {
  144. studies.Add(item);
  145. }
  146. returnTrains = await GetStatisticsTeacher(teacherTrains, setting, area, client,studies);
  147. //await foreach (var tarain in GetStatisticsTeacher(teacherTrains, setting, area, client))
  148. //{
  149. // returnTrains.Add(tarain);
  150. //}
  151. if (noupdate.IsNotEmpty())
  152. {
  153. returnTrains.AddRange(noupdate);
  154. }
  155. returnTrains.ForEach(x => {
  156. var mbm= members.Find(y => y.id.Equals(x.id));
  157. x.groupName = mbm?.groupName;
  158. x.name = mbm?.name;
  159. x.picture = mbm?.picture;
  160. });
  161. return (returnTrains, yxtrain);
  162. }
  163. private static async Task<List<TeacherTrain>> GetStatisticsTeacher(List<TeacherTrain> trains, AreaSetting setting, Area area, CosmosClient client, List<Study> studies)
  164. {
  165. List<Task<TeacherTrain>> teachers = new List<Task<TeacherTrain>>();
  166. foreach (var train in trains)
  167. {
  168. teachers.Add(StatisticsTeacher(train, setting, area, client,studies)); //yield return await StatisticsTeacher( train, setting, area, client);
  169. }
  170. int pagesize = 50;
  171. if (teachers.Count <= pagesize)
  172. {
  173. await Task.WhenAll(teachers);
  174. }
  175. else
  176. {
  177. int pages = (teachers.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
  178. for (int i = 0; i < pages; i++)
  179. {
  180. var lists = teachers.Skip((i) * pagesize).Take(pagesize).ToList();
  181. await Task.WhenAll(lists);
  182. }
  183. }
  184. return trains;
  185. }
  186. public static async Task<TeacherTrain> StatisticsTeacher(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client,List<Study> studies) {
  187. string _school = train.school;
  188. string _tmdid = train.tmdid;
  189. // TeacherTrain teacher_train = null;
  190. List<Task<TeacherTrain>> teachers = new List<Task<TeacherTrain>>();
  191. if (train.updateProperty.Count > 0) {
  192. foreach (string property in train.updateProperty) {
  193. teachers.Add(DoProperty(train.updateProperty, property, setting, area, client, train,studies));
  194. }
  195. int pagesize = 50;
  196. if (teachers.Count <= pagesize)
  197. {
  198. await Task.WhenAll(teachers);
  199. }
  200. else
  201. {
  202. int pages = (teachers.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
  203. for (int i = 0; i < pages; i++)
  204. {
  205. var lists = teachers.Skip((i) * pagesize).Take(pagesize).ToList();
  206. await Task.WhenAll(lists);
  207. }
  208. }
  209. }
  210. //每次都统计活动相关的数据。
  211. // train= await DoActivity(train, setting, area, client, _school, _tmdid);
  212. train.totalTime = train.onlineTime + train.classTime + train.currency.submitTime + train.offlineTime;
  213. if (train.totalTime >= setting.allTime)
  214. {
  215. //如果总学生超过50 且不是优秀则至少是合格。
  216. if (train.finalScore != 2)
  217. {
  218. train.finalScore = 1;
  219. }
  220. }
  221. // 50> 学时>0 是不合格
  222. else if (train.totalTime < setting.allTime && train.totalTime > 0)
  223. {
  224. train.finalScore = 0;
  225. }
  226. else {
  227. //学时<=0 则是为
  228. train.finalScore = -1;
  229. }
  230. await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TeacherTrain>(train, new PartitionKey($"TeacherTrain-{_school}"));
  231. return train;
  232. }
  233. private static async Task<TeacherTrain> DoProperty(HashSet<string> updateProperty,string property, AreaSetting setting, Area area, CosmosClient client, TeacherTrain train ,List<Study> studies )
  234. {
  235. string _school = train.school;
  236. string _tmdid = train.tmdid;
  237. switch (property) {
  238. case TeacherAility:
  239. train = await DoTeacherAility(train, setting, area, client, _school, _tmdid);
  240. train.updateProperty.Remove(TeacherAility);
  241. break;
  242. //课堂实录更新
  243. case TeacherClass:
  244. train = await DoTeacherClass(train, setting, area, client, _school, _tmdid);
  245. train.updateProperty.Remove(TeacherClass);
  246. break;
  247. //线下研修
  248. case OfflineRecord:
  249. train = await DoOfflineRecord(train, setting, area, client, _school, _tmdid,studies);
  250. train.updateProperty.Remove(OfflineRecord);
  251. break;
  252. //投票
  253. case TeacherVote:
  254. train = await DoTeacherVote(train, setting, area, client, _school, _tmdid);
  255. train.updateProperty.Remove(TeacherVote);
  256. break;
  257. //问卷
  258. case TeacherSurvey:
  259. train = await DoTeacherSurvey(train, setting, area, client, _school, _tmdid);
  260. train.updateProperty.Remove(TeacherSurvey);
  261. break;
  262. //作业
  263. //case TeacherHomework:
  264. // train = await DoTeacherHomework(train, setting, area, client, _school, _tmdid);
  265. // train.updateProperty.Remove(TeacherHomework);
  266. // break;
  267. //评测
  268. case TeacherExamLite:
  269. train = await DoTeacherExamLite(train, setting, area, client, _school, _tmdid);
  270. train.updateProperty.Remove(TeacherExamLite);
  271. break;
  272. default:
  273. train.updateProperty.Remove(property);
  274. break;
  275. }
  276. return train;
  277. }
  278. public static async Task<TeacherTrain> DoTeacherVote(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) {
  279. int voteJoin = 0;
  280. int voteDone = 0;
  281. int voteAreaJoin = 0;
  282. int voteAreaDone = 0;
  283. //投票活动
  284. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  285. .GetItemQueryIterator<StuActivity>(queryText: $"select c.owner, c.taskStatus from c where c.type = 'Vote' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") }))
  286. {
  287. if (!string.IsNullOrEmpty(item.owner))
  288. {
  289. if (item.owner.Equals("school"))
  290. {
  291. voteJoin += 1;
  292. if (item.taskStatus > 0)
  293. {
  294. voteDone += 1;
  295. }
  296. }
  297. else if (item.owner.Equals("area"))
  298. {
  299. voteAreaJoin += 1;
  300. if (item.taskStatus > 0)
  301. {
  302. voteAreaDone += 1;
  303. }
  304. }
  305. }
  306. }
  307. train.voteJoin = voteJoin;
  308. train.voteDone = voteDone;
  309. train.voteAreaJoin = voteAreaJoin;
  310. train.voteAreaDone = voteAreaDone;
  311. return train;
  312. }
  313. public static async Task<TeacherTrain> DoTeacherSurvey(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid)
  314. {
  315. //问卷调查
  316. int surveyJoin = 0;
  317. int surveyDone = 0;
  318. int surveyAreaJoin = 0;
  319. int surveyAreaDone = 0;
  320. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher")
  321. .GetItemQueryIterator<StuActivity>(queryText: $"select c.owner, c.taskStatus from c where c.type = 'Survey' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") }))
  322. {
  323. if (!string.IsNullOrEmpty(item.owner))
  324. {
  325. if (item.owner.Equals("school"))
  326. {
  327. surveyJoin += 1;
  328. if (item.taskStatus > 0)
  329. {
  330. surveyDone += 1;
  331. }
  332. }
  333. else if (item.owner.Equals("area"))
  334. {
  335. surveyAreaJoin += 1;
  336. if (item.taskStatus > 0)
  337. {
  338. surveyAreaDone += 1;
  339. }
  340. }
  341. }
  342. }
  343. train.surveyJoin = surveyJoin;
  344. train.surveyDone = surveyDone;
  345. train.surveyAreaJoin = surveyAreaJoin;
  346. train.surveyAreaDone = surveyAreaDone;
  347. return train;
  348. }
  349. public static async Task<TeacherTrain> DoTeacherExamLite(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid)
  350. {
  351. //问卷调查
  352. int examJoin = 0;
  353. int examDone = 0;
  354. int examAreaJoin = 0;
  355. int examAreaDone = 0;
  356. //评量检测
  357. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  358. .GetItemQueryIterator<StuActivity>(queryText: $"select c.owner, c.taskStatus from c where c.type = 'ExamLite' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") }))
  359. {
  360. if (!string.IsNullOrEmpty(item.owner))
  361. {
  362. if (item.owner.Equals("school"))
  363. {
  364. examJoin += 1;
  365. if (item.taskStatus > 0)
  366. {
  367. examDone += 1;
  368. }
  369. }
  370. else if (item.owner.Equals("area"))
  371. {
  372. examAreaJoin += 1;
  373. if (item.taskStatus > 0)
  374. {
  375. examAreaDone += 1;
  376. }
  377. }
  378. }
  379. }
  380. train.examJoin = examJoin;
  381. train.examDone = examDone;
  382. train.examAreaJoin = examAreaJoin;
  383. train.examAreaDone = examAreaDone;
  384. return train;
  385. }
  386. /// <summary>
  387. /// 课堂实录更新
  388. /// </summary>
  389. /// <param name="train"></param>
  390. /// <param name="setting"></param>
  391. /// <param name="area"></param>
  392. /// <param name="client"></param>
  393. /// <param name="_school"></param>
  394. /// <param name="_tmdid"></param>
  395. /// <returns></returns>
  396. public static async Task<TeacherTrain> DoOfflineRecord(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid, List<Study> studies) {
  397. //owner: school area
  398. //线下 学校研修活动
  399. List<StuActivity> activities = new List<StuActivity>();
  400. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  401. .GetItemQueryIterator<StuActivity>(queryText: $"select value(c) from c where c.type = 'Study' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") }))
  402. {
  403. activities.Add(item);
  404. }
  405. string insql = "";
  406. if (studies.IsEmpty()) {
  407. studies = new List<Study>();
  408. if (activities.IsNotEmpty())
  409. {
  410. insql = $" where c.id in ({string.Join(",", activities.Select(o => $"'{o.id}'"))})";
  411. }
  412. await foreach (var item in client.GetContainer("TEAMModelOS", "Common")
  413. .GetItemQueryIterator<Study>(queryText: $"select value(c) from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{_school}") }))
  414. {
  415. studies.Add(item);
  416. }
  417. }
  418. List<StudyRecord> studyRecords = new List<StudyRecord>();
  419. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  420. .GetItemQueryIterator<StudyRecord>(queryText: $"select value(c) from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StudyRecord-{_tmdid}") }))
  421. {
  422. studyRecords.Add(item);
  423. }
  424. string rcdsql = $" where c.id in ({string.Join(",", studies.FindAll(x=>!string.IsNullOrEmpty(x.workId)).Select(o => $"'{o.workId}'"))})";
  425. List<HomeworkRecord> homeworkRecords = new List<HomeworkRecord>();
  426. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  427. .GetItemQueryIterator<HomeworkRecord>(queryText: $"select value(c) from c {rcdsql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"HomeworkRecord-{_tmdid}") }))
  428. {
  429. homeworkRecords.Add(item);
  430. }
  431. List<OfflineRecord> offlines = new List<OfflineRecord>();
  432. activities.ForEach(item => {
  433. Study study = studies.Find(y=>y.id.Equals(item.id));
  434. if (!string.IsNullOrEmpty(item.owner) && study != null && !string.IsNullOrEmpty(study.workId) && !item.owner.Equals("area") )
  435. {
  436. StudyRecord studyRecord = studyRecords.Find(y => y.id.Equals(item.id));
  437. HomeworkRecord homeworkRecord = homeworkRecords.Find(y => y.id.Equals(study.workId));
  438. Attachment attachment = homeworkRecord != null ? homeworkRecord.content.Find(x => x.prime) : null;
  439. OfflineRecord record = new OfflineRecord
  440. {
  441. id = item.id,
  442. name = item.name,
  443. done = item.taskStatus,
  444. owner = item.owner
  445. };
  446. record.sethour = study.hour;
  447. if (!string.IsNullOrEmpty(study.workId) ) {
  448. record.haswork = 1;
  449. }
  450. if (null != studyRecord)
  451. {
  452. //通过获得学时
  453. record.hour = studyRecord.status == 1 ? study.hour : 0;
  454. record.score = studyRecord.status;
  455. if (record.score >= 0)
  456. {
  457. record.done = 1;
  458. }
  459. else {
  460. record.score = -1;
  461. }
  462. }
  463. if (null != attachment)
  464. {
  465. record.url = attachment.url;
  466. record.upload = 1;
  467. record.hash = attachment.hash;
  468. record.size = attachment.size;
  469. }
  470. offlines.Add(record);
  471. }
  472. });
  473. int sum = offlines.Select(x => x.hour).Sum();
  474. train.offlineTime =sum >setting.offlineTime?setting.offlineTime: sum;
  475. train.offlineRecords= offlines;
  476. return train;
  477. }
  478. /// <summary>
  479. /// 课堂实录更新
  480. /// </summary>
  481. /// <param name="train"></param>
  482. /// <param name="setting"></param>
  483. /// <param name="area"></param>
  484. /// <param name="client"></param>
  485. /// <param name="_school"></param>
  486. /// <param name="_tmdid"></param>
  487. /// <returns></returns>
  488. public static async Task<TeacherTrain> DoTeacherClass(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid)
  489. {
  490. string code = $"ClassVideo-{_school}";
  491. ClassVideo classVideo = null;
  492. try { classVideo = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<ClassVideo>($"{_tmdid}", new PartitionKey(code));
  493. } catch (Exception ex) {
  494. classVideo = null;
  495. }
  496. if (classVideo != null && classVideo.files.IsNotEmpty())
  497. {
  498. //2021.11.17 15:05,与J哥确认,取课堂实录第一个。前端也只show第一个视频。
  499. var files = classVideo.files[0];
  500. if (files.score > 0)
  501. {
  502. train.classTime = setting.classTime;
  503. }
  504. else
  505. {
  506. train.classTime = 0;
  507. }
  508. train.teacherClasses = new List<TeacherClass> { new Models.TeacherClass { url = files.url, score = files.score, hash = files.hash, name = files.name, size = files.size } };
  509. }
  510. else {
  511. train.classTime = 0;
  512. }
  513. return train;
  514. }
  515. public static async Task<TeacherTrain> DoTeacherAility(TeacherTrain train, AreaSetting setting,Area area , CosmosClient client,string _school,string _tmdid) {
  516. //视频播放
  517. List<string> abilityIds = new List<string> ();
  518. TeacherFile file = null;
  519. try
  520. {
  521. file = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<TeacherFile>(_tmdid, new PartitionKey($"TeacherFile-{_school}"));
  522. }
  523. catch (CosmosException )
  524. {
  525. file = new TeacherFile
  526. {
  527. id = _tmdid,
  528. code = $"TeacherFile-{_school}",
  529. pk = "TeacherFile",
  530. ttl = -1,
  531. };
  532. await client.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<TeacherFile>(file, new PartitionKey($"TeacherFile-{_school}"));
  533. }
  534. List<AbilitySub> abilitySubs= new List<AbilitySub> ();
  535. //认证材料
  536. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
  537. .GetItemQueryIterator<AbilitySub>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{_school}-{_tmdid}") }))
  538. {
  539. abilitySubs.Add(item);
  540. }
  541. List<Ability> abilities = new List<Ability>();
  542. string insql = "";
  543. if (abilitySubs.IsNotEmpty()) {
  544. insql =$" where c.id in ({string.Join(",", abilitySubs.Select(o => $"'{o.id}'"))})";
  545. }
  546. await foreach (var item in client.GetContainer("TEAMModelOS", "Normal")
  547. .GetItemQueryIterator<Ability>(queryText: $"select c.id,c.name,c.currency,c.no,c.dimension,c.hour,c.stds from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{area.standard}") }))
  548. {
  549. abilities.Add(item);
  550. }
  551. Currency currency= new Currency();
  552. Currency currencyAll = new Currency();
  553. abilitySubs.ForEach(item => {
  554. int currencyInt = item.from == 1 ? 1 : 0;
  555. Ability ability = abilities.Find(x=>x.id.Equals(item.id));
  556. if (ability != null) {
  557. if (ability != null)
  558. {
  559. currencyInt = item.from == 0 ? ability.currency : 1;
  560. }
  561. else
  562. {
  563. currencyInt = 0;
  564. }
  565. if (item.uploads.IsNotEmpty())
  566. {
  567. if (currencyInt == 1)
  568. {
  569. currency.uploadDone += item.uploads.Count;
  570. }
  571. currencyAll.uploadDone += item.uploads.Count;
  572. }
  573. if (item.exerciseScore > 0)
  574. {
  575. if (currencyInt == 1)
  576. {
  577. currency.exerciseAbility += 1;
  578. currency.learnAbility += item.abilityCount;
  579. }
  580. currencyAll.exerciseAbility += 1;
  581. currencyAll.learnAbility += item.abilityCount;
  582. }
  583. List<TeacherHprecord> hprecords = new List<TeacherHprecord>();
  584. TeacherAility teacherAility = new Models.TeacherAility
  585. {
  586. id = ability.id,
  587. currency = currencyInt,
  588. no = ability.no,
  589. name = ability.name,
  590. dimension = ability.dimension,
  591. zpscore = item.self,
  592. hprecord = hprecords,
  593. uploadHas = item.uploads.Count
  594. };
  595. if (file != null)
  596. {
  597. long view = 0;
  598. file.fileRecords.ForEach(record => {
  599. var abilityVideo = record.files.FindAll(x => x.abilityId.Equals(item.id));
  600. if (abilityVideo.IsNotEmpty())
  601. {
  602. view += record.view;
  603. }
  604. });
  605. //能力点学时限制
  606. int limit = ability.hour * setting.lessonMinutes;
  607. //如果超过 8* 45分钟学时,则直接赋值360(limit)分钟。
  608. view = view / 60;
  609. view = view > limit ? limit : view;
  610. teacherAility.videoTime = view;
  611. teacherAility.limitTime = ability.hour;
  612. teacherAility.onlineTime = view / setting.lessonMinutes;
  613. }
  614. if (item.otherScore.IsNotEmpty())
  615. {
  616. var schoolScore = item.otherScore.Where(x => x.roleType.Equals("school")).FirstOrDefault();
  617. if (schoolScore != null && schoolScore.score >= 0)
  618. {
  619. teacherAility.xzscore = schoolScore.score;
  620. teacherAility.xztime = schoolScore.time;
  621. teacherAility.xztmdid = schoolScore.tmdid;
  622. teacherAility.xztmdname = schoolScore.tmdname;
  623. }
  624. var hprecord = item.otherScore.FindAll(x => x.roleType.Equals("member")).Select(y => new TeacherHprecord { tmdid = y.tmdid, tmdname = y.tmdname, score = y.score });
  625. if (hprecord != null)
  626. {
  627. var no = hprecord.Where(x => x.score == 0) != null ? hprecord.Where(x => x.score == 0).Count() : 0;
  628. var hg = hprecord.Where(x => x.score == 1) != null ? hprecord.Where(x => x.score == 1).Count() : 0;
  629. var yx = hprecord.Where(x => x.score == 2) != null ? hprecord.Where(x => x.score == 2).Count() : 0;
  630. if (no == hg && hg == yx && no == 0)
  631. {
  632. teacherAility.hpscore = -1;
  633. }
  634. else if (no == hg && hg == yx && no != 0)
  635. {
  636. teacherAility.hpscore = 2;
  637. }
  638. else
  639. {
  640. bool ok = false;
  641. List<int> arr = new List<int>() { yx, hg, no };
  642. int max = arr.Max();
  643. if (max == yx && !ok)
  644. {
  645. teacherAility.hpscore = 2;
  646. ok = true;
  647. }
  648. if (max == hg && !ok)
  649. {
  650. teacherAility.hpscore = 1;
  651. ok = true;
  652. }
  653. if (max == no && !ok)
  654. {
  655. teacherAility.hpscore = 0;
  656. ok = true;
  657. }
  658. }
  659. teacherAility.hprecord.AddRange(hprecord);
  660. }
  661. }
  662. if (currencyInt == 1)
  663. {
  664. currency.subCount += 1;
  665. currency.uploadTotal += ability.stds.FindAll(x => x.task.IsNotEmpty()).Select(y => y.task).Count();
  666. currency.teacherAilities.Add(teacherAility);
  667. }
  668. currencyAll.subCount += 1;
  669. currencyAll.uploadTotal += ability.stds.FindAll(x => x.task.IsNotEmpty()).Select(y => y.task).Count();
  670. currencyAll.teacherAilities.Add(teacherAility);
  671. }
  672. });
  673. train.currency = currency;
  674. train.currencyAll = currencyAll;
  675. train.currency.videoTime = train.currency.teacherAilities.Select(x => x.videoTime).Sum();
  676. train.currencyAll.videoTime= train.currencyAll.teacherAilities.Select(x => x.videoTime).Sum();
  677. //如果总分钟数超过20学时,则直接复制20学时。
  678. var videoTime = (int)train.currency.videoTime / setting.lessonMinutes;
  679. train.onlineTime = videoTime > setting.onlineTime ? setting.onlineTime:videoTime;
  680. var bhg = train.currency.teacherAilities.FindAll(x => x.xzscore > 0);
  681. if (bhg.IsNotEmpty()&& bhg.Count == train.currency.subCount)
  682. {
  683. ///要全部合格才能获得学时。
  684. train.currency.submitTime = setting.submitTime;
  685. train.currencyAll.submitTime = setting.submitTime;
  686. }
  687. return train;
  688. }
  689. }
  690. }