VoteController.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IdentityModel.Tokens.Jwt;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.Models.Dto;
  12. using TEAMModelOS.Models.SchoolInfo;
  13. using TEAMModelOS.Models.StudentInfo;
  14. using TEAMModelOS.SDK;
  15. using TEAMModelOS.SDK.Context.Constant.Common;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
  18. using TEAMModelOS.SDK.Extension;
  19. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  20. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  21. namespace TEAMModelOS.Controllers.Learn
  22. {
  23. /// <summary>
  24. /// 投票活动
  25. /// </summary>
  26. [ProducesResponseType(StatusCodes.Status200OK)]
  27. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  28. //[Authorize(Roles = "IES5")]
  29. [Route("school/vote")]
  30. [ApiController]
  31. public class VoteController : ControllerBase
  32. {
  33. private readonly SnowflakeId _snowflakeId;
  34. private readonly AzureCosmosFactory _azureCosmos;
  35. private readonly AzureServiceBusFactory _serviceBus;
  36. public VoteController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId)
  37. {
  38. _snowflakeId = snowflakeId;
  39. _azureCosmos = azureCosmos;
  40. _serviceBus = serviceBus;
  41. }
  42. /// <summary>
  43. /// 新增 或 修改投票活动
  44. /// </summary>
  45. /// <param name="request"></param>
  46. /// <returns></returns>
  47. [ProducesDefaultResponseType]
  48. [HttpPost("upsert")]
  49. public async Task<IActionResult> Upsert(VoteDto request)
  50. {
  51. /*ResponseBuilder builder = ResponseBuilder.custom();
  52. //新增
  53. if (string.IsNullOrEmpty(request.vote.id))
  54. {
  55. request.vote.id = _snowflakeId.NextId()+"";
  56. request.vote.status = 100;
  57. request.vote.code = typeof(Vote).Name + "-" + request.vote.code;
  58. }
  59. if (request.vote.publishModel.Equals("0"))
  60. {
  61. request.vote.startTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
  62. request.vote.status = 200;
  63. } else if (request.vote.publishModel.Equals("1")) {
  64. string msgId = _snowflakeId.NextId() + "";
  65. long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime, 200, msgId);
  66. request.vote.sequenceNumber = SequenceNumber;
  67. }*/
  68. //新增ote
  69. //string code = request.vote.code;
  70. var client = _azureCosmos.GetCosmosClient();
  71. Vote vote = new Vote();
  72. request.vote.ttl = -1;
  73. request.vote.pk = typeof(Vote).Name;
  74. request.vote.school = request.vote.code;
  75. request.vote.code = typeof(Vote).Name + "-" + request.vote.code;
  76. request.vote.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  77. /*if (request.vote.publishModel.Equals("0"))
  78. {
  79. //request.vote.startTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
  80. request.vote.progress = "going";
  81. }
  82. else if (request.vote.publishModel.Equals("1"))
  83. {
  84. string msgId = _snowflakeId.NextId() + "";
  85. long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime, "going", msgId);
  86. request.vote.sequenceNumber = SequenceNumber;
  87. }*/
  88. if (string.IsNullOrEmpty(request.vote.id))
  89. {
  90. request.vote.id = Guid.NewGuid().ToString();
  91. //request.survey.status = 100;
  92. request.vote.progress = "pending";
  93. long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime);
  94. request.vote.sequenceNumber = SequenceNumber;
  95. vote = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request.vote, new PartitionKey($"{request.vote.code}"));
  96. /*if (request.vote.scope.Equals("school"))
  97. {
  98. vote = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request.vote, new PartitionKey($"Vote-{code}"));
  99. }
  100. else
  101. {
  102. vote = await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(request.vote, new PartitionKey($"Vote-{code}"));
  103. }*/
  104. }
  105. else
  106. {
  107. Vote info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(request.vote.id, new PartitionKey($"{request.vote.code}"));
  108. if (info.progress.Equals("going"))
  109. {
  110. return Ok(new { v = "活动正在进行中" });
  111. }
  112. //request.vote.code = info.code;
  113. request.vote.progress = info.progress;
  114. await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName,info.sequenceNumber);
  115. long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime);
  116. request.vote.sequenceNumber = SequenceNumber;
  117. vote = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request.vote, info.id, new PartitionKey($"{info.code}"));
  118. /*if (request.vote.scope.Equals("school"))
  119. {
  120. vote = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(request.vote, request.vote.id, new PartitionKey($"{request.vote.code}"));
  121. }
  122. else
  123. {
  124. vote = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(request.vote, request.vote.id, new PartitionKey($"{request.vote.code}"));
  125. }*/
  126. }
  127. //Vote homeWork = await _azureCosmos.SaveOrUpdate<Vote>(request.vote);
  128. //设定结束时间
  129. //_timerWorkService.TimerWork<Vote>(request.vote.endTime, 300, new Dictionary<string, object> { { "id", request.vote.id } });
  130. //设定结束时间
  131. await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.endTime);
  132. //清除作业
  133. if (!request.reset)
  134. {
  135. //根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
  136. List<VoteRecord> voteRecords = await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> { { "id", request.vote.id } });
  137. if (voteRecords.IsNotEmpty())
  138. {
  139. await _azureCosmos.DeleteAll(voteRecords);
  140. }
  141. //List<Target> targets = request.@params.vote.target;
  142. //List<VoteRecord> votekStudents = new List<VoteRecord>();
  143. //foreach (Target target in targets)
  144. //{
  145. // //查询之前是否有 关联关系表 HomeWorkStudent 有则删除
  146. // List<ClassStudent> classroom = await _cosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", target.classroomCode } });
  147. // if (classroom.IsNotEmpty() && classroom[0].code!=null)
  148. // {
  149. // foreach (ClassStudent student in classroom)
  150. // {
  151. // VoteRecord voteStudent = new VoteRecord();
  152. // voteStudent.id = request.@params.vote.id;
  153. // voteStudent.code = student.code;
  154. // voteStudent.classroom.code = target.classroomCode;
  155. // voteStudent.classroom.name = target.classroomName;
  156. // votekStudents.Add(voteStudent);
  157. // }
  158. // }
  159. //}
  160. //if (votekStudents.IsNotEmpty())
  161. //{
  162. // foreach (VoteRecord voteRecord in votekStudents)
  163. // {
  164. // List<Student> student = await _cosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId", voteRecord.code } });
  165. // if (student.IsNotEmpty())
  166. // {
  167. // voteRecord.name = student[0].name;
  168. // voteRecord.code = student[0].studentId;
  169. // }
  170. // }
  171. // await _cosmos.SaveOrUpdateAll(votekStudents);
  172. //}
  173. }
  174. //return builder.Data(homeWork).build();
  175. return Ok(new { vote });
  176. }
  177. /// <summary>
  178. /// 查询投票活动
  179. /// </summary>
  180. /// <param name="request"></param>
  181. /// <returns></returns>
  182. [ProducesDefaultResponseType]
  183. [HttpPost("find")]
  184. public async Task<IActionResult> Find(JsonElement requert)
  185. {
  186. var client = _azureCosmos.GetCosmosClient();
  187. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  188. if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  189. StringBuilder sql = new StringBuilder();
  190. sql.Append("select c.id,c.code,c.name,c.targetClassIds,c.options,c.description,c.status,c.startTime,c.selectMax,c.endTime,c.secret,c.progress from c ");
  191. /*if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  192. if (!requert.TryGetProperty("@CURRPAGE", out JsonElement page)) return BadRequest();
  193. if (!requert.TryGetProperty("@PAGESIZE", out JsonElement size)) return BadRequest();
  194. if (!requert.TryGetProperty("@DESC", out JsonElement desc)) return BadRequest();*/
  195. Dictionary<string, object> dict = new Dictionary<string, object>();
  196. var emobj = requert.EnumerateObject();
  197. while (emobj.MoveNext())
  198. {
  199. dict[emobj.Current.Name] = emobj.Current.Value;
  200. }
  201. //处理code
  202. if (dict.TryGetValue("code", out object _))
  203. {
  204. dict.Remove("code");
  205. }
  206. AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
  207. List<object> votes = new List<object>();
  208. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
  209. {
  210. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  211. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  212. {
  213. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  214. {
  215. votes.Add(obj.ToObject<object>());
  216. }
  217. }
  218. }
  219. /*if (scope.ToString().Equals("school"))
  220. {
  221. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
  222. {
  223. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  224. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  225. {
  226. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  227. {
  228. votes.Add(obj.ToObject<object>());
  229. }
  230. }
  231. }
  232. }
  233. else
  234. {
  235. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
  236. {
  237. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  238. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  239. {
  240. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  241. {
  242. votes.Add(obj.ToObject<object>());
  243. }
  244. }
  245. }
  246. }*/
  247. return Ok(new { votes, votes.Count });
  248. /*ResponseBuilder builder = ResponseBuilder.custom();
  249. List<Vote> data = new List<Vote>();
  250. if (StringHelper.getKeyCount(request) > 0)
  251. {
  252. data = await _azureCosmos.FindByDict<Vote>(request);
  253. }
  254. else
  255. {
  256. return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常!").build();
  257. }
  258. return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
  259. }
  260. /// <summary>
  261. /// 删除投票活动
  262. /// </summary>
  263. /// <param name="request"></param>
  264. /// <returns></returns>
  265. [ProducesDefaultResponseType]
  266. [HttpPost("delete")]
  267. public async Task<IActionResult> Delete(JsonElement request)
  268. {
  269. try
  270. {
  271. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  272. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  273. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  274. var client = _azureCosmos.GetCosmosClient();
  275. var response = await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
  276. return Ok(new { code = response.Status });
  277. /*if (scope.ToString().Equals("school"))
  278. {
  279. var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
  280. return Ok(new { code = response.Status });
  281. }
  282. else
  283. {
  284. var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
  285. return Ok(new { code = response.Status });
  286. }*/
  287. }
  288. catch (Exception e)
  289. {
  290. return BadRequest();
  291. }
  292. //ResponseBuilder builder = ResponseBuilder.custom();
  293. /* List<IdPk> idPks = await _azureCosmos.DeleteAll<Vote>(request);
  294. if (idPks.IsNotEmpty())
  295. {
  296. foreach (IdPk idPk in idPks)
  297. {
  298. List<VoteRecord> votes = await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> { { "id", idPk.id } });
  299. await _azureCosmos.DeleteAll(votes);
  300. }
  301. //builder.Data(idPks);
  302. }
  303. else
  304. {
  305. return Ok("删除失败!");
  306. //return builder.Error(ResponseCode.FAILED, "删除失败!").build();
  307. }
  308. return Ok(idPks);*/
  309. //return builder.build();
  310. }
  311. /// <summary>
  312. /// 撤消投票
  313. /// </summary>
  314. /// <param name="request"></param>
  315. /// <returns></returns>
  316. [ProducesDefaultResponseType]
  317. [HttpPost("cancel")]
  318. public async Task<IActionResult> Cancel(JsonElement request)
  319. {
  320. request.TryGetProperty("id", out JsonElement voteId);
  321. //ResponseBuilder builder = ResponseBuilder.custom();
  322. List<Vote> votes = await _azureCosmos.FindByDict<Vote>(new Dictionary<string, object> { { "id", voteId } });
  323. foreach (Vote vote in votes)
  324. {
  325. vote.status = 100;
  326. vote.progress = "pending";
  327. }
  328. List<Vote> vote1 = await _azureCosmos.UpdateAll<Vote>(votes);
  329. //查询之前是否有 关联关系表 HomeWorkStudent 有则删除
  330. List<VoteRecord> voteStudents = await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> { { "id", voteId } });
  331. if (voteStudents.IsNotEmpty())
  332. {
  333. await _azureCosmos.DeleteAll(voteStudents);
  334. }
  335. //return builder.Data(vote1).build();
  336. return Ok(vote1);
  337. }
  338. /// <summary>
  339. /// 查询 投票 学生关联
  340. /// </summary>
  341. /// <param name="request"></param>
  342. /// <returns></returns>
  343. [ProducesDefaultResponseType]
  344. [HttpPost("find-record")]
  345. public async Task<IActionResult> FindRecord(JsonElement request)
  346. {
  347. ResponseBuilder builder = ResponseBuilder.custom();
  348. List<VoteRecord> data = new List<VoteRecord>();
  349. List<Options> options = new List<Options>();
  350. if (StringHelper.getKeyCount(request) > 0)
  351. {
  352. data = await _azureCosmos.FindByDict<VoteRecord>(request);
  353. if (data.IsNotEmpty()) {
  354. List< Vote > votes = await _azureCosmos.FindByDict<Vote>(new Dictionary<string, object> { { "id", data[0].id } });
  355. List<OptionsVote> options2 = votes[0].options;
  356. foreach (IGrouping<string, VoteRecord> voteStudents in data.GroupBy(x => x.option))
  357. {
  358. Options options1 = new Options();
  359. options1.optionKey = voteStudents.Key;
  360. options2.ForEach(x => { if (x.code == voteStudents.Key) options1.optionValue = x.value; });
  361. if(options1.optionValue == null) options1.optionValue = "Null";
  362. foreach (VoteRecord voteStudent in voteStudents)
  363. {
  364. options1.students.Add(voteStudent);
  365. }
  366. options.Add(options1);
  367. }
  368. }
  369. }
  370. else
  371. {
  372. //return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常!").build();
  373. return Ok("参数异常!");
  374. }
  375. //return builder.Data(options).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();
  376. return Ok(new { options, data.Count });
  377. }
  378. /// <summary>
  379. /// 学生投票
  380. /// </summary>
  381. /// <param name="request"></param>
  382. /// <returns></returns>
  383. [ProducesDefaultResponseType]
  384. [HttpPost("upsert-record")]
  385. public async Task<IActionResult> UpsertRecord(List<VoteRecord> request)
  386. {
  387. ResponseBuilder builder = ResponseBuilder.custom();
  388. await _azureCosmos.SaveOrUpdateAll<VoteRecord>(request);
  389. return Ok(request);
  390. //return builder.Data(request).build();
  391. }
  392. public class Options {
  393. public Options() {
  394. students = new List<VoteRecord>();
  395. }
  396. /// <summary>
  397. /// 选项Key
  398. /// </summary>
  399. public string optionKey { get; set; }
  400. /// <summary>
  401. /// 选项value
  402. /// </summary>
  403. public string optionValue { get; set; }
  404. /// <summary>
  405. /// 选项人
  406. /// </summary>
  407. public List<VoteRecord> students { get; set; }
  408. }
  409. }
  410. }