NoticeController.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Dynamic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Text;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. using Azure;
  12. using Microsoft.Azure.Cosmos;
  13. using Azure.Storage.Sas;
  14. using TEAMModelOS.SDK;
  15. using Microsoft.AspNetCore.Authorization;
  16. using Microsoft.AspNetCore.Cryptography.KeyDerivation;
  17. using Microsoft.AspNetCore.Mvc;
  18. using Microsoft.Extensions.Options;
  19. using TEAMModelOS.Filter;
  20. using TEAMModelOS.Models;
  21. using TEAMModelOS.SDK.DI;
  22. using TEAMModelOS.SDK.Extension;
  23. using TEAMModelOS.SDK.Models;
  24. using TEAMModelOS.SDK.Models.Cosmos;
  25. using TEAMModelOS.SDK.Models.Cosmos.Common;
  26. namespace TEAMModelOS.Controllers
  27. {
  28. [Route("school/notice")]
  29. [ApiController]
  30. public class NoticeController :ControllerBase
  31. {
  32. private readonly AzureCosmosFactory _azureCosmos;
  33. private readonly AzureStorageFactory _azureStorage;
  34. private readonly DingDing _dingDing;
  35. private readonly Option _option;
  36. public NoticeController(
  37. AzureCosmosFactory azureCosmos,
  38. AzureStorageFactory azureStorage,
  39. DingDing dingDing,
  40. IOptionsSnapshot<Option> option
  41. )
  42. {
  43. _azureCosmos = azureCosmos;
  44. _azureStorage = azureStorage;
  45. _dingDing = dingDing;
  46. _option = option?.Value;
  47. }
  48. /// <summary>
  49. /// 新增 或 修改
  50. /// </summary>
  51. /// <param name="request"></param>
  52. /// <returns></returns>
  53. [ProducesDefaultResponseType]
  54. [HttpPost("upsert")]
  55. [Authorize(Roles = "IES")]
  56. [AuthToken(Roles = "teacher,admin")]
  57. public async Task<IActionResult> Upsert(Notice request)
  58. {
  59. try
  60. {
  61. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  62. //新增
  63. var client = _azureCosmos.GetCosmosClient();
  64. if (request.scope.Equals("school") && (!string.IsNullOrEmpty(request.school)|| !string.IsNullOrEmpty(school)))
  65. {
  66. request.school = string.IsNullOrWhiteSpace(request.school) ? school : request.school;
  67. request.code = $"Notice-{request.school}";
  68. }
  69. else if (request.scope.Equals("private") && (!string.IsNullOrEmpty(request.creatorId)|| !string.IsNullOrEmpty(userid)))
  70. {
  71. request.creatorId = string.IsNullOrWhiteSpace(request.creatorId) ? userid : request.creatorId;
  72. request.code = $"Notice";
  73. }
  74. // request.code =$"Notice-{request.code}";
  75. request.pk = "Notice";
  76. request.ttl = -1;
  77. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  78. if (request.autoDelete) {
  79. int time = (int)(request.endTime - now) / 1000;
  80. if (time > 0) {
  81. request.ttl = time;
  82. }
  83. }
  84. request.createTime = now;
  85. request.creatorId = userid;
  86. //如果设置的时间是小于当前时间则立即发布
  87. if (request.startTime <= 0)
  88. {
  89. request.startTime = now;
  90. }
  91. if (request.publish == 1) {
  92. if (request.endTime <= request.startTime)
  93. {
  94. return BadRequest("结束时间必须大于开始时间");
  95. }
  96. }
  97. if (string.IsNullOrEmpty(request.id))
  98. {
  99. request.id = Guid.NewGuid().ToString();
  100. request = await client.GetContainer(Constant.TEAMModelOS,Constant.Common).CreateItemAsync(request, new PartitionKey($"{request.code}"));
  101. }
  102. else
  103. {
  104. var response = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(request.id, new PartitionKey($"{request.code}"));
  105. if (response.StatusCode==System.Net.HttpStatusCode.OK)
  106. {
  107. request = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).ReplaceItemAsync(request, request.id, new PartitionKey($"{request.code}"));
  108. }
  109. else
  110. {
  111. request = await client.GetContainer(Constant.TEAMModelOS, Constant.Common).CreateItemAsync(request, new PartitionKey($"{request.code}"));
  112. }
  113. }
  114. return Ok(new { vote = request });
  115. }
  116. catch (Exception e)
  117. {
  118. await _dingDing.SendBotMsg($"OS,{_option.Location},school/Notice/upsert()\n{e.Message}\n{e.StackTrace}\n{e .StackTrace}", GroupNames.醍摩豆服務運維群組);
  119. return BadRequest(e.StackTrace);
  120. }
  121. }
  122. /// <summary>
  123. ///
  124. /// </summary>
  125. /// <param name="request"></param>
  126. /// <returns></returns>
  127. [ProducesDefaultResponseType]
  128. [HttpPost("find")]
  129. [Authorize(Roles = "IES")]
  130. [AuthToken(Roles = "teacher,admin,student")]
  131. public async Task<IActionResult> Find(JsonElement request)
  132. {
  133. try
  134. {
  135. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  136. //必须有学校或者教师编码
  137. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  138. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  139. request.TryGetProperty("admin", out JsonElement admin);
  140. string stimestampsql = "";
  141. string etimestampsql = "";
  142. if (!$"{admin}".Equals("1"))
  143. {
  144. var stimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  145. if (request.TryGetProperty("stime", out JsonElement stime))
  146. {
  147. if (long.TryParse($"{stime}", out long data))
  148. {
  149. stimestamp = data;
  150. }
  151. }
  152. stimestampsql = $" and c.startTime <= {stimestamp} ";
  153. //默认当前时间
  154. var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  155. if (request.TryGetProperty("etime", out JsonElement etime))
  156. {
  157. if (long.TryParse($"{etime}", out long data))
  158. {
  159. etimestamp = data;
  160. }
  161. }
  162. etimestampsql = $" and c.endTime >= {etimestamp} ";
  163. }
  164. var publishsql = "";
  165. if (request.TryGetProperty("publish", out JsonElement publish))
  166. {
  167. if (!publish.ValueKind.Equals(JsonValueKind.Undefined) && !publish.ValueKind.Equals(JsonValueKind.Null) && publish.ValueKind.Equals(JsonValueKind.Number))
  168. {
  169. publishsql = $" and c.publish={publish} ";
  170. }
  171. }
  172. var creatorIdSql = "";
  173. if (request.TryGetProperty("creatorId", out JsonElement creatorId))
  174. {
  175. if (!publish.ValueKind.Equals(JsonValueKind.Undefined) && !publish.ValueKind.Equals(JsonValueKind.Null) && publish.ValueKind.Equals(JsonValueKind.String))
  176. {
  177. publishsql = $" and c.creatorId='{creatorId}' ";
  178. }
  179. }
  180. var typesql = "";
  181. if (request.TryGetProperty("type", out JsonElement type))
  182. {
  183. if (!type.ValueKind.Equals(JsonValueKind.Undefined) && !type.ValueKind.Equals(JsonValueKind.Null) && type.ValueKind.Equals(JsonValueKind.String))
  184. {
  185. typesql = $" and c.type='{type}' ";
  186. }
  187. }
  188. string joinSqlClasses = "";
  189. string andSqlClasses = "";
  190. if (request.TryGetProperty("classes", out JsonElement _classes))
  191. {
  192. if (_classes.ValueKind is JsonValueKind.Array)
  193. {
  194. List<string> subjects = _classes.ToObject<List<string>>();
  195. if (subjects.IsNotEmpty())
  196. {
  197. joinSqlClasses = " join A2 in c.classes ";
  198. List<string> sqlList = new List<string>();
  199. subjects.ForEach(x => { sqlList.Add($" '{x}' "); });
  200. string sql = string.Join(" , ", sqlList);
  201. andSqlClasses = $" and A2 in ({sql}) ";
  202. }
  203. }
  204. }
  205. List<Notice> notices = new List<Notice>();
  206. var client = _azureCosmos.GetCosmosClient();
  207. var query = $"select distinct value(c) from c {joinSqlClasses} where 1=1 {etimestampsql} {stimestampsql} {publishsql} {typesql} {andSqlClasses} {creatorIdSql} ";
  208. if ($"{scope}".Equals("school"))
  209. {
  210. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIteratorSql<Notice>(queryText: query,
  211. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Notice-{code}") }))
  212. {
  213. notices.Add(item);
  214. }
  215. }
  216. else {
  217. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIteratorSql<Notice>(queryText: query,
  218. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Notice") }))
  219. {
  220. notices.Add(item);
  221. }
  222. }
  223. return Ok(new { notices });
  224. }
  225. catch (Exception ex)
  226. {
  227. await _dingDing.SendBotMsg($"OS,{_option.Location},school/Notice/find()\n", GroupNames.醍摩豆服務運維群組);
  228. return BadRequest(ex.StackTrace);
  229. }
  230. }
  231. /// <summary>
  232. ///
  233. /// </summary>
  234. /// <param name="request"></param>
  235. /// <returns></returns>
  236. [ProducesDefaultResponseType]
  237. [HttpPost("find-by-student")]
  238. [Authorize(Roles = "IES")]
  239. [AuthToken(Roles = "teacher,admin,student")]
  240. public async Task<IActionResult> FindByStudent(JsonElement request)
  241. {
  242. try
  243. {
  244. object scope = null;
  245. HttpContext?.Items.TryGetValue("Scope", out scope);
  246. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  247. //必须有学校或者教师编码
  248. // if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  249. //string stimestampsql = "";
  250. //string etimestampsql = "";
  251. //var stimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  252. //if (request.TryGetProperty("stime", out JsonElement stime) && stime.ValueKind.Equals(JsonValueKind.Number))
  253. //{
  254. // if (long.TryParse($"{stime}", out long data))
  255. // {
  256. // stimestamp = data;
  257. // }
  258. //}
  259. //stimestampsql = $" and c.startTime <= {stimestamp} ";
  260. ////默认当前时间
  261. //var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  262. //if (request.TryGetProperty("etime", out JsonElement etime) && stime.ValueKind.Equals(JsonValueKind.Number))
  263. //{
  264. // if (long.TryParse($"{etime}", out long data))
  265. // {
  266. // etimestamp = data;
  267. // }
  268. //}
  269. //etimestampsql = $" and c.endTime >= {etimestamp} ";
  270. var publishsql = $" and c.publish=1 ";
  271. string joinSqlClasses = "";
  272. string andSqlClasses = "";
  273. if (request.TryGetProperty("classes", out JsonElement _classes))
  274. {
  275. if (_classes.ValueKind is JsonValueKind.Array)
  276. {
  277. List<string> subjects = _classes.ToObject<List<string>>();
  278. if (subjects.IsNotEmpty())
  279. {
  280. joinSqlClasses = " join A2 in c.classes ";
  281. List<string> sqlList = new List<string>();
  282. subjects.ForEach(x => { sqlList.Add($" '{x}' "); });
  283. string sql = string.Join(" , ", sqlList);
  284. andSqlClasses = $" and A2 in ({sql}) ";
  285. }
  286. }
  287. }
  288. else {
  289. return BadRequest();
  290. }
  291. List<Notice> notices = new List<Notice>();
  292. var client = _azureCosmos.GetCosmosClient();
  293. var query = $"select distinct value(c) from c {joinSqlClasses} where 1=1 {publishsql} {andSqlClasses} ";
  294. if ($"{scope}".Equals(Constant.ScopeTmdUser))
  295. {
  296. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIteratorSql<Notice>(queryText: query,
  297. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Notice") }))
  298. {
  299. notices.Add(item);
  300. }
  301. }
  302. else {
  303. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIteratorSql<Notice>(queryText: query,
  304. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Notice") }))
  305. {
  306. notices.Add(item);
  307. }
  308. if (!string.IsNullOrWhiteSpace(school)) {
  309. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIteratorSql<Notice>(queryText: query,
  310. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Notice-{school}") }))
  311. {
  312. notices.Add(item);
  313. }
  314. }
  315. }
  316. return Ok(new { notices });
  317. }
  318. catch (Exception ex)
  319. {
  320. await _dingDing.SendBotMsg($"OS,{_option.Location},school/Notice/find()\n", GroupNames.醍摩豆服務運維群組);
  321. return BadRequest(ex.StackTrace);
  322. }
  323. }
  324. /// <summary>
  325. /// 删除
  326. /// </summary>
  327. /// <param name="request"></param>
  328. /// <returns></returns>
  329. [ProducesDefaultResponseType]
  330. [HttpPost("delete")]
  331. [AuthToken(Roles = "teacher,admin")]
  332. #if !DEBUG
  333. [Authorize(Roles = "IES")]
  334. #endif
  335. public async Task<IActionResult> Delete(JsonElement request) {
  336. try
  337. {
  338. // var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  339. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  340. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  341. var client = _azureCosmos.GetCosmosClient();
  342. await client.GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(id.GetString(), new PartitionKey($"{code}"));
  343. return Ok(new { status = 200 });
  344. }
  345. catch (Exception e)
  346. {
  347. return BadRequest(e.StackTrace);
  348. }
  349. }
  350. }
  351. }