GroupListController.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IdentityModel.Tokens.Jwt;
  8. using System.Linq;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.Models;
  12. using TEAMModelOS.SDK.Models;
  13. using TEAMModelOS.SDK;
  14. using TEAMModelOS.SDK.DI;
  15. using TEAMModelOS.SDK.Extension;
  16. using Azure;
  17. using TEAMModelOS.SDK.Models.Cosmos.Common;
  18. using Azure.Messaging.ServiceBus;
  19. using Microsoft.Extensions.Configuration;
  20. using TEAMModelOS.Filter;
  21. using HTEXLib.COMM.Helpers;
  22. using System.Text;
  23. using TEAMModelOS.SDK.Models.Service;
  24. using Microsoft.AspNetCore.Authorization;
  25. namespace TEAMModelOS.Controllers
  26. {
  27. [ProducesResponseType(StatusCodes.Status200OK)]
  28. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  29. [Route("grouplist")]
  30. [ApiController]
  31. public class GroupListController : ControllerBase
  32. {
  33. private AzureCosmosFactory _azureCosmos;
  34. private readonly DingDing _dingDing;
  35. private readonly Option _option;
  36. private readonly AzureServiceBusFactory _serviceBus;
  37. private readonly AzureStorageFactory _azureStorage;
  38. private readonly NotificationService _notificationService;
  39. private readonly CoreAPIHttpService _coreAPIHttpService;
  40. private const string SummarySql = " c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.leader ";
  41. public IConfiguration _configuration { get; set; }
  42. public GroupListController(CoreAPIHttpService coreAPIHttpService,AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration, NotificationService notificationService)
  43. {
  44. _azureCosmos = azureCosmos;
  45. _dingDing = dingDing;
  46. _option = option?.Value;
  47. _serviceBus = serviceBus;
  48. _configuration = configuration;
  49. _azureStorage = azureStorage;
  50. _notificationService = notificationService;
  51. _coreAPIHttpService = coreAPIHttpService;
  52. }
  53. //学生获取自己已经加入的名单和课程。
  54. [ProducesDefaultResponseType]
  55. [HttpPost("get-my-course-grouplist")]
  56. [Authorize(Roles = "IES")]
  57. public async Task<IActionResult> GetMyCourseAndGroupList(JsonElement json)
  58. {
  59. var (userid, _name, _picture, _) = HttpContext.GetAuthTokenInfo();
  60. if (!json.TryGetProperty("schoolId", out JsonElement _schoolId)) return BadRequest();
  61. var client = _azureCosmos.GetCosmosClient();
  62. object scope = null; ;
  63. HttpContext?.Items.TryGetValue("Scope", out scope);
  64. if ($"{scope}".Equals(Constant.ScopeStudent))
  65. {
  66. Student student = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<Student>(userid, new PartitionKey($"Base-{_schoolId}"));
  67. }
  68. if ($"{scope}".Equals(Constant.ScopeTmdUser))
  69. {
  70. }
  71. if ($"{scope}".Equals(Constant.ScopeTeacher))
  72. {
  73. }
  74. return Ok();
  75. }
  76. /// <summary>
  77. /// 扫码加入名单
  78. /// </summary>
  79. /// <param name="json"></param>
  80. /// <returns></returns>
  81. [ProducesDefaultResponseType]
  82. [HttpPost("scan-code-join-list")]
  83. public async Task<IActionResult> ScanCodeJoinList(JsonElement json)
  84. {
  85. if (!json.TryGetProperty("stuListNo", out JsonElement _stuListNo)) return BadRequest();
  86. json.TryGetProperty("school", out JsonElement school);
  87. var client = _azureCosmos.GetCosmosClient();
  88. json.TryGetProperty("id_token", out JsonElement id_token);
  89. var jwt = new JwtSecurityToken(id_token.GetString());
  90. var id = jwt.Payload.Sub;
  91. jwt.Payload.TryGetValue("name", out object name);
  92. jwt.Payload.TryGetValue("picture", out object picture);
  93. try
  94. {
  95. TmdUser tmduser = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<TmdUser>(id, new PartitionKey("Base"));
  96. }
  97. catch (CosmosException ex)
  98. {
  99. if (ex.Status == 404)
  100. {
  101. //如果沒有,則初始化Teacher基本資料到Cosmos
  102. TmdUser tmduser = new TmdUser
  103. {
  104. id = id,
  105. pk = "Base",
  106. code = "Base",
  107. name = name?.ToString(),
  108. picture = picture?.ToString(),
  109. //创建账号并第一次登录IES5则默认赠送1G
  110. defaultSchool = null,
  111. schools = new List<TmdUser.School>(),
  112. };
  113. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync<TmdUser>(tmduser, new PartitionKey("Base"));
  114. }
  115. }
  116. (int status, GroupList stuList) data = await GroupListService.CodeJoinList(client, $"{_stuListNo}", id, type: 1, $"{school}");
  117. //没有TmdUser时
  118. if (data.status == 0)
  119. {
  120. await GroupListService.UpsertList(data.stuList, _azureCosmos, _configuration, _serviceBus);
  121. List<string> ids = new List<string>();
  122. if (data.stuList.scope.Equals("private") && !string.IsNullOrEmpty(data.stuList.creatorId))
  123. {
  124. ids.Add(data.stuList.creatorId);
  125. }
  126. else if (data.stuList.scope.Equals("school") && !string.IsNullOrEmpty(data.stuList.school))
  127. {
  128. //通知管理员
  129. string sql = "select distinct value(c.id) from c where array_contains(c.roles,'admin')";
  130. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<string>(queryText: sql,
  131. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Teacher-{school}") }))
  132. {
  133. ids.Add(item);
  134. }
  135. }
  136. if (ids.IsNotEmpty())
  137. {
  138. string bizcode = "scan-join";
  139. Notification notification = new Notification
  140. {
  141. hubName = "hita",
  142. type = "msg",
  143. from = $"ies5:{_option.Location}:private",
  144. to = ids.Select(x => x).ToList(),
  145. label = $"{bizcode}_groupList",
  146. body = new { location = _option.Location, biz = bizcode, tmdid = id, tmdname = name, groupListName = $"{data.stuList.name}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  147. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  148. };
  149. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  150. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  151. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  152. var location = _option.Location;
  153. var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
  154. }
  155. return Ok(new { data.stuList, data.status });
  156. }
  157. else
  158. {
  159. return Ok(new { data.status });
  160. }
  161. }
  162. /// <summary>
  163. /// 根据邀请码加入名单
  164. /// </summary>
  165. /// <param name="json"></param>
  166. /// <returns></returns>
  167. [ProducesDefaultResponseType]
  168. [AuthToken(Roles = "admin,teacher,student")]
  169. [HttpPost("input-code-join-list")]
  170. [Authorize(Roles = "IES")]
  171. public async Task<IActionResult> InputCodeJoinList(JsonElement json)
  172. {
  173. if (!json.TryGetProperty("stuListNo", out JsonElement _stuListNo)) return BadRequest();
  174. var (userid, _name, _picture, school) = HttpContext.GetAuthTokenInfo();
  175. object scope = null;
  176. int type = 0;
  177. string no = null;
  178. var client = _azureCosmos.GetCosmosClient();
  179. HttpContext?.Items.TryGetValue("Scope", out scope);
  180. if ($"{scope}".Equals(Constant.ScopeStudent))
  181. {
  182. type = 2;
  183. Student student = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<Student>(userid, new PartitionKey($"Base-{school}"));
  184. no = student.no;
  185. }
  186. if ($"{scope}".Equals(Constant.ScopeTmdUser))
  187. {
  188. type = 1;
  189. }
  190. if ($"{scope}".Equals(Constant.ScopeTeacher))
  191. {
  192. type = 1;
  193. }
  194. (int status, GroupList stuList) data = await GroupListService.CodeJoinList(client, $"{_stuListNo}", userid, type, school);
  195. if (data.status == 0)
  196. {
  197. await GroupListService.UpsertList(data.stuList, _azureCosmos, _configuration, _serviceBus);
  198. List<string> ids = new List<string>();
  199. if (data.stuList.scope.Equals("private") && !string.IsNullOrEmpty(data.stuList.creatorId))
  200. {
  201. ids.Add(data.stuList.creatorId);
  202. }
  203. else if (data.stuList.scope.Equals("school") && !string.IsNullOrEmpty(data.stuList.school))
  204. {
  205. //通知管理员
  206. string sql = "select distinct value(c.id) from c where array_contains(c.roles,'admin')";
  207. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<string>(queryText: sql,
  208. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Teacher-{school}") }))
  209. {
  210. ids.Add(item);
  211. }
  212. }
  213. if (ids.IsNotEmpty()) {
  214. string bizcode = "scan-join";
  215. Notification notification = new Notification
  216. {
  217. hubName = "hita",
  218. type = "msg",
  219. from = $"ies5:{_option.Location}:private",
  220. to = ids.Select(x => x).ToList(),
  221. label = $"{bizcode}_groupList",
  222. body = new { location = _option.Location, biz = bizcode, tmdid = userid, tmdname = _name, groupListName = $"{data.stuList.name}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  223. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  224. };
  225. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  226. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  227. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  228. var location = _option.Location;
  229. var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
  230. }
  231. return Ok(new { data.stuList, data.status });
  232. }
  233. else
  234. {
  235. return Ok(new { data.status });
  236. }
  237. }
  238. /// <summary>
  239. /// 获取名单的tags
  240. /// </summary>
  241. /// <param name="json"></param>
  242. /// <returns></returns>
  243. [ProducesDefaultResponseType]
  244. [AuthToken(Roles = "admin,teacher,student")]
  245. [HttpPost("get-grouplist-tags")]
  246. [Authorize(Roles = "IES")]
  247. public async Task<IActionResult> GetGrouplistTags(JsonElement json)
  248. {
  249. var client = _azureCosmos.GetCosmosClient();
  250. var (id, _, _, school) = HttpContext.GetAuthTokenInfo();
  251. object scope = null;
  252. StringBuilder sql = new StringBuilder($"SELECT {SummarySql} ,A1.tag FROM c " +
  253. $" join A1 in c. members where A1.id='{id}' and A1.tag<>null ");
  254. HttpContext?.Items.TryGetValue("Scope", out scope);
  255. if (!string.IsNullOrEmpty(school)&& $"{scope}".Equals(Constant.ScopeStudent)) {
  256. sql.Append($" and A1.code='{school}'");
  257. }
  258. List<dynamic> groupLists = new List<dynamic>();
  259. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  260. GetItemQueryIterator<dynamic>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school}") }))
  261. {
  262. groupLists.Add(item);
  263. }
  264. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").
  265. GetItemQueryIterator<dynamic>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList") }))
  266. {
  267. groupLists.Add(item);
  268. }
  269. return Ok(new { groupLists });
  270. }
  271. /// <summary>
  272. /// 获取发布活动的名单
  273. /// </summary>
  274. /// <param name="json"></param>
  275. /// <returns></returns>
  276. [ProducesDefaultResponseType]
  277. [AuthToken(Roles = "teacher,admin,student")]
  278. [HttpPost("get-activity-grouplist")]
  279. [Authorize(Roles = "IES")]
  280. public async Task<IActionResult> GetActivityGrouplist(JsonElement json)
  281. {
  282. var client = _azureCosmos.GetCosmosClient();
  283. json.TryGetProperty("tmdid", out JsonElement tmdid);
  284. json.TryGetProperty("schoolId", out JsonElement schoolId);
  285. if (!json.TryGetProperty("opt", out JsonElement opt)) { return BadRequest(); }
  286. json.TryGetProperty("periodId", out JsonElement periodId);
  287. List<GroupListGrp> groupLists = new List<GroupListGrp>();
  288. switch (true)
  289. {
  290. //我管理的
  291. case bool when $"{opt}".Equals("manage", StringComparison.OrdinalIgnoreCase):
  292. //包含,学校的行政班,教学班
  293. json.TryGetProperty("type", out JsonElement _type);
  294. List<string> types = null ;
  295. if (_type.ValueKind.Equals(JsonValueKind.Array))
  296. {
  297. types = _type.ToObject<List<string>>();
  298. }
  299. else if (_type.ValueKind.Equals(JsonValueKind.String)) {
  300. types = new List<string> { $"{types}" };
  301. }
  302. if (types.IsEmpty() || types.Contains("class") )
  303. {
  304. StringBuilder classsql = new StringBuilder($"SELECT c.id,c.name,c.periodId ,c.year FROM c ");
  305. if (!string.IsNullOrEmpty($"{periodId}"))
  306. {
  307. classsql.Append($" where c.periodId='{periodId}' ");
  308. }
  309. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: classsql.ToString(),
  310. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schoolId}") }))
  311. {
  312. HashSet<string> groupNames = new HashSet<string>();
  313. string gpsql = $"SELECT distinct c.groupId,c.groupName FROM c where c.classId='{item.id}'and c.groupName <>null";
  314. await foreach (var gp in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: gpsql,
  315. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{schoolId}") }))
  316. {
  317. groupNames.Add(gp.groupName);
  318. }
  319. ///行政班(学生搜寻classId动态返回)class
  320. GroupListGrp group = new GroupListGrp
  321. {
  322. id = item.id,
  323. code = $"GroupList-{schoolId}",
  324. name = item.name,
  325. periodId = item.periodId,
  326. scope = "school",
  327. school = $"{schoolId}",
  328. type = "class",
  329. year = item.year,
  330. groupName = groupNames
  331. };
  332. groupLists.Add(group);
  333. }
  334. }
  335. if (types.IsEmpty() || types.Contains("teach") )
  336. {
  337. //教学班
  338. StringBuilder teachsql = new StringBuilder($" SELECT distinct value(c) FROM c where c.type='teach'");
  339. if (!string.IsNullOrEmpty($"{periodId}"))
  340. {
  341. teachsql.Append($" and c.periodId='{periodId}'");
  342. }
  343. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  344. GetItemQueryIterator<GroupList>(queryText: teachsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{schoolId}") }))
  345. {
  346. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  347. groupLists.Add(new GroupListGrp(item, groupName));
  348. }
  349. }
  350. if (types.IsEmpty() || types.Contains("research") )
  351. {
  352. //教研组
  353. StringBuilder researchsql = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='research'");
  354. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  355. GetItemQueryIterator<GroupList>(queryText: researchsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{schoolId}") }))
  356. {
  357. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  358. groupLists.Add(new GroupListGrp(item, groupName));
  359. }
  360. }
  361. if (types.IsEmpty()||types.Contains("yxtrain") )
  362. {
  363. //研修名单
  364. StringBuilder yxtrainsql = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='yxtrain'");
  365. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  366. GetItemQueryIterator<GroupList>(queryText: yxtrainsql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{schoolId}") }))
  367. {
  368. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  369. groupLists.Add(new GroupListGrp(item, groupName));
  370. }
  371. }
  372. return Ok(new { groupLists });
  373. case bool when $"{opt}".Equals("teach", StringComparison.OrdinalIgnoreCase):
  374. //我执教的
  375. //从学校的课程和个人课程搜寻与我相关的课程对应的名单。
  376. List<TeachCourse> teachCourses = new List<TeachCourse>();
  377. if (!string.IsNullOrEmpty($"{schoolId}"))
  378. {
  379. var schoolQuery = new StringBuilder($"select distinct c.name,c.id, c.scope,c.subject,c.period,A0 schedule from c join A0 in c.schedule where A0.teacherId = '{tmdid}'");
  380. if (!string.IsNullOrEmpty($"{periodId}"))
  381. {
  382. schoolQuery.Append($" and c.period.id='{periodId}' ");
  383. }
  384. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
  385. GetItemQueryIterator<TeachCourse>(queryText: schoolQuery.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{schoolId}") }))
  386. {
  387. teachCourses.Add(item);
  388. }
  389. }
  390. var query = new StringBuilder($"select distinct c.name,c.id, c.scope,c.subject,c.period,A0 schedule from c join A0 in c.schedule where A0.teacherId = '{tmdid}'");
  391. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").
  392. GetItemQueryIterator<TeachCourse>(queryText: query.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{tmdid}") }))
  393. {
  394. teachCourses.Add(item);
  395. }
  396. var classIds = teachCourses.Select(x => x.schedule).Where(y => !string.IsNullOrEmpty(y.classId)).Select(x => x.classId).Distinct().ToList();
  397. var schedule = teachCourses.Where(y => !string.IsNullOrEmpty(y.schedule.stulist)).Distinct().ToList();
  398. //var schedule = teachCourses.Select(x => new { schedule = x.schedule.Where(mm=>!string.IsNullOrEmpty(mm.stulist)), scope = x.scope }).ToList();
  399. if (classIds.IsNotEmpty())
  400. {
  401. string insql = string.Join(",", classIds.Select(x => $"'{x}'"));
  402. query = new StringBuilder($"SELECT c.id,c.name,c.periodId ,c.year FROM c where c.id in ({insql}) ");
  403. ///行政班(学生搜寻classId动态返回)class
  404. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name ,c.periodId ,c.year from c where c.id in ({insql})",
  405. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{schoolId}") }))
  406. {
  407. HashSet<string> groupNames = new HashSet<string>();
  408. string gpsql = $"SELECT distinct c.groupId,c.groupName FROM c where c.classId='{item.id}'and c.groupName <>null";
  409. await foreach (var gp in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: gpsql,
  410. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{schoolId}") }))
  411. {
  412. groupNames.Add(gp.groupName);
  413. }
  414. GroupListGrp group = new GroupListGrp
  415. {
  416. id = item.id,
  417. code = $"GroupList-{schoolId}",
  418. name = item.name,
  419. periodId = item.periodId,
  420. scope = "school",
  421. school = $"{schoolId}",
  422. type = "class",
  423. year = item.year,
  424. groupName = groupNames
  425. };
  426. groupLists.Add(group);
  427. }
  428. }
  429. if (schedule.IsNotEmpty())
  430. {
  431. var privateList = schedule.Where(x => x.scope.Equals("private")).Select(x => x.schedule.stulist).Distinct();
  432. if (privateList.Count() > 0)
  433. {
  434. string insql = string.Join(",", privateList.Select(x => $"'{x}'"));
  435. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupList>(queryText: $"select distinct {SummarySql} from c where c.id in ({insql})",
  436. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
  437. {
  438. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  439. groupLists.Add(new GroupListGrp(item, groupName));
  440. }
  441. }
  442. var schoolList = schedule.Where(x => x.scope.Equals("school")).Select(x => x.schedule.stulist).Distinct();
  443. if (schoolList.Count() > 0)
  444. {
  445. List<GroupListDto> groups = new List<GroupListDto>();
  446. string insql = string.Join(",", schoolList.Select(x => $"'{x}'"));
  447. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: $"select distinct {SummarySql} from c where c.id in ({insql})",
  448. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{schoolId}") }))
  449. {
  450. HashSet<string> groupName = item.members.Where(x => !string.IsNullOrEmpty(x.groupName)).Select(y => y.groupName).ToHashSet();
  451. groupLists.Add(new GroupListGrp(item, groupName));
  452. }
  453. }
  454. }
  455. List<CourseGroupList> courseGroups = new List<CourseGroupList>();
  456. teachCourses.GroupBy(y => (y.id, y.name, y.scope, y.period.name, y.period.id, y.subject.name, y.subject.id)).ToList().ForEach(x => {
  457. List<GroupListGrp> classIds = groupLists.Where(n => x.Where(m => !string.IsNullOrEmpty(m.schedule.classId)).Select(b=>b.schedule.classId).Contains(n.id)).ToList();
  458. List<GroupListGrp> stulists = groupLists.Where(n => x.Where(m => !string.IsNullOrEmpty(m.schedule.stulist)).Select(b => b.schedule.stulist).Contains(n.id)).ToList();
  459. if (classIds == null)
  460. {
  461. classIds = new List<GroupListGrp>();
  462. }
  463. if (stulists != null)
  464. {
  465. classIds.AddRange(stulists);
  466. }
  467. CourseGroupList groupList = new CourseGroupList()
  468. {
  469. scope = x.Key.Item3,
  470. subject = x.Key.Item6,
  471. period = x.Key.Item4,
  472. id = x.Key.Item1,
  473. name = x.Key.Item2,
  474. groups = classIds
  475. };
  476. courseGroups.Add(groupList);
  477. });
  478. return Ok(new { groupLists = courseGroups });
  479. case bool when $"{opt}".Equals("private", StringComparison.OrdinalIgnoreCase):
  480. //我个人的
  481. break;
  482. default:
  483. break;
  484. }
  485. return Ok(new { error = 1, msg = "参数异常" });
  486. }
  487. /// <summary>
  488. /// 根据任意名单id获取成员信息。
  489. /// </summary>
  490. /// <param name="json"></param>
  491. /// <returns></returns>
  492. [ProducesDefaultResponseType]
  493. [AuthToken(Roles = "teacher,admin,student")]
  494. [HttpPost("get-members-listids")]
  495. [Authorize(Roles = "IES")]
  496. public async Task<IActionResult> GetMembersListids(JsonElement json)
  497. {
  498. var client = _azureCosmos.GetCosmosClient();
  499. if (!json.TryGetProperty("ids", out JsonElement ids)) return BadRequest();
  500. json.TryGetProperty("schoolId", out JsonElement schoolId);
  501. List<string> listids = ids.ToObject<List<string>>();
  502. (List < RMember > members,List < RGroupList > groups) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, listids, $"{schoolId}");
  503. return Ok(new { groups, members });
  504. }
  505. /// <summary>
  506. /// 根据任意名单id获取名单摘要信息。
  507. /// </summary>
  508. /// <param name="json"></param>
  509. /// <returns></returns>
  510. [ProducesDefaultResponseType]
  511. [AuthToken(Roles = "teacher,admin,student")]
  512. [HttpPost("get-grouplist-listids")]
  513. [Authorize(Roles = "IES")]
  514. public async Task<IActionResult> GetGroupListListids(JsonElement json)
  515. {
  516. var client = _azureCosmos.GetCosmosClient();
  517. if (!json.TryGetProperty("ids", out JsonElement ids)) return BadRequest();
  518. json.TryGetProperty("schoolId", out JsonElement schoolId);
  519. List<string> listids = ids.ToObject<List<string>>();
  520. List<GroupListDto> groups = await GroupListService.GetGroupListListids(client, _dingDing, listids, $"{schoolId}", SummarySql);
  521. return Ok(new { groups });
  522. }
  523. /// <summary>
  524. /// 获取名单和成员信息。
  525. /// </summary>
  526. /// <param name="json"></param>
  527. /// <returns></returns>
  528. [ProducesDefaultResponseType]
  529. [AuthToken(Roles = "teacher,admin,student")]
  530. [HttpPost("get-grouplists-members")]
  531. [Authorize(Roles = "IES")]
  532. public async Task<IActionResult> GetGrouplistsMembers(JsonElement json)
  533. {
  534. try
  535. {
  536. var client = _azureCosmos.GetCosmosClient();
  537. json.TryGetProperty("tmdid", out JsonElement _tmdid);
  538. json.TryGetProperty("schoolId", out JsonElement _schoolId);
  539. if (!json.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  540. if (!json.TryGetProperty("type", out JsonElement type)) return BadRequest();
  541. json.TryGetProperty("periodId", out JsonElement periodId);
  542. json.TryGetProperty("no", out JsonElement no);
  543. StringBuilder sql = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='{type}'");
  544. List<RGroupList> groups = new List<RGroupList>();
  545. string tbname = "Teacher";
  546. string code = $"GroupList";
  547. if ($"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase))
  548. {
  549. tbname = "School";
  550. code = $"GroupList-{_schoolId}";
  551. if (!string.IsNullOrEmpty($"{periodId}"))
  552. {
  553. sql.Append($" and c.periodId='{periodId}'");
  554. }
  555. if (!string.IsNullOrEmpty($"{no}"))
  556. {
  557. sql.Append($" and c.no='{no}'");
  558. }
  559. }
  560. else
  561. {
  562. sql.Append($" and c.creatorId='{_tmdid}'");
  563. }
  564. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, tbname).GetItemQueryIterator<RGroupList>(queryText: sql.ToString(),
  565. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(code) }))
  566. {
  567. groups.Add(item);
  568. }
  569. (List<RGroupList> groupsData, List<RMember> members) = await GroupListService.GetGroupListMemberInfo(_coreAPIHttpService, client, $"{type}", groups, tbname,_dingDing,$"{_schoolId}");
  570. return Ok(new { groups = groupsData, members });
  571. }
  572. catch (CosmosException ex)
  573. {
  574. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplists-members()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  575. }
  576. catch (Exception ex)
  577. {
  578. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplists-members()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  579. }
  580. return Ok();
  581. }
  582. /// <summary>
  583. /// 获取名单列表
  584. /// </summary>
  585. /// <param name="json"></param>
  586. /// <returns></returns>
  587. [ProducesDefaultResponseType]
  588. [AuthToken(Roles = "teacher,admin,student")]
  589. [HttpPost("get-grouplists")]
  590. [Authorize(Roles = "IES")]
  591. public async Task<IActionResult> GetGrouplists(JsonElement json)
  592. {
  593. try
  594. {
  595. var client = _azureCosmos.GetCosmosClient();
  596. json.TryGetProperty("tmdid", out JsonElement _tmdid);
  597. json.TryGetProperty("schoolId", out JsonElement _schoolId);
  598. if (!json.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  599. if (!json.TryGetProperty("type", out JsonElement type)) return BadRequest();
  600. json.TryGetProperty("periodId", out JsonElement periodId);
  601. json.TryGetProperty("no", out JsonElement no);
  602. StringBuilder sql = new StringBuilder($"SELECT distinct {SummarySql} FROM c where c.type='{type}'");
  603. List<GroupListDto> groups = new List<GroupListDto>();
  604. string tbname = "Teacher";
  605. string code = $"GroupList";
  606. if ($"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase))
  607. {
  608. tbname = "School";
  609. code = $"GroupList-{_schoolId}";
  610. if (!string.IsNullOrEmpty($"{periodId}"))
  611. {
  612. sql.Append($" and c.periodId='{periodId}'");
  613. }
  614. if (!string.IsNullOrEmpty($"{no}"))
  615. {
  616. sql.Append($" and c.no='{no}'");
  617. }
  618. }
  619. else
  620. {
  621. sql.Append($" and c.creatorId='{_tmdid}'");
  622. }
  623. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, tbname).GetItemQueryIterator<GroupListDto>(queryText: sql.ToString(),
  624. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(code) }))
  625. {
  626. groups.Add(item);
  627. }
  628. return Ok(new { groups });
  629. }
  630. catch (CosmosException ex)
  631. {
  632. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplists()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  633. }
  634. catch (Exception ex)
  635. {
  636. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplists()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  637. }
  638. return Ok();
  639. }
  640. /// <summary>
  641. /// 根据id,code获取学校行政班信息和学生信息。用于维护学生基本信息。
  642. /// </summary>
  643. /// <param name="json"></param>
  644. /// <returns></returns>
  645. [ProducesDefaultResponseType]
  646. [AuthToken(Roles = "teacher,admin")]
  647. [HttpPost("get-classstudents-idcode")]
  648. [Authorize(Roles = "IES")]
  649. public async Task<IActionResult> GetClassStudentsIdcode(JsonElement json) {
  650. if (!json.TryGetProperty("id", out JsonElement id)) return BadRequest();
  651. if (!json.TryGetProperty("code", out JsonElement _code)) return BadRequest();
  652. try {
  653. var client = _azureCosmos.GetCosmosClient();
  654. Class clazz = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Class>($"{id}", new PartitionKey($"Class-{_code}"));
  655. List<Student> students = new List<Student>();
  656. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId = '{clazz.id}'",
  657. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{_code}") }))
  658. {
  659. item.salt = null;
  660. item.pw = null;
  661. students.Add(item);
  662. }
  663. return Ok(new { classInfo= clazz, students= students });
  664. } catch (Exception ex) {
  665. return Ok(new { error = 404,msg="班级不存在!" });
  666. }
  667. }
  668. //处理通用名单
  669. [ProducesDefaultResponseType]
  670. [AuthToken(Roles = "teacher,admin,student")]
  671. [HttpPost("get-grouplist-idcode")]
  672. [Authorize(Roles = "IES")]
  673. public async Task<IActionResult> GetGrouplistIdcode(JsonElement json)
  674. {
  675. RGroupList groupList = null;
  676. try
  677. {
  678. var client = _azureCosmos.GetCosmosClient();
  679. json.TryGetProperty("type", out JsonElement _type);
  680. json.TryGetProperty("code", out JsonElement _code);
  681. if (!json.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  682. if (!json.TryGetProperty("id", out JsonElement id)) return BadRequest();
  683. string tbname = $"{scope}".Equals("private") ? "Teacher" : "School";
  684. string code = "";
  685. if (string.IsNullOrEmpty($"{_type}") || !$"{_type}".Equals("class"))
  686. {
  687. if ($"{scope}".Equals("private"))
  688. {
  689. //私人名单
  690. code = "GroupList";
  691. }
  692. else
  693. {
  694. //学校自定义名单
  695. code = !code.StartsWith("GroupList-") ? $"GroupList-{_code}" : code;
  696. }
  697. groupList = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<RGroupList>($"{id}", new PartitionKey($"{code}"));
  698. }
  699. else if($"{_type}".Equals("class")) {
  700. try {
  701. code = $"Class-{_code}";
  702. Class clazz = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Class>($"{id}", new PartitionKey($"{code}"));
  703. if (clazz != null) {
  704. List<Student> students = new List<Student>();
  705. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId = '{clazz.id}'",
  706. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{_code}") }))
  707. {
  708. students.Add(item);
  709. }
  710. ///行政班(学生搜寻classId动态返回)class
  711. List<RMember> smembers = students.Where(x => x.classId.Equals(clazz.id)).Select(y => new RMember { id = y.id, code = $"{_code}", name = y.name, type = 2, picture = y.picture, no = y.no,classId=y.classId, groupId = y.groupId, groupName = y.groupName }).ToList();
  712. groupList = new RGroupList
  713. {
  714. id=clazz.id,
  715. code=$"GroupList-{clazz.school}",
  716. name=clazz.name,
  717. periodId=clazz.periodId,
  718. pk= "GroupList",
  719. year=clazz.year,
  720. school=clazz.school ,
  721. scope = "school",
  722. type = "class",
  723. scount = smembers.Count,
  724. no=clazz.no,
  725. leader=clazz.teacher?.id,
  726. members= smembers,
  727. };
  728. }
  729. }catch (CosmosException ex) {
  730. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplist-idcode()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  731. return Ok(new { groupList });
  732. }
  733. }
  734. (List<RGroupList> groupsData, List<RMember> members) = await GroupListService.GetGroupListMemberInfo(_coreAPIHttpService, client, $"{groupList.type}", new List<RGroupList> { groupList }, tbname,_dingDing, $"{_code}");
  735. groupList = groupsData.FirstOrDefault();
  736. }
  737. catch (CosmosException ex)
  738. {
  739. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplist-idcode()\n{ex.Message}{ex.StackTrace}\n {json}", GroupNames.醍摩豆服務運維群組);
  740. return Ok(new { groupList });
  741. }
  742. catch (Exception ex)
  743. {
  744. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/get-grouplist-idcode()\n{ex.Message}{ex.StackTrace}\n{json}", GroupNames.醍摩豆服務運維群組);
  745. }
  746. return Ok(new { groupList });
  747. }
  748. /// <summary>
  749. /// 保存或更新通用名单
  750. /// </summary>
  751. /// <param name="json"></param>
  752. /// <returns></returns>
  753. [ProducesDefaultResponseType]
  754. [AuthToken(Roles = "teacher,admin")]
  755. [HttpPost("upsert-grouplist")]
  756. [Authorize(Roles = "IES")]
  757. public async Task<IActionResult> UpsertGroupList(GroupList list)
  758. {
  759. try
  760. {
  761. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  762. if (string.IsNullOrEmpty(list.type))
  763. {
  764. return BadRequest();
  765. }
  766. list.year = list.year > 0 ? list.year : DateTimeOffset.UtcNow.Year;
  767. list.ttl = -1;
  768. list.creatorId = userid;
  769. list.school = string.IsNullOrEmpty(list.school) ? school : list.school;
  770. list.pk = "GroupList";
  771. if (list.scope.Equals("private"))
  772. {
  773. //私人名单
  774. list.code = "GroupList";
  775. list.school = null;
  776. }
  777. else
  778. {
  779. //学校自定义名单
  780. list.code = !list.code.StartsWith("GroupList-") ? $"GroupList-{list.code}" : list.code;
  781. }
  782. switch (true)
  783. {
  784. //普通学生名单(包含学校教学班名单,个人课程名单),其中学生成员账号类型可以是学校学生账号和醍摩豆ID,分区键为GroupList-hbcn
  785. case bool when $"{list.type}".Equals("teach", StringComparison.OrdinalIgnoreCase):
  786. list.type = "teach";
  787. list = await GroupListService.CheckListNo(list, _azureCosmos, _dingDing, _option);
  788. list = await GroupListService.UpsertList(list, _azureCosmos, _configuration, _serviceBus);
  789. break;
  790. //教研组名单,只有加入学校的老师名单 成员账号类型是醍摩豆ID,保存在学校表,分区键为GroupList-hbcn
  791. case bool when $"{list.type}".Equals("research", StringComparison.OrdinalIgnoreCase):
  792. list.type = "research";
  793. list.scope = "school";
  794. list = await GroupListService.UpsertList(list, _azureCosmos, _configuration, _serviceBus);
  795. break;
  796. //个人好友名单,成员账号类型可以是学校学生账号和醍摩豆ID,分区键为GroupList
  797. case bool when $"{list.type}".Equals("friend", StringComparison.OrdinalIgnoreCase):
  798. list.type = "friend";
  799. list.scope = "private";
  800. list = await GroupListService.UpsertList(list, _azureCosmos,_configuration, _serviceBus);
  801. break;
  802. //社交群组类型(包含学校交流群组,个人交流群组),成员账号类型可以是学校学生账号和醍摩豆ID,,分区键为GroupList-hbcn
  803. case bool when $"{list.type}".Equals("group", StringComparison.OrdinalIgnoreCase):
  804. list.type = "group";
  805. list = await GroupListService.CheckListNo(list, _azureCosmos, _dingDing, _option);
  806. list = await GroupListService.UpsertList(list, _azureCosmos, _configuration, _serviceBus);
  807. break;
  808. //社交群组类型(包含学校交流群组,个人交流群组),成员账号类型可以是学校学生账号和醍摩豆ID,,分区键为GroupList-hbcn
  809. case bool when $"{list.type}".Equals("yxtrain", StringComparison.OrdinalIgnoreCase):
  810. list.type = "yxtrain";
  811. list.scope = "school";
  812. list = await GroupListService.UpsertList(list, _azureCosmos, _configuration, _serviceBus);
  813. break;
  814. default:
  815. return Ok(new { error = 400, msg = "参数错误!" });
  816. }
  817. return Ok(new { list });
  818. }
  819. catch (Exception ex)
  820. {
  821. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/upsert-grouplist()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  822. return BadRequest();
  823. }
  824. }
  825. //删除名单
  826. [ProducesDefaultResponseType]
  827. [AuthToken(Roles = "teacher,admin")]
  828. [HttpPost("delete-grouplist")]
  829. [Authorize(Roles = "IES")]
  830. public async Task<IActionResult> DeleteGroupList(JsonElement json)
  831. {
  832. try
  833. {
  834. if (!json.TryGetProperty("code", out JsonElement code)) return BadRequest();
  835. if (!json.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  836. if (!json.TryGetProperty("id", out JsonElement id)) return BadRequest();
  837. var client = _azureCosmos.GetCosmosClient();
  838. GroupChange change = new GroupChange();
  839. string tbname = "";
  840. string datacode = "";
  841. if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
  842. {
  843. tbname = "School";
  844. datacode = $"GroupList-{code}";
  845. }
  846. else
  847. {
  848. tbname = "Teacher";
  849. datacode = $"GroupList";
  850. }
  851. GroupList groupList = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync<GroupList>(id.ToString(), new PartitionKey(datacode));
  852. var tleave = groupList.members.FindAll(x => x.type == 1);
  853. if (tleave.IsNotEmpty())
  854. {
  855. if (groupList.type.Equals("research")||groupList.type.Equals("yxtrain"))
  856. {
  857. change.tchleave.AddRange(tleave);
  858. }
  859. else
  860. {
  861. change.tmdleave.AddRange(tleave);
  862. }
  863. }
  864. var sleave = groupList.members.FindAll(x => x.type == 2);
  865. if (sleave.IsNotEmpty())
  866. {
  867. change.stuleave.AddRange(sleave);
  868. }
  869. change.listid = groupList.id;
  870. change.scope = groupList.scope;
  871. change.originCode = $"{code}";
  872. change.school = groupList.school;
  873. change.creatorId = groupList.creatorId;
  874. change.type = groupList.type;
  875. if (change.tmdleave.IsNotEmpty() || change.tchleave.IsNotEmpty() || change.stuleave.IsNotEmpty()) {
  876. var messageChange = new ServiceBusMessage(change.ToJsonString());
  877. messageChange.ApplicationProperties.Add("name", "GroupChange");
  878. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  879. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
  880. }
  881. await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemStreamAsync(id.ToString(), new PartitionKey(datacode));
  882. return Ok(new { id });
  883. }
  884. catch (Exception ex)
  885. {
  886. await _dingDing.SendBotMsg($"OS,{_option.Location},grouplist/delete-grouplist()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  887. return Ok(new { error=400 });
  888. }
  889. }
  890. }
  891. }