VoteController.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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.SDK.Models;
  13. using TEAMModelOS.SDK;
  14. using TEAMModelOS.SDK.DI;
  15. using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
  16. using TEAMModelOS.SDK.Extension;
  17. using TEAMModelOS.SDK;
  18. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  19. using TEAMModelOS.Models;
  20. using Microsoft.Extensions.Options;
  21. using TEAMModelOS.SDK.Models.Cosmos;
  22. using Microsoft.AspNetCore.Authorization;
  23. using TEAMModelOS.Filter;
  24. using StackExchange.Redis;
  25. using TEAMModelOS.SDK.Models.Cosmos.Common.Inner;
  26. using TEAMModelOS.Services.Common;
  27. using Azure.Messaging.ServiceBus;
  28. using Microsoft.Extensions.Configuration;
  29. namespace TEAMModelOS.Controllers.Learn
  30. {
  31. /// <summary>
  32. /// 投票活动
  33. /// </summary>
  34. [ProducesResponseType(StatusCodes.Status200OK)]
  35. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  36. //[Authorize(Roles = "IES5")]
  37. [Route("common/vote")]
  38. [ApiController]
  39. public class VoteController : ControllerBase
  40. {
  41. private readonly AzureRedisFactory _azureRedis;
  42. private readonly AzureCosmosFactory _azureCosmos;
  43. private readonly SnowflakeId _snowflakeId;
  44. private readonly AzureServiceBusFactory _serviceBus;
  45. private readonly DingDing _dingDing;
  46. private readonly Option _option;
  47. private readonly AzureStorageFactory _azureStorage;
  48. public IConfiguration _configuration { get; set; }
  49. public VoteController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option,
  50. AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, IConfiguration configuration)
  51. {
  52. _azureCosmos = azureCosmos;
  53. _serviceBus = serviceBus;
  54. _snowflakeId = snowflakeId;
  55. _dingDing = dingDing;
  56. _option = option?.Value;
  57. _azureRedis = azureRedis;
  58. _azureStorage = azureStorage;
  59. _configuration = configuration;
  60. }
  61. /// <summary>
  62. /// 新增 或 修改投票活动
  63. /// </summary>
  64. /// <param name="request"></param>
  65. /// <returns></returns>
  66. [ProducesDefaultResponseType]
  67. [HttpPost("upsert")]
  68. [AuthToken(Roles = "teacher,admin")]
  69. public async Task<IActionResult> Upsert(Vote request)
  70. {
  71. try
  72. {
  73. //新增Vote
  74. var client = _azureCosmos.GetCosmosClient();
  75. request.code = request.pk + "-" + request.code;
  76. request.ttl = -1;
  77. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  78. request.createTime = now;
  79. //如果设置的时间是小于当前时间则立即发布
  80. if (request.startTime <= 0) {
  81. request.startTime = now;
  82. }
  83. if (string.IsNullOrEmpty(request.id))
  84. {
  85. request.id = Guid.NewGuid().ToString();
  86. if (request.startTime > now)
  87. {
  88. request.progress = "pending";
  89. }
  90. else {
  91. request.progress = "going";
  92. }
  93. string blobcntr = null;
  94. var messageBlob = new ServiceBusMessage();
  95. if (request.scope.Equals("school"))
  96. {
  97. blobcntr = request.school;
  98. request.size = await _azureStorage.GetBlobContainerClient(request.school).GetBlobsSize($"vote/{request.id}");
  99. messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "insert", root = $"vote/{request.id}", name = $"{request.school}" }.ToJsonString());
  100. }
  101. else
  102. {
  103. blobcntr = request.creatorId;
  104. request.size = await _azureStorage.GetBlobContainerClient(request.creatorId).GetBlobsSize($"vote/{request.id}");
  105. messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "insert", root = $"vote/{request.id}", name = $"{request.creatorId}" }.ToJsonString());
  106. }
  107. messageBlob.ApplicationProperties.Add("name", "BlobRoot");
  108. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  109. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  110. string url = $"/vote/{request.id}/record.json";
  111. request.recordUrl = url;
  112. await _azureStorage.UploadFileByContainer(blobcntr, new { options = new List<string>(), records = new List<VoteRecord>() }.ToJsonString(), "vote", $"{request.id}/record.json");
  113. request = await client.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync(request, new PartitionKey($"{request.code}"));
  114. }
  115. else
  116. {
  117. var response = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync(request.id, new PartitionKey($"{request.code}"));
  118. var messageBlob = new ServiceBusMessage();
  119. string blobcntr = null;
  120. if (request.scope.Equals("school"))
  121. {
  122. blobcntr = request.school;
  123. request.size = await _azureStorage.GetBlobContainerClient(request.school).GetBlobsSize($"vote/{request.id}");
  124. messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "update", root = $"vote/{request.id}", name = $"{request.school}" }.ToJsonString());
  125. }
  126. else
  127. {
  128. blobcntr = request.creatorId;
  129. request.size = await _azureStorage.GetBlobContainerClient(request.creatorId).GetBlobsSize($"vote/{request.id}");
  130. messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "update", root = $"vote/{request.id}", name = $"{request.creatorId}" }.ToJsonString());
  131. }
  132. messageBlob.ApplicationProperties.Add("name", "BlobRoot");
  133. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  134. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  135. if (response.Status == 200)
  136. {
  137. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  138. var info = json.ToObject<Vote>();
  139. if (info.progress.Equals("going"))
  140. {
  141. return Ok(new { v = "活动正在进行中" });
  142. }
  143. if (request.startTime > now)
  144. {
  145. request.progress = "pending";
  146. }
  147. else
  148. {
  149. request.progress = "going";
  150. }
  151. request.progress = info.progress;
  152. string url = $"/vote/{request.id}/record.json";
  153. request.recordUrl = url;
  154. request = await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(request, info.id, new PartitionKey($"{info.code}"));
  155. }
  156. else
  157. {
  158. if (request.startTime > now)
  159. {
  160. request.progress = "pending";
  161. }
  162. else
  163. {
  164. request.progress = "going";
  165. }
  166. string url = $"/vote/{request.id}/record.json";
  167. request.recordUrl = url;
  168. await _azureStorage.UploadFileByContainer(blobcntr, new { options = new List<string>(), records = new List<VoteRecord>() }.ToJsonString(), "vote", $"{request.id}/record.json");
  169. request = await client.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync(request, new PartitionKey($"{request.code}"));
  170. }
  171. }
  172. return Ok(new { vote = request });
  173. }
  174. catch (Exception e)
  175. {
  176. await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/save()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  177. return BadRequest(e.StackTrace);
  178. }
  179. }
  180. /// <summary>
  181. /// 查询投票活动,用于列表,编辑,查看
  182. /// </summary>
  183. /// <data>
  184. ///Vote-学校/教师编码 活动分区 !"code":"hbcn"/1606285227
  185. ///时间筛选范围开始时间 默认30天之前 ?"stime":1608274766154
  186. ///时间筛选范围结束时间 默认当前时间 ?"etime":1608274766666
  187. ///每页大小 ?"count":10/null/Undefined
  188. ///分页Token ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
  189. /// 当前状态 ?"progress":Undefined/null/"" 表示两种状态都要查询/ "going"/"finish" 表示查询进行中/ 或者已完成 学生端只能查询正在进行或已经结束 going 已发布|finish 已结束
  190. /// </data>
  191. /// <param name="request"></param>
  192. /// <returns></returns>
  193. [ProducesDefaultResponseType]
  194. [HttpPost("find")]
  195. [AuthToken(Roles = "teacher,admin")]
  196. public async Task<IActionResult> Find(JsonElement requert)
  197. {
  198. try
  199. {
  200. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  201. //必须有学校或者教师编码
  202. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  203. //开始时间,默认最近三十天
  204. var stimestamp = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds();
  205. if (requert.TryGetProperty("stime", out JsonElement stime)) {
  206. if (long.TryParse($"{stime}", out long data))
  207. {
  208. stimestamp = data;
  209. };
  210. };
  211. //默认当前时间
  212. var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  213. if (requert.TryGetProperty("etime", out JsonElement etime))
  214. {
  215. if (long.TryParse($"{etime}", out long data))
  216. {
  217. etimestamp = data;
  218. };
  219. };
  220. var progresssql = "";
  221. if (!requert.TryGetProperty("progress", out JsonElement progress))
  222. {
  223. if (!progress.ValueKind.Equals(JsonValueKind.Undefined) && !progress.ValueKind.Equals(JsonValueKind.Null) && progress.ValueKind.Equals(JsonValueKind.String))
  224. {
  225. progresssql = $" and c.progress='{progresssql}' ";
  226. }
  227. }
  228. string continuationToken = null;
  229. //默认不指定返回大小
  230. int? topcout=null;
  231. if (requert.TryGetProperty("count", out JsonElement jcount)) {
  232. if (int.TryParse($"{jcount}", out int data))
  233. {
  234. topcout = data;
  235. }
  236. };
  237. //是否需要进行分页查询,默认不分页
  238. bool iscontinuation = false;
  239. //如果指定了返回大小
  240. if (requert.TryGetProperty("continuationToken", out JsonElement continuation))
  241. {
  242. //指定了cancellationToken 表示需要进行分页
  243. if (!continuation.ValueKind.Equals(JsonValueKind.Null) && !continuation.ValueKind.Equals(JsonValueKind.Undefined))
  244. {
  245. continuationToken = continuation.GetString();
  246. iscontinuation = true;
  247. }
  248. };
  249. List<Vote> votes = new List<Vote>();
  250. var client = _azureCosmos.GetCosmosClient();
  251. var query = $"select c.id,c.name,c.code,c.startTime,c.endTime,c.progress ,c.scope,c.school from c where c.createTime >= {stimestamp} and c.createTime <= {etimestamp} {progresssql } and c.ttl=-1 ";
  252. if (string.IsNullOrEmpty(school))
  253. {
  254. query = $"{query} and c.scope='private' ";
  255. }
  256. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<Vote>(queryText: query,
  257. requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Vote-{code}") }))
  258. {
  259. if (!string.IsNullOrEmpty(school))
  260. {
  261. //只能查出相关学校的
  262. if (!item.scope.Equals("private") && !string.IsNullOrEmpty(item.school) && item.school.Equals(school))
  263. {
  264. votes.Add(item);
  265. }
  266. //和自己私人发布的
  267. if (item.scope.Equals("private"))
  268. {
  269. votes.Add(item);
  270. }
  271. }
  272. else
  273. {
  274. votes.Add(item);
  275. }
  276. }
  277. return Ok(new { votes, continuationToken });
  278. }
  279. catch (Exception ex)
  280. {
  281. await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find()\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  282. return BadRequest(ex.StackTrace);
  283. }
  284. }
  285. ///<summary>
  286. /// 查询投票活动,用于创建者列表,编辑,查看,投票人员查看
  287. /// </summary>
  288. /// <data>
  289. /// ! "id":"3c075347-75ef-4bcb-ae03-68678d02d5ef",
  290. /// ! "code":"Vote-hbcn"/"code":"Vote-1606285227"
  291. /// </data>
  292. /// <param name="request"></param>
  293. /// <returns></returns>
  294. [ProducesDefaultResponseType]
  295. [HttpPost("find-id")]
  296. [AuthToken(Roles = "teacher,admin,student")]
  297. public async Task<IActionResult> FindById(JsonElement requert)
  298. {
  299. Vote vote = null;
  300. //活动id
  301. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  302. //活动分区
  303. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  304. try
  305. {
  306. var client = _azureCosmos.GetCosmosClient();
  307. vote = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Vote>(id.GetString(), new PartitionKey($"{code}"));
  308. if (vote != null)
  309. {
  310. return Ok(new { vote, status = 200 });
  311. }
  312. else
  313. {
  314. return Ok(new { vote, status = 404 });
  315. }
  316. }
  317. catch (Exception ex)
  318. {
  319. await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find-id()\n{ex.Message}\n{id}\n{code}", GroupNames.醍摩豆服務運維群組);
  320. return Ok(new { vote,status=404 });
  321. }
  322. }
  323. /// <summary>
  324. /// 删除投票活动 TODO 使用ttl删除,并处理相关事务逻辑
  325. /// </summary>
  326. /// <param name="request"></param>
  327. /// <returns></returns>
  328. [ProducesDefaultResponseType]
  329. [HttpPost("delete")]
  330. [AuthToken(Roles = "admin,teacher")]
  331. public async Task<IActionResult> Delete(JsonElement request)
  332. {
  333. try
  334. {
  335. var (userid, _, _,school) = HttpContext.GetAuthTokenInfo();
  336. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  337. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  338. var client = _azureCosmos.GetCosmosClient();
  339. Vote vote =await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Vote>(id.GetString(), new PartitionKey($"{code}") );
  340. bool flag = false;
  341. //必须是本人或者这个学校的管理者才能删除
  342. if (vote.creatorId == userid)
  343. {
  344. flag = true;
  345. }
  346. else {
  347. if (vote.scope == "school"&& vote.school.Equals(school)) {
  348. flag = true;
  349. }
  350. }
  351. if (flag)
  352. {
  353. //使用ttl删除,并处理相关事务逻辑
  354. vote.ttl = 1;
  355. vote.status = 404;
  356. vote = await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(vote,vote.id, new PartitionKey($"{vote.code}"));
  357. await _dingDing.SendBotMsg($"{_option.Location}-投票活动【{vote.name}-{vote.id}-ttl={vote.ttl}】正在操作", GroupNames.成都开发測試群組);
  358. _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Record:{vote.id}");
  359. _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Count:{vote.id}");
  360. await _dingDing.SendBotMsg($"{_option.Location}-投票活动【{vote.name}-{vote.id}】被删除", GroupNames.成都开发測試群組);
  361. //删除blob 相关资料
  362. await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, $"{code}".Replace("Vote-",""), new List<string> { $"vote/{vote.id}" });
  363. //通知删除信息
  364. var messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "delete", root = $"vote/{vote.id}", name = $"{code}" }.ToJsonString());
  365. messageBlob.ApplicationProperties.Add("name", "BlobRoot");
  366. var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  367. await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
  368. return Ok(new { flag });
  369. }
  370. else {
  371. return Ok(new { flag });
  372. }
  373. }
  374. catch (Exception e)
  375. {
  376. return BadRequest(e.StackTrace);
  377. }
  378. }
  379. /// <summary>
  380. /// 投票记录 当活动没结算且没有BlobUrl时则调用此接口
  381. /// </summary>
  382. /// <redis>
  383. /// 投票活动选项计数器 使用SortedSet(有序集合)ZSET 数据集合 使用命令 ZINCRBY key:"Vote:Count:AAA",value:"A",score:1
  384. /// 投票活动 投票记录 使用Hash(哈希表)使用命令 key:"Vote:Record:AAA",feild:15283771540-20210105,value:"{"opt":["A","C","A"],"time":1608274766154}"
  385. /// </redis>
  386. /// <param name="request">
  387. /// !"id":"aaaa"
  388. /// !"code":"Vote-hbcn"/"code":"Vote-1606285227"
  389. /// </param>
  390. /// <returns>
  391. /// </returns>
  392. [ProducesDefaultResponseType]
  393. [HttpPost("record")]
  394. [AuthToken(Roles = "teacher,admin,student")]
  395. public async Task<IActionResult> Record(JsonElement request)
  396. {
  397. if (!request.TryGetProperty("id", out JsonElement id))
  398. {
  399. return BadRequest();
  400. }
  401. //活动分区
  402. if (!request.TryGetProperty("code", out JsonElement code))
  403. {
  404. return BadRequest();
  405. }
  406. //获取投票活动的所有投票记录
  407. var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Vote:Record:{id}");
  408. //获取投票活动的选项及投票数
  409. var counts = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Vote:Count:{id}");
  410. List<dynamic> options = new List<dynamic>();
  411. if (counts != null && counts.Length > 0)
  412. {
  413. foreach (var count in counts)
  414. {
  415. options.Add(new { code = count.Element.ToString(), count = (int)count.Score });
  416. }
  417. }
  418. List<JsonElement> res = new List<JsonElement>();
  419. foreach (var rcd in records)
  420. {
  421. var value = rcd.Value.ToString().ToObject<JsonElement>();
  422. res.Add(value);
  423. }
  424. return Ok(new { options, records= res});
  425. }
  426. /// <summary>
  427. /// 个人已投票记录查询
  428. /// </summary>
  429. /// <param name="request"></param>
  430. /// <returns></returns>
  431. [ProducesDefaultResponseType]
  432. [HttpPost("decided")]
  433. [AuthToken(Roles = "teacher,student")]
  434. public async Task<IActionResult> Decided(JsonElement request)
  435. {
  436. var (userid, _, _, _) = HttpContext.GetAuthTokenInfo();
  437. if (!request.TryGetProperty("id", out JsonElement id))
  438. {
  439. return BadRequest();
  440. }
  441. //活动分区
  442. if (!request.TryGetProperty("code", out JsonElement code))
  443. {
  444. return BadRequest();
  445. }
  446. //获取投票活动的所有投票记录
  447. var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Vote:Record:{id}:{userid}");
  448. List<JsonElement> res = new List<JsonElement>();
  449. foreach (var rcd in records)
  450. {
  451. var value = rcd.Value.ToString().ToObject<JsonElement>();
  452. res.Add(value);
  453. }
  454. return Ok(new { records= res });
  455. }
  456. /// <summary>
  457. /// 投票
  458. /// </summary>
  459. /// <redis>
  460. /// 投票活动选项计数器 使用SortedSet(有序集合)ZSET 数据集合 使用命令 ZINCRBY key:"Vote:Count:AAA",value:"A",score:1
  461. /// 投票活动 投票记录 使用Hash(哈希表)使用命令 key:"Vote:Record:AAA",feild:15283771540-20210105,value:"{"opt":["A","C","A"],"time":1608274766154}"
  462. /// </redis>
  463. /// <param name="request">
  464. /// !"id":"aaaa"
  465. /// !"code":"Vote-hbcn"/"code":"Vote-1606285227"
  466. /// !"option":{"A":5,"B":6}/{"1":5,"2":8}
  467. /// </param>
  468. /// <returns>
  469. /// msgid=0投票失败,1投票成功,2不在时间范围内,3不在发布范围内,4投票周期内重复投票,5周期内的可投票数不足
  470. ///
  471. /// </returns>
  472. [ProducesDefaultResponseType]
  473. [HttpPost("decide")]
  474. [AuthToken(Roles = "teacher,student")]
  475. public async Task<IActionResult> Decide(JsonElement request)
  476. {
  477. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  478. (int msgid,int taskStatus) = await ActivityStudentService.Decide(request, _azureCosmos, _azureRedis ,_azureStorage, userid, school);
  479. return Ok(new { msgid, taskStatus });
  480. }
  481. /// <summary>
  482. /// 投票
  483. /// </summary>
  484. /// <redis>
  485. /// 投票活动选项计数器 使用SortedSet(有序集合)ZSET 数据集合 使用命令 ZINCRBY key:"Vote:Count:AAA",value:"A",score:1
  486. /// 投票活动 投票记录 使用Hash(哈希表)使用命令 key:"Vote:Record:AAA",feild:15283771540-20210105,value:"{"opt":["A","C","A"],"time":1608274766154}"
  487. /// </redis>
  488. /// <param name="request">
  489. /// !"id":"aaaa"
  490. /// !"code":"Vote-hbcn"/"code":"Vote-1606285227"
  491. /// !"option":{"A":5,"B":6}/{"1":5,"2":8}
  492. /// !"userid":"15283771540"
  493. /// </param>
  494. /// <returns>
  495. /// msgid=0投票失败,1投票成功,2不在时间范围内,3不在发布范围内,4投票周期内重复投票,5周期内的可投票数不足,6未设置投票项
  496. /// </returns>
  497. [ProducesDefaultResponseType]
  498. [HttpPost("decide-mock")]
  499. public async Task<IActionResult> DecideMock(JsonElement request)
  500. {
  501. //var (userid, _, _, _) = HttpContext.GetAuthTokenInfo();
  502. //活动id
  503. if (request.TryGetProperty("userid", out JsonElement userid)&& request.TryGetProperty("school", out JsonElement _school))
  504. {
  505. (int msgid, int taskStatus) = await ActivityStudentService.Decide(request, _azureCosmos, _azureRedis, _azureStorage, $"{userid}",$"{_school}");
  506. return Ok(new { msgid ,taskStatus });
  507. }
  508. else { return Ok(new { msgid = 0 }); }
  509. }
  510. }
  511. }