AbilitySubController.cs 70 KB

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