AbilitySubController.cs 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  1. 
  2. using Azure.Cosmos;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Options;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Text.Json;
  11. using System.Threading.Tasks;
  12. using TEAMModelOS.Models;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK;
  15. using TEAMModelOS.SDK.Models;
  16. using TEAMModelOS.SDK.Extension;
  17. using static TEAMModelOS.Controllers.SchoolTeacherController;
  18. using HTEXLib.COMM.Helpers;
  19. using TEAMModelOS.Filter;
  20. using Azure;
  21. using Azure.Messaging.ServiceBus;
  22. using Microsoft.Extensions.Configuration;
  23. namespace TEAMModelOS.Controllers
  24. {
  25. [ProducesResponseType(StatusCodes.Status200OK)]
  26. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  27. //[Authorize(Roles = "IES5")]
  28. [Route("research/ability")]
  29. [ApiController]
  30. public class AbilitySubController : ControllerBase
  31. {
  32. private readonly AzureCosmosFactory _azureCosmos;
  33. private readonly SnowflakeId _snowflakeId;
  34. private readonly DingDing _dingDing;
  35. private readonly Option _option;
  36. private readonly ThirdApisService _thirdApisService;
  37. private readonly HttpTrigger _httpTrigger;
  38. private readonly AzureServiceBusFactory _serviceBus;
  39. public IConfiguration _configuration { get; set; }
  40. public AbilitySubController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, ThirdApisService thirdApisService, HttpTrigger httpTrigge, AzureServiceBusFactory serviceBus, IConfiguration configuration)
  41. {
  42. _azureCosmos = azureCosmos;
  43. _snowflakeId = snowflakeId;
  44. _dingDing = dingDing;
  45. _option = option?.Value;
  46. _thirdApisService = thirdApisService;
  47. _httpTrigger = httpTrigge;
  48. _serviceBus = serviceBus;
  49. _configuration = configuration;
  50. }
  51. /// <summary>
  52. /// 保存
  53. /// </summary>
  54. /// <param name="request"></param>
  55. /// <returns></returns>
  56. [ProducesDefaultResponseType]
  57. [HttpPost("save-subs")]
  58. [AuthToken(Roles = "teacher,admin,area")]
  59. public async Task<IActionResult> SaveSubs(JsonElement request)
  60. {
  61. try
  62. {
  63. (string id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  64. if (string.IsNullOrEmpty(school))
  65. {
  66. if (!request.TryGetProperty("school", out JsonElement _school))
  67. {
  68. return BadRequest();
  69. }
  70. else
  71. {
  72. school = $"{_school}";
  73. }
  74. }
  75. var client = _azureCosmos.GetCosmosClient();
  76. if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return BadRequest();
  77. if (!request.TryGetProperty("abilityIds", out JsonElement _abilityIds)) return BadRequest();
  78. List<string> abilityIds = _abilityIds.ToObject<List<string>>();
  79. foreach (var abilityId in abilityIds)
  80. {
  81. if (!string.IsNullOrEmpty(abilityId))
  82. {
  83. string code = $"AbilitySub-{school}-{_tmdid}";
  84. try
  85. {
  86. await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<AbilitySub>(abilityId, new PartitionKey(code));
  87. }
  88. catch (CosmosException ex)
  89. {
  90. if (ex.Status == 404)
  91. {
  92. AbilitySub abilitySub = new AbilitySub
  93. {
  94. id = abilityId,
  95. code = $"AbilitySub-{school}-{_tmdid}",
  96. school = $"{school}",
  97. creatorId = $"{_tmdid}",
  98. done = false,
  99. hour = 0,
  100. comid = Guid.NewGuid().ToString(),
  101. pk = "AbilitySub"
  102. };
  103. await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(abilitySub, new PartitionKey(abilitySub.code));
  104. }
  105. }
  106. }
  107. }
  108. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return BadRequest();
  109. await StatisticsService.SendServiceBus(new List<(string standard, string tmdid, string school, List<string> update, int statistics)> { ($"{standard}", $"{_tmdid}", $"{school}",new List<string> { StatisticsService.TeacherAility }, 0) }, _configuration, _serviceBus);
  110. return Ok(new { abilityIds });
  111. }
  112. catch (Exception ex)
  113. {
  114. await _dingDing.SendBotMsg($"OS,{_option.Location},AbilityController/SaveSubs()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  115. return BadRequest();
  116. }
  117. }
  118. /// <summary>
  119. ///当前老师 获取没有订阅以及已经订阅的能力点学习课程
  120. /// </summary>
  121. /// <param name="request"></param>
  122. /// <returns></returns>
  123. [ProducesDefaultResponseType]
  124. [AuthToken(Roles = "teacher,admin,area")]
  125. [HttpPost("get-subs")]
  126. public async Task<IActionResult> GetSubs(JsonElement request)
  127. {
  128. try
  129. {
  130. var client = _azureCosmos.GetCosmosClient();
  131. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return Ok(new { error = 400 });
  132. ///没有订阅的
  133. List<Ability> notSub = new List<Ability>();
  134. ///已经订阅的
  135. List<Ability> hadSubs = new List<Ability>();
  136. ///订阅的学习记录
  137. List<AbilitySub> rcdSubs = new List<AbilitySub>();
  138. //必修
  139. List<Ability> currencyAb1 = new List<Ability>();
  140. //通识
  141. List<Ability> currencyAb2 = new List<Ability>();
  142. //tmdid
  143. if (!request.TryGetProperty("tmdid", out JsonElement tmdid)) return Ok(new { error = 400 });
  144. //学校编码
  145. (string id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  146. if (string.IsNullOrEmpty(school))
  147. {
  148. if (!request.TryGetProperty("school", out JsonElement _school))
  149. {
  150. return Ok(new { error = 400 });
  151. }
  152. else
  153. {
  154. school = $"{_school}";
  155. }
  156. }
  157. if (!string.IsNullOrEmpty(school))
  158. {
  159. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Normal")
  160. .GetItemQueryIterator<Ability>(queryText: $"select value(c) from c where c.status = 1 ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") }))
  161. {
  162. notSub.Add(item);
  163. if (item.currency == 2)
  164. {
  165. currencyAb2.Add(item);
  166. }
  167. if (item.currency == 1)
  168. {
  169. currencyAb1.Add(item);
  170. }
  171. }
  172. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher")
  173. .GetItemQueryIterator<AbilitySub>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{school}-{tmdid}") }))
  174. {
  175. var had = notSub.Where(x => x.id.Equals(item.id)).FirstOrDefault();
  176. if (had != null)
  177. {
  178. notSub.Remove(had);
  179. hadSubs.Add(had);
  180. }
  181. rcdSubs.Add(item);
  182. }
  183. }
  184. else
  185. {
  186. return Ok(new { error = 400 });
  187. };
  188. (string accessConfig, Area area, AreaSetting setting) = await ThirdService.GetAccessConfig(client, $"{standard}");
  189. //automatic,自动分配系统设置的=0,manual手动挑选的=1
  190. int from = 0;
  191. //未对接其他平台。有对接其他平台则必修。
  192. if (!string.IsNullOrEmpty(accessConfig))
  193. {
  194. Teacher teacher = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
  195. HashSet<string> pxid = teacher.binds.SelectMany(x => x.pxid).ToHashSet();
  196. var abilitys = await ThirdService.GetDiagnosisList(client, $"{standard}", _dingDing, setting, _httpTrigger, pxid, _option);
  197. if (abilitys != null)
  198. {
  199. abilitys.ForEach(x => { x.currency = 1; });
  200. currencyAb1 = abilitys;
  201. //同时处理 原有设置必修的能力点。
  202. hadSubs.FindAll(x => x.currency == 1).ForEach(y => { y.currency = 0; });
  203. from = 1;
  204. }
  205. else
  206. {
  207. currencyAb1 = null;
  208. }
  209. }
  210. //通识
  211. foreach (var item in currencyAb2)
  212. {
  213. var had = hadSubs.Where(x => x.id.Equals(item.id)).FirstOrDefault();
  214. if (had == null)
  215. {
  216. hadSubs.Add(item);
  217. AbilitySub abilitySub = new AbilitySub
  218. {
  219. id = item.id,
  220. code = $"AbilitySub-{school}-{id}",
  221. school = $"{school}",
  222. creatorId = $"{id}",
  223. done = false,
  224. hour = 0,
  225. comid = Guid.NewGuid().ToString(),
  226. pk = "AbilitySub" ,
  227. from = 0,
  228. currency = item.currency
  229. };
  230. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(abilitySub, new PartitionKey(abilitySub.code));
  231. }
  232. }
  233. if (currencyAb1 != null)
  234. {
  235. //必修
  236. foreach (var item in currencyAb1)
  237. {
  238. var had = hadSubs.Where(x => x.id.Equals(item.id)).FirstOrDefault();
  239. if (had == null)
  240. {
  241. hadSubs.Add(item);
  242. AbilitySub abilitySub = new AbilitySub
  243. {
  244. id = item.id,
  245. code = $"AbilitySub-{school}-{id}",
  246. school = $"{school}",
  247. creatorId = $"{id}",
  248. done = false,
  249. hour = 0,
  250. comid = Guid.NewGuid().ToString(),
  251. pk = "AbilitySub",
  252. from=from,
  253. currency = item.currency
  254. };
  255. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(abilitySub, new PartitionKey(abilitySub.code));
  256. }
  257. }
  258. }
  259. return Ok(new { rcdSubs, hadSubs });
  260. }
  261. catch (Exception ex)
  262. {
  263. await _dingDing.SendBotMsg($"OS,{_option.Location},AbilityController:get-subs\n{ex.Message}{ex.StackTrace}\n{request.ToJsonString()}", GroupNames.成都开发測試群組);
  264. return Ok(new { error = 400 });
  265. }
  266. }
  267. private async IAsyncEnumerable<List<AbilitySub>> GetSubsAsyn(List<string> tmdids, string _school, HashSet<string> ids)
  268. {
  269. foreach (var tmdid in tmdids)
  270. {
  271. List<AbilitySub> abilitySubs = new List<AbilitySub>();
  272. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher")
  273. .GetItemQueryIterator<AbilitySub>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{_school}-{tmdid}") }))
  274. {
  275. ids.Add(item.id);
  276. abilitySubs.Add(item);
  277. }
  278. yield return abilitySubs;
  279. }
  280. }
  281. /// <summary>
  282. /// 批量更新认证材料分数。
  283. /// </summary>
  284. /// <param name="request"></param>
  285. /// <returns></returns>
  286. [ProducesDefaultResponseType]
  287. [HttpPost("score-teacher-submit")]
  288. [AuthToken(Roles = "admin,teacher", Permissions = "train-appraise")]
  289. public async Task<IActionResult> UpsertSubmitScore(JsonElement request)
  290. {
  291. try
  292. {
  293. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return BadRequest();
  294. if (!request.TryGetProperty("score", out JsonElement _score)) return BadRequest();
  295. if (!request.TryGetProperty("tmdids", out JsonElement _tmdids)) return BadRequest();
  296. if (!request.TryGetProperty("roleType", out JsonElement _roleType)) return BadRequest();
  297. var (userid, name, picture, school) = HttpContext.GetAuthTokenInfo();
  298. int score = -999;
  299. var client = _azureCosmos.GetCosmosClient();
  300. int.TryParse($"{_score}", out score);
  301. List<string> tmdids = _tmdids.ToObject<List<string>>();
  302. List<AbilitySub> abilitySubs = new List<AbilitySub>();
  303. HashSet<AbilitySub> subs = new HashSet<AbilitySub>();
  304. HashSet<string> ids = new HashSet<string>();
  305. // List<string> abilities = new List<string>();
  306. await foreach (var item in GetSubsAsyn(tmdids, school, ids))
  307. {
  308. abilitySubs.AddRange(item);
  309. }
  310. var su = abilitySubs.FindAll(x => x.from == 1);
  311. if (su.IsNotEmpty())
  312. {
  313. subs = new HashSet<AbilitySub>(su);
  314. }
  315. if (ids.Count > 0)
  316. {
  317. string queryText = $"SELECT value(c.id) FROM c WHERE c.currency=1 and c.id IN ({string.Join(",", ids.Select(o => $"'{o}'"))})";
  318. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Normal")
  319. .GetItemQueryIterator<string>(queryText: queryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") }))
  320. {
  321. var sb = abilitySubs.FindAll(x => x.id.Equals(item));
  322. if (sb != null)
  323. {
  324. subs.UnionWith(sb);
  325. }
  326. //abilities.Add(item);
  327. }
  328. }
  329. if (subs.Count > 0 && score >= -1 && score <= 2)
  330. {
  331. long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  332. List<Task<ItemResponse<AbilitySub>>> abilitySubTasks = new List<Task<ItemResponse<AbilitySub>>>();
  333. subs.ToList().ForEach(sub => {
  334. OtherScore otherScore = null;
  335. if ($"{_roleType}".Equals("school"))
  336. {
  337. otherScore = sub.otherScore.Find(x => x.roleType.Equals($"{_roleType}"));
  338. }
  339. else
  340. {
  341. otherScore = sub.otherScore.Find(x => x.roleType.Equals($"{_roleType}") && x.tmdid.Equals(userid));
  342. }
  343. if (otherScore != null)
  344. {
  345. otherScore.score = score;
  346. otherScore.scoreUploads.ForEach(x => {
  347. x.score = score;
  348. });
  349. otherScore.tmdid = userid;
  350. otherScore.tmdname = name;
  351. otherScore.time = nowTime;
  352. }
  353. else
  354. {
  355. if (sub.uploads != null)
  356. {
  357. List<ScoreUpload> scoreUploads = new List<ScoreUpload>();
  358. sub.uploads.ForEach(x => {
  359. scoreUploads.Add(new ScoreUpload
  360. {
  361. score = score,
  362. stdid = x.stdid,
  363. taskid = x.taskid,
  364. titleIds = x.titleIds,
  365. });
  366. });
  367. otherScore = new OtherScore
  368. {
  369. roleType = $"{_roleType}",
  370. tmdid = userid,
  371. tmdname = name,
  372. score = score,
  373. time = nowTime,
  374. scoreUploads = scoreUploads
  375. };
  376. }
  377. }
  378. abilitySubTasks.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(sub, sub.id, new PartitionKey(sub.code)));
  379. });
  380. List<(string standard, string tmdid, string school, List<string> update, int statistics)> list = new List<(string standard, string tmdid, string school, List<string> update, int statistics)>();
  381. tmdids.ForEach(x => {
  382. list.Add(($"{standard}", $"{x}", $"{school}", new List<string> { StatisticsService.TeacherAility }, 1));
  383. });
  384. int pagesize = 50;
  385. if (abilitySubTasks.Count <= pagesize)
  386. {
  387. await Task.WhenAll(abilitySubTasks);
  388. }
  389. else
  390. {
  391. int pages = (abilitySubTasks.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
  392. for (int i = 0; i < pages; i++)
  393. {
  394. var lists = abilitySubTasks.Skip((i) * pagesize).Take(pagesize).ToList();
  395. await Task.WhenAll(lists);
  396. }
  397. }
  398. await StatisticsService.SendServiceBus(list, _configuration, _serviceBus);
  399. return Ok(new { status = 200 });
  400. }
  401. }
  402. catch (Exception ex)
  403. {
  404. await _dingDing.SendBotMsg($"OS,{_option.Location},UpsertSubmitScore/UpsertSubmitScore()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  405. }
  406. return Ok(new { error = 0, msg = "参数异常" });
  407. }
  408. /// <summary>
  409. /// 对某个订阅的能力点进行操作
  410. /// </summary>
  411. /// <param name="request"></param>
  412. /// <returns></returns>
  413. [ProducesDefaultResponseType]
  414. [HttpPost("sub-opt")]
  415. [AuthToken(Roles = "teacher,admin,area")]
  416. public async Task<IActionResult> SubOpt(JsonElement request)
  417. {
  418. try
  419. {
  420. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return BadRequest();
  421. var client = _azureCosmos.GetCosmosClient();
  422. if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return BadRequest();
  423. if (!request.TryGetProperty("school", out JsonElement _school)) return BadRequest();
  424. if (!request.TryGetProperty("opt", out JsonElement _opt)) return BadRequest();
  425. if (!request.TryGetProperty("abilityId", out JsonElement _abilityId)) return BadRequest();
  426. string code = $"AbilitySub-{_school}-{_tmdid}";
  427. int status = 0;
  428. AbilitySub abilitySub = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<AbilitySub>($"{_abilityId}", new PartitionKey(code));
  429. Ability abilityA = await client.GetContainer("TEAMModelOS", "Normal").ReadItemAsync<Ability>($"{_abilityId}", new PartitionKey($"Ability-{standard}"));
  430. switch ($"{_opt}")
  431. {
  432. case "ReadSelfOnlineRcd":
  433. //获取线上学习记录
  434. return Ok(new { abilitySub.taskRcds });
  435. case "ReadSomeoneSub":
  436. //获取线一个人的完整的能力点订阅数据
  437. var replyIds = abilitySub.otherScore.SelectMany(x => x.replyIds).Where(y=>!string.IsNullOrEmpty(y));
  438. List<DebateReply> replies = new List<DebateReply>();
  439. if (replyIds != null && replyIds.Count()>0) {
  440. string sql = $"select value(A1) from c join A1 in c.replies where A1.id in({string.Join(",", replyIds.Select(o => $"'{o}'"))})";
  441. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School")
  442. .GetItemQueryIterator<DebateReply>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Debate-{_school}") }))
  443. {
  444. replies.Add(item);
  445. }
  446. abilitySub.otherScore.ForEach(x => {
  447. x.replyIds.RemoveAll(x =>string.IsNullOrEmpty(x) || !replies.Select(r=>r.id).Contains(x));
  448. });
  449. }
  450. List<OtherScoreReply> scoreReplies= new List<OtherScoreReply>();
  451. abilitySub.otherScore.ForEach(x => {
  452. OtherScoreReply scoreReply = new OtherScoreReply
  453. {
  454. roleType=x.roleType,
  455. tmdid=x.tmdid,
  456. tmdname=x.tmdname,
  457. score=x.score,
  458. scoreUploads=x.scoreUploads,
  459. time=x.time
  460. };
  461. var rs= replies.FindAll(m => x.replyIds.Contains(m.id));
  462. scoreReply.replies.AddRange(rs);
  463. scoreReplies.Add(scoreReply);
  464. });
  465. Dictionary<string, List<DebateReply>> pairs = new Dictionary<string, List<DebateReply>>();
  466. abilitySub.otherScore.GroupBy(x => x.roleType).Select(m => new { key= m.Key, list = m.ToList() }).ToList().ForEach(y => {
  467. var reply= replies.FindAll(z =>y.list.SelectMany(a=>a.replyIds).Contains(z.id));
  468. pairs.Add(y.key, reply);
  469. });
  470. return Ok(new { abilitySub,scoreReplies, ability = abilityA });
  471. case "SetOnlineDone":
  472. //完成线上学习
  473. abilitySub.done = true;
  474. //abilitySub.abilityCount = abilityA.abilityCount;
  475. //abilitySub.hour = abilityA.hour;
  476. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  477. return Ok(new { abilitySub });
  478. case "ExerciseScore":
  479. //保存自测结果
  480. if (!request.TryGetProperty("exercise", out JsonElement _exercise)) return BadRequest();
  481. if (!string.IsNullOrEmpty($"{_exercise}"))
  482. {
  483. //exercise -1未自测 0不合格 1 合格
  484. abilitySub.exerciseScore = int.Parse($"{_exercise}");
  485. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  486. status = 1;
  487. await StatisticsService.SendServiceBus(new List<(string standard, string tmdid, string school, List<string> update, int statistics)> { ($"{standard}", $"{_tmdid}", $"{_school}",new List<string> { StatisticsService.TeacherAility }, 1) }, _configuration, _serviceBus);
  488. return Ok(new { status });
  489. }
  490. else
  491. {
  492. return BadRequest("参数exercise没有值");
  493. }
  494. case "ExerciseRcd":
  495. //获取自测结果
  496. return Ok(new { exercise = abilitySub.exerciseScore });
  497. case "Upload":
  498. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  499. //上传作品和自评
  500. if (!request.TryGetProperty("uploads", out JsonElement _uploads)) return BadRequest();
  501. if (!request.TryGetProperty("self", out JsonElement _self)) return BadRequest();
  502. List<SubUpload> uploads = _uploads.ToObject<List<SubUpload>>();
  503. if (!string.IsNullOrEmpty($"{_self}"))
  504. {
  505. //_self 0 不及格,1及格,2优秀
  506. abilitySub.self = int.Parse($"{_self}");
  507. }
  508. else
  509. {
  510. return BadRequest();
  511. }
  512. if (uploads.IsNotEmpty())
  513. {
  514. abilitySub.abilityCount = abilityA.abilityCount;
  515. abilitySub.hour = abilityA.hour;
  516. uploads.ForEach(u =>
  517. {
  518. var up = abilitySub.uploads.Find(x => x.stdid.Equals(u.stdid));
  519. if (up != null)
  520. {
  521. up.urls = u.urls;
  522. up.taskid = u.taskid;
  523. up.titleIds = u.titleIds;
  524. up.time = now;
  525. }
  526. else
  527. {
  528. u.time = now;
  529. abilitySub.uploads.Add(u);
  530. }
  531. });
  532. abilitySub.selfTime = now;
  533. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  534. status = 1;
  535. await StatisticsService.SendServiceBus(new List<(string standard, string tmdid, string school, List<string> update, int statistics)> { ($"{standard}", $"{_tmdid}", $"{_school}", new List<string> { StatisticsService.TeacherAility }, 0) }, _configuration, _serviceBus);
  536. }
  537. else
  538. {
  539. return BadRequest();
  540. }
  541. return Ok(new { status });
  542. case "YouRateSomone":
  543. //你对别人的某个能力点的学习进行评价,不能评价自己的,
  544. if (!request.TryGetProperty("otherScore", out JsonElement _other)) return BadRequest();
  545. RoleScore other = _other.ToObject<RoleScore>();
  546. string replyId = null;
  547. if (other != null)
  548. {
  549. //if (abilitySub.creatorId.Equals(other.tmdid))
  550. //{
  551. // return BadRequest("不能评价自己的");
  552. //}
  553. long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  554. if (!string.IsNullOrEmpty(other.reply))
  555. {
  556. replyId = Guid.NewGuid().ToString();
  557. DebateReply debateReply = new DebateReply
  558. {
  559. atUserType = "tmdid",
  560. userType = "tmdid",
  561. id = replyId,
  562. pid = abilitySub.comid,
  563. tmdid = other.tmdid,
  564. tmdname = other.tmdname,
  565. comment = other.reply,
  566. atTmdid = $"{_tmdid}",
  567. atTmdname = other.atTmdname,
  568. time = nowTime
  569. };
  570. try
  571. {
  572. Debate debate = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>(abilitySub.comid, new PartitionKey($"Debate-{_school}"));
  573. debate.replies.Add(debateReply);
  574. await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, abilitySub.comid, new PartitionKey($"Debate-{_school}"));
  575. }
  576. catch (CosmosException ex)
  577. {
  578. if (ex.Status == 404)
  579. {
  580. Debate debate = new Debate
  581. {
  582. userType = "tmdid",
  583. comid = $"{abilityA.comid}",
  584. code = $"Debate-{_school}",
  585. id = $"{abilitySub.comid}",
  586. tmdid = abilitySub.creatorId,
  587. tmdname = other.atTmdname,
  588. title = $"{other.atTmdname}-{abilityA.name}",
  589. time = nowTime,
  590. comment = "",
  591. school = $"{_school}",
  592. replies = new List<DebateReply>() { debateReply },
  593. source = "uploadscore",
  594. openType = 0,
  595. ttl = -1,
  596. pk = "Debate"
  597. };
  598. await client.GetContainer("TEAMModelOS", "School").CreateItemAsync<Debate>(debate, new PartitionKey($"Debate-{_school}"));
  599. }
  600. }
  601. }
  602. if (other.roleType.Equals("school"))
  603. {
  604. //学校的身份不管是谁,只能以学校的身份进行一次评论
  605. abilitySub.allDone = true;
  606. var otherScore = abilitySub.otherScore.Find(x => x.roleType.Equals(other.roleType));
  607. if (otherScore != null)
  608. {
  609. otherScore.tmdid = other.tmdid;
  610. otherScore.tmdname = other.tmdname;
  611. otherScore.score = other.score;
  612. if (!string.IsNullOrEmpty(replyId))
  613. {
  614. if (otherScore.replyIds.IsNotEmpty())
  615. {
  616. otherScore.replyIds.Add(replyId);
  617. }
  618. else
  619. {
  620. otherScore.replyIds = new List<string>() { replyId };
  621. }
  622. }
  623. otherScore.scoreUploads = other.scoreUploads;
  624. otherScore.time = nowTime;
  625. }
  626. else
  627. {
  628. abilitySub.otherScore.Add(new OtherScore
  629. {
  630. roleType = other.roleType,
  631. tmdid = other.tmdid,
  632. tmdname = other.tmdname,
  633. score = other.score,
  634. replyIds = new List<string>() { replyId },
  635. scoreUploads = other.scoreUploads,
  636. time = nowTime
  637. });
  638. }
  639. }
  640. else if (other.roleType.Equals("leader"))
  641. {
  642. //小组评的身份不管是谁,只能以学校的身份进行一次评论
  643. abilitySub.allDone = true;
  644. var otherScore = abilitySub.otherScore.Find(x => x.roleType.Equals(other.roleType));
  645. if (otherScore != null)
  646. {
  647. otherScore.tmdid = other.tmdid;
  648. otherScore.tmdname = other.tmdname;
  649. otherScore.score = other.score;
  650. if (!string.IsNullOrEmpty(replyId))
  651. {
  652. if (otherScore.replyIds.IsNotEmpty())
  653. {
  654. otherScore.replyIds.Add(replyId);
  655. }
  656. else
  657. {
  658. otherScore.replyIds = new List<string>() { replyId };
  659. }
  660. }
  661. otherScore.scoreUploads = other.scoreUploads;
  662. otherScore.time = nowTime;
  663. }
  664. else
  665. {
  666. abilitySub.otherScore.Add(new OtherScore
  667. {
  668. roleType = other.roleType,
  669. tmdid = other.tmdid,
  670. tmdname = other.tmdname,
  671. score = other.score,
  672. replyIds = new List<string>() { replyId },
  673. scoreUploads = other.scoreUploads,
  674. time = nowTime
  675. });
  676. }
  677. }
  678. else
  679. {
  680. //其他身份的同一个人可以以不同身份进行点评
  681. var otherScore = abilitySub.otherScore.Find(x => x.tmdid.Equals(other.tmdid) && x.roleType.Equals(other.roleType));
  682. if (otherScore != null)
  683. {
  684. otherScore.tmdid = other.tmdid;
  685. otherScore.tmdname = other.tmdname;
  686. otherScore.score = other.score;
  687. if (!string.IsNullOrEmpty(replyId))
  688. {
  689. if (otherScore.replyIds.IsNotEmpty())
  690. {
  691. otherScore.replyIds.Add(replyId);
  692. }
  693. else
  694. {
  695. otherScore.replyIds = new List<string>() { replyId };
  696. }
  697. }
  698. otherScore.scoreUploads = other.scoreUploads;
  699. otherScore.time = nowTime;
  700. }
  701. else
  702. {
  703. abilitySub.otherScore.Add(new OtherScore
  704. {
  705. roleType = other.roleType,
  706. tmdid = other.tmdid,
  707. tmdname = other.tmdname,
  708. score = other.score,
  709. replyIds = new List<string>() { replyId },
  710. scoreUploads = other.scoreUploads,
  711. time = nowTime
  712. });
  713. }
  714. }
  715. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  716. await StatisticsService.SendServiceBus(new List<(string standard, string tmdid, string school, List<string> update, int statistics)> { ($"{standard}", $"{_tmdid}", $"{_school}", new List<string> { StatisticsService.TeacherAility }, 1) }, _configuration, _serviceBus);
  717. status = 1;
  718. }
  719. return Ok(new { status, abilitySub });
  720. case "YouGetSomoneRate":
  721. //你获取你对别人的某个能力点的学习评价
  722. OtherScore score = null;
  723. if (!request.TryGetProperty("yourTmdid", out JsonElement _yourTmdid)) return BadRequest();
  724. if (string.IsNullOrEmpty($"{_yourTmdid}"))
  725. {
  726. score = abilitySub.otherScore.Find(x => x.tmdid.Equals($"{_yourTmdid}"));
  727. if (score != null)
  728. {
  729. status = 1;
  730. return Ok(new { score, status });
  731. }
  732. else
  733. {
  734. return Ok(new { status, score });
  735. }
  736. }
  737. else
  738. {
  739. return Ok(new { status, score });
  740. }
  741. case "SaveLearnOnlineRcd":
  742. //保存线上学习记录
  743. if (!request.TryGetProperty("taskRcds", out JsonElement _taskRcds)) return BadRequest();
  744. AbilityTaskRcd taskRcds = _taskRcds.ToObject<AbilityTaskRcd>();
  745. if (taskRcds != null)
  746. {
  747. bool isnew = true;
  748. abilitySub.taskRcds.ForEach(x =>
  749. {
  750. if (x.id.Equals(taskRcds.id))
  751. {
  752. //重新上传或者覆盖之前
  753. x.done = taskRcds.done;
  754. x.urls = taskRcds.urls;
  755. isnew = false;
  756. }
  757. });
  758. if (isnew)
  759. {
  760. abilitySub.taskRcds.Add(taskRcds);
  761. }
  762. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  763. status = 1;
  764. }
  765. return Ok(new { status, abilitySub.taskRcds });
  766. case "SaveVideoRcd":
  767. //保存线上学习记录
  768. if (!request.TryGetProperty("videoRcd", out JsonElement _videoRcd)) return BadRequest();
  769. AbilityVideoRcd videoRcd = _videoRcd.ToObject<AbilityVideoRcd>();
  770. if (videoRcd != null)
  771. {
  772. bool isnew = true;
  773. abilitySub.videoRcds.ForEach(x =>
  774. {
  775. if (x.abilityId.Equals(videoRcd.abilityId) && x.abilityTaskId.Equals(videoRcd.abilityTaskId) && x.url.Equals(videoRcd.url))
  776. {
  777. //重新上传或者覆盖之前
  778. x.done = videoRcd.done;
  779. x.time = videoRcd.time;
  780. isnew = false;
  781. }
  782. });
  783. if (isnew)
  784. {
  785. abilitySub.videoRcds.Add(videoRcd);
  786. }
  787. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<AbilitySub>(abilitySub, $"{_abilityId}", new PartitionKey(code));
  788. status = 1;
  789. }
  790. return Ok(new { status, abilitySub.videoRcds });
  791. case "SaveFileRcd":
  792. //保存文件学习记录
  793. if (!request.TryGetProperty("fileRcd", out JsonElement _fileRcd)) return BadRequest();
  794. List< TeacherFileRcd > fileRcds = new List< TeacherFileRcd >();
  795. if (_fileRcd.ValueKind.Equals(JsonValueKind.Object))
  796. {
  797. TeacherFileRcd fileRcd = _fileRcd.ToObject<TeacherFileRcd>();
  798. fileRcds.Add( fileRcd );
  799. }
  800. else if (_fileRcd.ValueKind.Equals(JsonValueKind.Array))
  801. {
  802. fileRcds = _fileRcd.ToObject<List<TeacherFileRcd>>();
  803. }
  804. TeacherFile teacherFile = null;
  805. try
  806. {
  807. teacherFile = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<TeacherFile>($"{_tmdid}", new PartitionKey($"TeacherFile-{_school}"));
  808. fileRcds.ForEach(fileRcd => {
  809. var file = teacherFile.fileRecords.Find(x => x.hash.Equals(fileRcd.hash));
  810. if (file != null)
  811. {
  812. file.hash = fileRcd.hash;
  813. file.view = fileRcd.view;
  814. file.done = fileRcd.done;
  815. FileAbility ability = file.files.Find(x => x.abilityId.Equals(fileRcd.abilityId) && x.url.Equals(fileRcd.url) && x.taskId.Equals(fileRcd.taskId) && x.nodeId.Equals(fileRcd.nodeId));
  816. if (ability != null)
  817. {
  818. ability.url = fileRcd.url;
  819. ability.abilityId = fileRcd.abilityId;
  820. ability.taskId = fileRcd.taskId;
  821. ability.nodeId = fileRcd.nodeId;
  822. }
  823. else
  824. {
  825. file.files.Add(new FileAbility { url = fileRcd.url, abilityId = fileRcd.abilityId, taskId = fileRcd.taskId, nodeId = fileRcd.nodeId, });
  826. }
  827. }
  828. else
  829. {
  830. teacherFile.fileRecords.Add(new FileRecord
  831. {
  832. hash = fileRcd.hash,
  833. size = fileRcd.size,
  834. duration = fileRcd.duration,
  835. view = fileRcd.view,
  836. type = fileRcd.type,
  837. done = fileRcd.done,
  838. files = new List<FileAbility> { new FileAbility { url = fileRcd.url, abilityId = fileRcd.abilityId, taskId = fileRcd.taskId, nodeId = fileRcd.nodeId, } }
  839. });
  840. }
  841. });
  842. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<TeacherFile>(teacherFile, teacherFile.id, new PartitionKey($"TeacherFile-{_school}"));
  843. }
  844. catch (CosmosException)
  845. {
  846. fileRcds.ForEach(fileRcd => {
  847. teacherFile = new TeacherFile
  848. {
  849. pk = "TeacherFile",
  850. id = $"{_tmdid}",
  851. code = $"TeacherFile-{_school}",
  852. fileRecords = new List<FileRecord>
  853. {
  854. new FileRecord
  855. {
  856. hash= fileRcd.hash,
  857. size=fileRcd.size,
  858. duration=fileRcd.duration,
  859. view=fileRcd.view,
  860. type=fileRcd.type,
  861. done=fileRcd.done,
  862. files= new List<FileAbility> { new FileAbility { url=fileRcd.url,abilityId=fileRcd.abilityId,taskId=fileRcd.taskId,nodeId=fileRcd.nodeId} }
  863. }
  864. },
  865. };
  866. });
  867. await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<TeacherFile>(teacherFile, new PartitionKey($"TeacherFile-{_school}"));
  868. }
  869. if (fileRcds.Exists(x => x.type.Equals("video"))) {
  870. await StatisticsService.SendServiceBus(new List<(string standard, string tmdid, string school, List<string> update, int statistics)> { ($"{standard}", $"{_tmdid}", $"{_school}", new List<string> { StatisticsService.TeacherAility }, 1) }, _configuration, _serviceBus);
  871. }
  872. //获取视文件学习记录
  873. List<dynamic> _files = new List<dynamic>();
  874. try
  875. {
  876. TeacherFile teacherFilercd = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<TeacherFile>($"{_tmdid}", new PartitionKey($"TeacherFile-{_school}"));
  877. teacherFilercd.fileRecords.ForEach(x => {
  878. var file = x.files.FindAll(y => y.abilityId.Equals($"{_abilityId}"));
  879. if (file.IsNotEmpty())
  880. {
  881. _files.Add(new { ability = file, view = x.view, hash = x.hash, done = x.done });
  882. }
  883. });
  884. }
  885. catch (Exception ex)
  886. {
  887. }
  888. return Ok(new { status, files=_files });
  889. case "ReadSelfVideoRcd":
  890. //获取视频学习记录
  891. return Ok(new { abilitySub.videoRcds });
  892. case "ReadSelfFileRcd":
  893. //获取视文件学习记录
  894. List<dynamic> files = new List<dynamic>();
  895. List<dynamic> abilityFiles = new List<dynamic>();
  896. try {
  897. TeacherFile teacherFilercd = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<TeacherFile>($"{_tmdid}", new PartitionKey($"TeacherFile-{_school}"));
  898. HashSet<string> abilityIds= teacherFilercd.fileRecords.SelectMany(x => x.files).Select(x => x.abilityId).ToHashSet() ;
  899. teacherFilercd.fileRecords.ForEach(x => {
  900. var file = x.files.FindAll(y => y.abilityId.Equals($"{_abilityId}"));
  901. if (file.IsNotEmpty()) {
  902. files.Add(new { ability =file,view=x.view,hash=x.hash,done=x.done });
  903. }
  904. });
  905. foreach (var abid in abilityIds) {
  906. var record= teacherFilercd.fileRecords.FindAll(x => x.files.Where(y => y.abilityId.Equals(abid)).Count() > 0);
  907. long view = 0;
  908. List<dynamic> urls = new List<dynamic>();
  909. record.ForEach(x => {
  910. var file= x.files.FindAll(y => y.abilityId.Equals($"{abid}"));
  911. if (file.IsNotEmpty())
  912. {
  913. view += x.view;
  914. urls.Add(new { ability = file, view = x.view, hash = x.hash, done = x.done });
  915. }
  916. });
  917. abilityFiles.Add(new { view, abilityId= abid });
  918. }
  919. return Ok(new { status, files, abilityFiles });
  920. } catch (Exception ex) {
  921. }
  922. return Ok(new { });
  923. default:
  924. return Ok(new { status = -1 });
  925. }
  926. }
  927. catch (CosmosException ex)
  928. {
  929. return Ok(new { status = -1 });
  930. }
  931. catch (Exception ex)
  932. {
  933. await _dingDing.SendBotMsg($"OS,{_option.Location},AbilityController/SubOpt()\n{ex.Message}{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  934. return Ok(new { status = -1 });
  935. }
  936. } /// <summary>
  937. /// 获取回复详情信息。
  938. /// </summary>
  939. /// <param name="request"></param>
  940. /// <returns></returns>
  941. [ProducesDefaultResponseType]
  942. [HttpPost("get-reply-info")]
  943. [AuthToken(Roles = "teacher,admin,area")]
  944. public async Task<IActionResult> GetReplyInfo(JsonElement request)
  945. {
  946. if (!request.TryGetProperty("school", out JsonElement _school)) return BadRequest();
  947. if (!request.TryGetProperty("replyIds", out JsonElement _replyIds)) return BadRequest();
  948. List<string> replyIds = _replyIds.ToObject<List<string>>();
  949. if (replyIds.IsNotEmpty())
  950. {
  951. List<dynamic> replies = new List<dynamic>();
  952. string sql = $"select A1 as replies from c join A1 in c.replies where A1.id in({string.Join(",", replyIds.Select(o => $"'{o}'"))})";
  953. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School")
  954. .GetItemQueryIterator<dynamic>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Debate-{_school}") }))
  955. {
  956. replies.Add(item);
  957. }
  958. return Ok(new { replies });
  959. }
  960. return Ok();
  961. }
  962. /// <summary>
  963. /// 获取订阅了相同的能力点的教师。
  964. /// </summary>
  965. /// <param name="request"></param>
  966. /// <returns></returns>
  967. [ProducesDefaultResponseType]
  968. [HttpPost("get-same-subs")]
  969. [AuthToken(Roles = "teacher,admin,area")]
  970. public async Task<IActionResult> GetSameSubs(JsonElement request)
  971. {
  972. // (string id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  973. if (!request.TryGetProperty("school", out JsonElement _school))
  974. {
  975. return Ok(new { error = 400 });
  976. }
  977. var client = _azureCosmos.GetCosmosClient();
  978. if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return Ok(new { error = 400 });
  979. if (!request.TryGetProperty("abilityId", out JsonElement _abilityId)) return Ok(new { error = 400 });
  980. List<RGroupList> yxtrain= await GroupListService.GetGroupListMemberByType(client, "yxtrain", new List<string> { "school" }, $"{_school}",_dingDing);
  981. List<dynamic> abilitySubs = new List<dynamic>();
  982. if (yxtrain.IsNotEmpty()) {
  983. var members = yxtrain.SelectMany(m => m.members).ToList();
  984. List<RMember> tmdids = members.FindAll(x => x.type == 1).Where((x, i) => members.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList();
  985. tmdids= tmdids.FindAll(x => !x.id.Equals($"{_tmdid}"));
  986. await foreach ((RMember tmdid, JsonElement sub) in GetSubsAsyn(tmdids, $"{_tmdid}", $"{_abilityId}", $"{_school}")) {
  987. AbilitySub abilitySub= sub.ToObject<AbilitySub>();
  988. if (abilitySub.uploads.IsNotEmpty()) {
  989. abilitySubs.Add(new { tmdid, sub= abilitySub });
  990. }
  991. }
  992. }
  993. return Ok(new { abilitySubs });
  994. }
  995. private async IAsyncEnumerable<(RMember, JsonElement)> GetSubsAsyn(List<RMember> tmdids,string _tmdid ,string _abilityId,string _school) {
  996. foreach (var tmdid in tmdids)
  997. {
  998. Response subs = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync($"{_abilityId}", new PartitionKey($"AbilitySub-{_school}-{tmdid.id}"));
  999. if (subs.Status==200) {
  1000. var json = await JsonDocument.ParseAsync(subs.ContentStream);
  1001. JsonElement element =json.RootElement;
  1002. yield return (tmdid, element);
  1003. }
  1004. }
  1005. }
  1006. /// <summary>
  1007. /// 获取本小组的订阅
  1008. /// </summary>
  1009. /// <param name="request"></param>
  1010. /// <returns></returns>
  1011. [ProducesDefaultResponseType]
  1012. [HttpPost("get-group-subs")]
  1013. [AuthToken(Roles = "teacher,admin,area")]
  1014. public async Task<IActionResult> GetGroupSubs(JsonElement request)
  1015. {
  1016. try
  1017. {
  1018. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return Ok(new { error = 400 });
  1019. // (string id, _, _, string school) = HttpContext.GetAuthTokenInfo();
  1020. string school = "";
  1021. if (!request.TryGetProperty("school", out JsonElement _school))
  1022. {
  1023. return Ok(new { error = 400 });
  1024. }
  1025. else
  1026. {
  1027. school = $"{_school}";
  1028. }
  1029. var client = _azureCosmos.GetCosmosClient();
  1030. if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return Ok(new { error = 400 });
  1031. request.TryGetProperty("all", out JsonElement _all);
  1032. List<Ability> abilities = new List<Ability>();
  1033. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Normal")
  1034. .GetItemQueryIterator<Ability>(queryText: $"select value(c) from c where c.status = 1 ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") }))
  1035. {
  1036. abilities.Add(item);
  1037. }
  1038. //List<ScTeacher> teachers = new List<ScTeacher>();
  1039. //await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<ScTeacher>(queryText: $"SELECT c.groupName,c.groupId, c.id, c.name, c.picture FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
  1040. //{
  1041. // if (string.IsNullOrEmpty(item.groupId))
  1042. // {
  1043. // item.groupId = "default";
  1044. // item.groupName = "默认组别";
  1045. // }
  1046. // teachers.Add(item);
  1047. //}
  1048. List<GroupList> tchLists = new List<GroupList>();
  1049. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<GroupList>(queryText: $"SELECT value(c) FROM c where c.type='research' ",
  1050. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{_school}") }))
  1051. {
  1052. tchLists.Add(item);
  1053. }
  1054. List<string> ids = tchLists.Select(x => x.id).ToList();
  1055. if (!ids.IsNotEmpty())
  1056. {
  1057. ids.Add("default");
  1058. }
  1059. (List<RMember> tmdInfos, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, ids, $"{_school}");
  1060. List<GroupMember> teachers = new List<GroupMember>();
  1061. foreach (var classInfo in classInfos)
  1062. {
  1063. foreach (var tmdinfo in classInfo.members)
  1064. {
  1065. teachers.Add(new GroupMember { groupId = classInfo.id, groupName = classInfo.name, tmdid = tmdinfo.id, tmdname = tmdinfo.name, picture = tmdinfo.picture, tag = tmdinfo.tag });
  1066. }
  1067. }
  1068. if ($"{_all}".Equals("1"))
  1069. {
  1070. List<SubGroupMember> groupMembers = new List<SubGroupMember>();
  1071. // List<Debate> debates = new List<Debate>();
  1072. // HashSet<string> comids = new HashSet<string>();
  1073. foreach (var t in teachers)
  1074. {
  1075. try
  1076. {
  1077. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher")
  1078. .GetItemQueryIterator<AbilitySub>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{school}-{t.tmdid}") }))
  1079. {
  1080. // comids.Add(item.comid);
  1081. groupMembers.Add(new SubGroupMember
  1082. {
  1083. tmdname = t.tmdname,
  1084. tmdid = t.tmdid,
  1085. picture = t.picture,
  1086. groupName = t.groupName,
  1087. groupId = t.groupId,
  1088. sub = new SubGroup
  1089. {
  1090. abilityId = item.id,
  1091. code = item.code,
  1092. uploads = item.uploads,
  1093. otherScore = item.otherScore,
  1094. comid = item.comid,
  1095. self = item.self
  1096. }
  1097. });
  1098. }
  1099. }
  1100. catch (CosmosException ex) { }
  1101. }
  1102. return Ok(new { groupMembers, abilities });
  1103. }
  1104. else
  1105. {
  1106. var teacer = teachers.FindAll(x => x.tmdid.Equals($"{_tmdid}"));
  1107. if (teacer != null)
  1108. {
  1109. List<SubGroupMember> groupMembers = new List<SubGroupMember>();
  1110. var tecs = teachers.Where(x => teacer.Select(y => y.groupId).Contains(x.groupId)).ToList();
  1111. foreach (var t in tecs)
  1112. {
  1113. //排除自己,如果不是组长则不排除
  1114. if (t.tmdid.Equals($"{_tmdid}") && string.IsNullOrEmpty(t.tag)) { continue; }
  1115. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher")
  1116. .GetItemQueryIterator<AbilitySub>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{school}-{t.tmdid}") }))
  1117. {
  1118. groupMembers.Add(new SubGroupMember
  1119. {
  1120. tmdname = t.tmdname,
  1121. tmdid = t.tmdid,
  1122. picture = t.picture,
  1123. groupName = t.groupName,
  1124. groupId = t.groupId,
  1125. sub = new SubGroup
  1126. {
  1127. abilityId = item.id,
  1128. code = item.code,
  1129. uploads = item.uploads,
  1130. otherScore = item.otherScore,
  1131. comid = item.comid,
  1132. self = item.self
  1133. },
  1134. tag = t.tag
  1135. });
  1136. }
  1137. }
  1138. return Ok(new { groupMembers, abilities });
  1139. }
  1140. else
  1141. {
  1142. return Ok(new { error = 400 });
  1143. }
  1144. }
  1145. }
  1146. catch (Exception ex)
  1147. {
  1148. await _dingDing.SendBotMsg($"OS,{_option.Location},AbilityController/SaveSubs()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  1149. return Ok(new { error = 400 });
  1150. }
  1151. }
  1152. public class GroupMember
  1153. {
  1154. public string tmdname { get; set; }
  1155. public string tmdid { get; set; }
  1156. public string picture { get; set; }
  1157. public string groupName { get; set; }
  1158. public string groupId { get; set; }
  1159. public string tag { get; set; }
  1160. }
  1161. public class SubGroupMember
  1162. {
  1163. public string tmdname { get; set; }
  1164. public string tmdid { get; set; }
  1165. public string picture { get; set; }
  1166. public string groupName { get; set; }
  1167. public string groupId { get; set; }
  1168. public SubGroup sub { get; set; }
  1169. public string tag { get; set; }
  1170. }
  1171. public class SubGroup
  1172. {
  1173. public string comid { get; set; }
  1174. public int self { get; set; }
  1175. public string abilityId { get; set; }
  1176. public string code { get; set; }
  1177. public List<SubUpload> uploads { get; set; }
  1178. public List<OtherScore> otherScore { get; set; }
  1179. }
  1180. public class RoleScore
  1181. {
  1182. /// <summary>
  1183. /// 角色类型 成员 member 学校 school 专家 expert
  1184. /// </summary>
  1185. public string roleType { get; set; }
  1186. /// <summary>
  1187. /// 评论人的id
  1188. /// </summary>
  1189. public string tmdid { get; set; }
  1190. /// <summary>
  1191. /// 评论人
  1192. /// </summary>
  1193. public string tmdname { get; set; }
  1194. /// <summary>
  1195. /// 被评论人的醍摩豆名称
  1196. /// </summary>
  1197. public string atTmdname { get; set; }
  1198. //总评 -1未评,0未通过,1合格,2优秀
  1199. public int score { get; set; } = -1;
  1200. /// <summary>
  1201. /// 某人对你这个能力点的学习评价的的评语记录的Id集合。
  1202. /// </summary>
  1203. public string reply { get; set; }
  1204. /// <summary>
  1205. /// 根据评判标准进行打分
  1206. /// </summary>
  1207. public List<ScoreUpload> scoreUploads { get; set; } = new List<ScoreUpload>();
  1208. }
  1209. }
  1210. }