ActivityController.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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.Linq;
  8. using System.Text;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.Models;
  12. using TEAMModelOS.SDK.Models;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Extension;
  15. using Azure;
  16. using Microsoft.Extensions.Configuration;
  17. using TEAMModelOS.Filter;
  18. using HTEXLib.COMM.Helpers;
  19. using TEAMModelOS.SDK;
  20. using StackExchange.Redis;
  21. using System.Text.RegularExpressions;
  22. using Microsoft.AspNetCore.Authorization;
  23. using OpenXmlPowerTools;
  24. namespace TEAMModelOS.Controllers
  25. {
  26. [ProducesResponseType(StatusCodes.Status200OK)]
  27. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  28. [Route("activity")]
  29. [ApiController]
  30. public class ActivityController : ControllerBase
  31. {
  32. private AzureCosmosFactory _azureCosmos;
  33. private readonly DingDing _dingDing;
  34. private readonly CoreAPIHttpService _coreAPIHttpService;
  35. private readonly Option _option;
  36. private readonly AzureServiceBusFactory _serviceBus;
  37. private readonly AzureStorageFactory _azureStorage;
  38. private readonly AzureRedisFactory _azureRedis;
  39. public IConfiguration _configuration { get; set; }
  40. public ActivityController(AzureRedisFactory azureRedis, AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration)
  41. {
  42. _azureCosmos = azureCosmos;
  43. _dingDing = dingDing;
  44. _option = option?.Value;
  45. _serviceBus = serviceBus;
  46. _configuration = configuration;
  47. _azureStorage = azureStorage;
  48. _azureRedis = azureRedis;
  49. _coreAPIHttpService = coreAPIHttpService;
  50. }
  51. /// <summary>
  52. /// 添加活动参与对象,学校,教师
  53. /// </summary>
  54. /// <param name="request"></param>
  55. /// <returns></returns>
  56. [ProducesDefaultResponseType]
  57. [AuthToken(Roles = "admin,area")]
  58. [HttpPost("invite-target")]
  59. [Authorize(Roles = "IES")]
  60. public async Task<IActionResult> InviteTarget (JsonElement request)
  61. {
  62. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  63. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  64. switch (true)
  65. {
  66. case bool when $"{grant_type}".Equals("schools", StringComparison.OrdinalIgnoreCase):
  67. {
  68. if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
  69. string sql = string.Empty;
  70. if (_scope.GetString().Equals("public", StringComparison.OrdinalIgnoreCase))
  71. {
  72. sql = "select c.id,c.name ,c.picture,c.region,c.province,c.city,c.areaId from c where c.code='Base' ";
  73. }
  74. else {
  75. if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  76. sql = $"select c.id,c.name ,c.picture,c.region,c.province,c.city,c.areaId from c where c.code='Base' and c.areaId='{_areaId}' ";
  77. }
  78. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<School>(sql, "Base");
  79. var sc= result.list.FindAll(z => !string.IsNullOrWhiteSpace(z.areaId));
  80. if (sc.IsNotEmpty()) {
  81. string areaSql = $"select value c from c where c.id in ({string.Join(",",sc.Select(z=>$"'{z.areaId}'").ToHashSet())})";
  82. var areaResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<Area>(sql, "Base-Area");
  83. if (areaResult.list.IsNotEmpty()) {
  84. List<dynamic> schools= new List<dynamic>();
  85. foreach (var item in result.list) {
  86. if (!string.IsNullOrWhiteSpace(item.areaId))
  87. {
  88. var area = areaResult.list.Find(z => z.id.Equals(item.areaId));
  89. schools.Add(new { item.id, item.name, item.picture, item.region, item.province, item.city, item.areaId, areaName = area?.name });
  90. }
  91. else {
  92. schools.Add(new { item.id, item.name, item.picture, item.region, item.province, item.city, item.areaId, areaName = string.Empty });
  93. }
  94. }
  95. }
  96. }
  97. return Ok(new {code=200, schools = result.list.Select(z=>new { z.id,z.name,z.picture,z.region,z.province,z.city,z.areaId, areaName = string.Empty }) });
  98. }
  99. case bool when $"{grant_type}".Equals("teachers", StringComparison.OrdinalIgnoreCase):
  100. {
  101. if (!string.IsNullOrWhiteSpace(school)) {
  102. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  103. string sql = $"select c.id,c.name ,c.picture from c where c.code='Teacher-{school}' ";
  104. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<SchoolTeacher>(sql, $"Teacher-{school}");
  105. return Ok(new { code = 200, teachers = result.list.Select(z=>new { z.id,z.name,z.picture,school,schooName = schoolbase.name}) });
  106. }
  107. break;
  108. }
  109. }
  110. return Ok(new { code = 400 });
  111. }
  112. /// <summary>
  113. /// 活动创建
  114. /// </summary>
  115. /// <param name="request"></param>
  116. /// <returns></returns>
  117. [ProducesDefaultResponseType]
  118. [AuthToken(Roles = "teacher,admin,area")]
  119. [HttpPost("manage")]
  120. [Authorize(Roles = "IES")]
  121. public async Task<IActionResult> Manage(JsonElement request)
  122. {
  123. try
  124. {
  125. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  126. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  127. var client = _azureCosmos.GetCosmosClient();
  128. switch (true)
  129. {
  130. case bool when $"{grant_type}".Equals("create", StringComparison.OrdinalIgnoreCase):
  131. {
  132. if (!request.TryGetProperty("Activity", out JsonElement _activity)) return Ok(new { error = ResponseCode._400ParamsError, msg = "活动信息参数错误" });
  133. Activity activity = _activity.ToObject<Activity>();
  134. activity.id=!string.IsNullOrWhiteSpace(activity.id)?activity.id: Guid.NewGuid().ToString();
  135. activity.code="Activity";
  136. activity.pk="Activity";
  137. //如果是区级活动,enroll报名制,则学校的确认状态默认为1 。
  138. //if (activity.scope.Equals("area", StringComparison.OrdinalIgnoreCase) && activity.joinMode.Equals("enroll", StringComparison.OrdinalIgnoreCase))
  139. //{
  140. // activity.schools.ForEach(z => z.status=1);
  141. //}
  142. //醍摩豆智慧学区
  143. if (!activity.owner.Equals("02944f32-f534-3397-ea56-e6f1fc6c3714", StringComparison.OrdinalIgnoreCase) && activity.scope.Equals("public", StringComparison.OrdinalIgnoreCase))
  144. {
  145. return Ok(new { error = ResponseCode._400ParamsError, msg = "公开的活动只能由醍摩豆智慧学区发布!" });
  146. }
  147. ValidResult validResult = activity.Valid();
  148. if (validResult.isVaild)
  149. {
  150. activity.creatorId=tmdid;
  151. activity.createTime= DateTimeOffset.Now.ToUnixTimeMilliseconds();
  152. activity.year=DateTimeOffset.Now.Year;
  153. foreach (var module in activity.modules) {
  154. switch (true)
  155. {
  156. //赛课
  157. case bool when module.Equals("Contest"):
  158. {
  159. if (!request.TryGetProperty("Contest", out JsonElement _contest))
  160. {
  161. return Ok(new { error = ResponseCode._400ParamsError, msg = "赛课信息参数错误" });
  162. }
  163. Contest contest = _activity.ToObject<Contest>();
  164. if (contest!=null) {
  165. contest.id=activity.id;
  166. contest.code="Contest";
  167. contest.pk="Contest";
  168. ValidResult validResultContest = contest.Valid();
  169. if (validResultContest.isVaild)
  170. {
  171. if (contest.modules.Contains("review")) {
  172. if (!request.TryGetProperty("reviewConfig", out JsonElement _reviewConfig))
  173. {
  174. return Ok(new { error = ResponseCode._400ParamsError, msg = "评审未配置" });
  175. }
  176. if (contest.review== null) {
  177. return Ok(new { error = ResponseCode._400ParamsError, msg = "评审未配置" });
  178. }
  179. ReviewRuleTree ruleTree = _reviewConfig.ToObject<ReviewRuleTree>();
  180. var reviewRule = await ActivityService.UpsertReviewRule(ruleTree, activity, _azureCosmos);
  181. contest.review.ruleId = reviewRule.id;
  182. contest.review.ruleName = reviewRule.name;
  183. }
  184. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(contest, new PartitionKey(contest.code));
  185. }
  186. else {
  187. return Ok(validResult);
  188. }
  189. }
  190. break;
  191. }
  192. //培训
  193. case bool when module.Equals("Training"):
  194. {
  195. break;
  196. }
  197. //教研
  198. case bool when module.Equals("Research"):
  199. {
  200. break;
  201. }
  202. }
  203. }
  204. //保存活动基础信息
  205. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).UpsertItemAsync(activity, new PartitionKey(activity.code));
  206. }
  207. else
  208. {
  209. return Ok(validResult);
  210. }
  211. break;
  212. }
  213. case bool when $"{grant_type}".Equals("list-area", StringComparison.OrdinalIgnoreCase):
  214. {
  215. if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  216. string yearSql = $" and c.year={DateTimeOffset.Now.Year}";
  217. if (request.TryGetProperty("year", out JsonElement _year)) {
  218. yearSql = $" and c.year={_year}";
  219. }
  220. string sql = $"select value c from c where c.scope='area' and c.owner='{_areaId}' {yearSql} ";
  221. //醍摩豆智慧学区
  222. if (_areaId.GetString().Equals("02944f32-f534-3397-ea56-e6f1fc6c3714", StringComparison.OrdinalIgnoreCase)) {
  223. sql = $"select value c from c where c.owner='{_areaId}' {yearSql } and ( c.scope='area' or c.scope='public' ) ";
  224. }
  225. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sql, "Activity");
  226. return Ok(new { activities = result.list.OrderByDescending(z=>z.stime) });
  227. }
  228. case bool when $"{grant_type}".Equals("list-school", StringComparison.OrdinalIgnoreCase):
  229. {
  230. if (!string.IsNullOrWhiteSpace(school)) {
  231. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  232. List<Activity> activities = new List<Activity>();
  233. string yearSql = $" and c.year={DateTimeOffset.Now.Year}";
  234. if (request.TryGetProperty("year", out JsonElement _year))
  235. {
  236. yearSql = $" and c.year={_year}";
  237. }
  238. //获取开放的
  239. {
  240. //完全开放 所有的学校
  241. string sqlOpen = $"select value c from c where c.scope='public'{yearSql} and (c.publish=1 or c.publish=2 ) and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false ) ";
  242. var resultOpen= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlOpen, "Activity");
  243. activities.AddRange(resultOpen.list);
  244. //部分学校
  245. string sqlSchool = $"select value c from c join s in c.invitedSchools where c.scope='public'{yearSql} and (c.publish=1 or c.publish=2 ) and s.id='{school}' ";
  246. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  247. resultSchool.list.ForEach(z => {
  248. var confirmedSchool = z.confirmedSchools.Find(z => z.id.Equals(school));
  249. if (confirmedSchool==null)
  250. {
  251. z.confirmedSchools.Add(new ActivityConfirmedSchool
  252. {
  253. id=schoolbase.id,
  254. name=schoolbase.name,
  255. picture=schoolbase.picture,
  256. status=0
  257. });
  258. }
  259. });
  260. activities.AddRange(resultSchool.list);
  261. }
  262. //获取区级下放的
  263. {
  264. if (!string.IsNullOrWhiteSpace(schoolbase.areaId)) {
  265. //区级所有学校
  266. string sqlOpen = $"select value c from c where c.scope='area'{yearSql} and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false) ";
  267. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlOpen, "Activity");
  268. resultOpen.list.ForEach(z => {
  269. var confirmedSchool = z.confirmedSchools.Find(z => z.id.Equals(school));
  270. if (confirmedSchool==null)
  271. {
  272. z.confirmedSchools.Add(new ActivityConfirmedSchool
  273. {
  274. id=schoolbase.id,
  275. name=schoolbase.name,
  276. picture=schoolbase.picture,
  277. status=0
  278. });
  279. }
  280. });
  281. activities.AddRange(resultOpen.list);
  282. //区级部分学校
  283. string sqlSchool = $"select value c from c join s in c.invitedSchools where c.scope='area'{yearSql} and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and s.id='{school}' ";
  284. var resultSchool= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  285. resultSchool.list.ForEach(z => {
  286. var confirmedSchool = z.confirmedSchools.Find(z => z.id.Equals(school));
  287. if (confirmedSchool==null)
  288. {
  289. z.confirmedSchools.Add(new ActivityConfirmedSchool
  290. {
  291. id=schoolbase.id,
  292. name=schoolbase.name,
  293. picture=schoolbase.picture,
  294. status=0
  295. });
  296. }
  297. });
  298. activities.AddRange(resultSchool.list);
  299. }
  300. }
  301. //获取学校自己的
  302. {
  303. string sqlSchool = $"select value c from c where c.scope='school'{yearSql} and c.owner='{school}' ";
  304. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  305. activities.AddRange(resultSchool.list);
  306. }
  307. return Ok(new { activities = activities.OrderByDescending(z => z.stime) });
  308. }
  309. break;
  310. }
  311. case bool when $"{grant_type}".Equals("list-teacher", StringComparison.OrdinalIgnoreCase):
  312. {
  313. List<Activity> activities = new List<Activity>();
  314. string yearSql = $" and c.year={DateTimeOffset.Now.Year}";
  315. if (request.TryGetProperty("year", out JsonElement _year))
  316. {
  317. yearSql = $" and c.year={_year}";
  318. }
  319. if (!string.IsNullOrWhiteSpace(school)) {
  320. School schoolbase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  321. //获取区级下放的
  322. {
  323. if (!string.IsNullOrWhiteSpace(schoolbase.areaId))
  324. {
  325. //区级所有学校
  326. string sqlOpen = $"select value c from c join s in c.confirmedSchools where c.scope='area'{yearSql} and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false) and s.id='{school}' and s.status=1 ";
  327. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlOpen, "Activity");
  328. resultOpen.list.ForEach(z => {
  329. //处理是否是邀请制
  330. if (z.joinMode.Equals("invite"))
  331. {
  332. var inviteTeacher = z.inviteTeachers.Find(t => t.id.Equals(tmdid));
  333. if (inviteTeacher!=null) {
  334. activities.Add(z);
  335. }
  336. }
  337. else
  338. {
  339. activities.Add(z);
  340. }
  341. });
  342. //区级部分学校
  343. string sqlSchool = $"select value c from c join i in c.invitedSchools join s in c.confirmedSchools where c.scope='area'{yearSql} and (c.publish=1 or c.publish=2 ) and c.owner='{schoolbase.areaId}' and i.id='{school}' and s.id='{school}' and s.status=1 ";
  344. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  345. resultSchool.list.ForEach(z => {
  346. //处理是否是邀请制
  347. if (z.joinMode.Equals("invite"))
  348. {
  349. var inviteTeacher = z.inviteTeachers.Find(t => t.id.Equals(tmdid));
  350. if (inviteTeacher!=null)
  351. {
  352. activities.Add(z);
  353. }
  354. }
  355. else
  356. {
  357. activities.Add(z);
  358. }
  359. });
  360. }
  361. }
  362. //获取学校自己的
  363. {
  364. string sqlSchool = $"select value c from c where c.scope='school'{yearSql} and (c.publish=1 or c.publish=2 ) and c.owner='{school}' ";
  365. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  366. resultSchool.list.ForEach(z => {
  367. //处理是否是邀请制
  368. if (z.joinMode.Equals("invite"))
  369. {
  370. var inviteTeacher = z.inviteTeachers.Find(t => t.id.Equals(tmdid));
  371. if (inviteTeacher!=null)
  372. {
  373. activities.Add(z);
  374. }
  375. }
  376. else {
  377. activities.Add(z);
  378. }
  379. });
  380. }
  381. }
  382. //获取开放的
  383. {
  384. //完全开放 所有的学校
  385. string sqlOpen = $"select value c from c where c.scope='public'{yearSql} and (c.publish=1 or c.publish=2 ) and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false ) ";
  386. var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlOpen, "Activity");
  387. activities.AddRange(resultOpen.list);
  388. //部分学校
  389. string sqlSchool = $"select value c from c join i in c.invitedSchools join s in c.confirmedSchools where c.scope='public'{yearSql} and (c.publish=1 or c.publish=2 ) and i.id='{school}' and s.id='{school}' and s.status=1 ";
  390. var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<Activity>(sqlSchool, "Activity");
  391. resultSchool.list.ForEach(z => {
  392. //处理是否是邀请制
  393. if (z.joinMode.Equals("invite"))
  394. {
  395. var inviteTeacher = z.inviteTeachers.Find(t => t.id.Equals(tmdid));
  396. if (inviteTeacher!=null)
  397. {
  398. activities.Add(z);
  399. }
  400. }
  401. else
  402. {
  403. activities.Add(z);
  404. }
  405. });
  406. }
  407. break;
  408. }
  409. case bool when $"{grant_type}".Equals("list-portal", StringComparison.OrdinalIgnoreCase):
  410. {
  411. break;
  412. }
  413. }
  414. }catch (Exception ex)
  415. {
  416. }
  417. return Ok();
  418. }
  419. }
  420. }