StatisticsService.cs 36 KB

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