123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- using Azure.Cosmos;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Models;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.Filter;
- using HTEXLib.COMM.Helpers;
- using Microsoft.AspNetCore.Authorization;
- namespace TEAMModelOS.Controllers
- {
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
-
- [Route("school/debate")]
- [ApiController]
- public class DebateController: ControllerBase
- {
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- public DebateController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
- {
- _azureCosmos = azureCosmos;
- _dingDing = dingDing;
- _option = option?.Value; ;
- }
- /// <summary>
- /// 查询话题
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- //[AuthToken(Roles = "teacher")]
- [HttpPost("find-id")]
- [AuthToken(Roles = "teacher,admin,student")]
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> FindId(JsonElement request)
- {
- try
- {
- if (!request.TryGetProperty("debateId", out JsonElement _debateId)) { return BadRequest(); }
- if (!request.TryGetProperty("debateCode", out JsonElement _debateCode)) { return BadRequest(); }
- if (!request.TryGetProperty("scope", out JsonElement _scope)) { return BadRequest(); }
- string debateCode = $"{_scope}".Equals("school") ? $"{_debateCode}".StartsWith("Debate-") ? $"{_debateCode}" : $"Debate-{_debateCode}" : "Debate";
- List<dynamic> debates = new List<dynamic>();
- Debate debate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_debateId}", new PartitionKey($"{debateCode}"));
- return Ok(new { debate = debate , replyCount = debate.replies!=null ?debate.replies.Count:0});
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"OS,{_option.Location},DebateController,school/debate/FindId\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- /// <summary>
- /// 删除话题
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- //[AuthToken(Roles = "teacher")]
- [HttpPost("delete")]
- #if !DEBUG
- [AuthToken(Roles = "teacher,admin,student")]
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> Delete(JsonElement request)
- {
- try
- {
- if (!request.TryGetProperty("debateId", out JsonElement _debateId)) { return BadRequest(); }
- if (!request.TryGetProperty("debateCode", out JsonElement _debateCode)) { return BadRequest(); }
- if (!request.TryGetProperty("scope", out JsonElement _scope)) { return BadRequest(); }
- string debateCode =$"{_scope}".Equals("school")? $"{_debateCode}".StartsWith("Debate-") ? $"{_debateCode}" : $"Debate-{_debateCode}": "Debate";
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync($"{_debateId}", new PartitionKey($"{debateCode}"));
- return Ok(new { status=200});
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"OS,{_option.Location},DebateController,school/debate/delete\n{ex.Message}\n{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- /// <summary>
- /// 查询所有话题
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- //[AuthToken(Roles = "teacher")]
- [HttpPost("find")]
- [AuthToken(Roles = "teacher,admin,student")]
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> Find(JsonElement request) {
- try
- {
- List<dynamic> debates = new List<dynamic>();
- request.TryGetProperty("source", out JsonElement _source);
- request.TryGetProperty("tmdid", out JsonElement _tmdid);
- request.TryGetProperty("userType", out JsonElement _userType);
- request.TryGetProperty("keyWord", out JsonElement _keyWord);
- request.TryGetProperty("comid", out JsonElement _comid);
- string debateCode = "Debate";
- if (request.TryGetProperty("code", out JsonElement _code) && !string.IsNullOrWhiteSpace($"{_code}"))
- {
- debateCode= $"{_code}".StartsWith("Debate-") ? $"{_code}" : $"Debate-{_code}";
- }
-
-
- StringBuilder stringBuilder = new StringBuilder($"select c.id,c.code,c.tmdid,c.userType,c.tmdname,c.title,c.comment,c.time,c.comid,c.likeCount,c.school,c.wordCount,c.timeoutReply,c.expire,c.source,c.pk, ARRAY_LENGTH( c.replies ) as replyCount from c where c.pk='Debate' ");
- if (!string.IsNullOrEmpty($"{_source}")) {
- stringBuilder.Append($" and c.source='{_source}'");
- }
- if (!string.IsNullOrEmpty($"{_tmdid}") && !string.IsNullOrWhiteSpace($"{_userType}"))
- {
- stringBuilder.Append($" and c.tmdid='{_tmdid}' and c.userType='{_userType}'");
- }
- if (!string.IsNullOrEmpty($"{_keyWord}"))
- {
- stringBuilder.Append($" and contains(c.title,'{_keyWord}') ");
- }
- if (!string.IsNullOrEmpty($"{_comid}"))
- {
- stringBuilder.Append($" and c.comid='{_comid}'");
- }
- stringBuilder.Append("order by c.time desc ");
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School")
- .GetItemQueryIterator<dynamic>(queryText: stringBuilder.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(debateCode) }))
- {
- debates.Add(item);
- }
-
- return Ok(debates);
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"OS,{_option.Location},school/debate/find\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- /*
- {
- "opt":"add"
- "debateId": "1fcdb1d6-de51-40d5-bfa0-193c3929e50c",
- "debateCode":"Debate-hbcn",
- "reply":{
- "id":null,
- "pid":"话题的id 1fcdb1d6-de51-40d5-bfa0-193c3929e50c",
- "tmdid":"回复者的id",
- "tmdname":"回复者的昵称",
- "comment":"回复内容",
- "atTmdid":"被回复的id",
- "atTmdname":"被回复的name"
- }
- }
- {
- "opt":"del"
- "debateId": "1fcdb1d6-de51-40d5-bfa0-193c3929e50c",
- "debateCode":"Debate-hbcn",
- "reply":{
- "id":"uuid"
- }
- }
- */
- /// <summary>
- /// 回复话题
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("reply")]
- [Authorize(Roles = "IES")]
- [AuthToken(Roles = "admin,teacher,student")]
- public async Task<IActionResult> reply(JsonElement request) {
- var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
- if (!request.TryGetProperty("opt", out JsonElement _opt)) { return BadRequest(); }
- if (!request.TryGetProperty("debateId", out JsonElement _debateId)) { return BadRequest(); }
- if (!request.TryGetProperty("debateCode", out JsonElement _debateCode)) { return BadRequest(); }
- if (!request.TryGetProperty("scope", out JsonElement _scope )) { return BadRequest(); }
- DebateReply reply = null;
-
- string debateCode = $"{_debateCode}".StartsWith("Debate-") ? $"{_debateCode}" : $"Debate-{_debateCode}";
- if (_scope.Equals("private")) {
- debateCode="Debate";
- }
- if (!string.IsNullOrEmpty($"{_debateId}") && !string.IsNullOrEmpty($"{debateCode}") && !string.IsNullOrEmpty($"{_opt}"))
- {
- switch ($"{_opt}")
- {
- case "add":
- try
- {
- if (!request.TryGetProperty("reply", out JsonElement _reply)) { return BadRequest(); }
- Debate debate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_debateId}", new PartitionKey($"{debateCode}"));
- reply = _reply.ToObject<DebateReply>();
- reply.pid = string.IsNullOrEmpty(reply.pid) ? $"{_debateId}" : reply.pid;
- reply.id = string.IsNullOrEmpty(reply.id) ? Guid.NewGuid().ToString() : reply.id;
- reply.time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- debate.replies.Add(reply);
- debate.likeCount = debate.replies.SelectMany(z => z.likes).Count();
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, $"{_debateId}", new PartitionKey($"{debateCode}"));
- return Ok(new { reply , replyCount = debate.replies.Count });
- }
- catch (CosmosException ex)
- {
- return BadRequest();
- }
- case "like":
- try
- {
- Debate debate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_debateId}", new PartitionKey($"{debateCode}"));
- if (!request.TryGetProperty("likeData", out JsonElement _likeData)) { return BadRequest(); }
- LikeRcd likeRcd = _likeData.ToObject<LikeRcd>();
- if (likeRcd != null && !string.IsNullOrWhiteSpace(likeRcd.replyId))
- {
- var replyData = debate.replies.Find(x => $"{likeRcd.replyId}".Equals(x.id));
- var like = replyData.likes.FindAll(c => !string.IsNullOrWhiteSpace(c.tmdid) && c.tmdid.Equals(likeRcd.tmdid) && !string.IsNullOrWhiteSpace(c.userType) && c.userType.Equals(likeRcd.userType));
- if (like.IsEmpty())
- {
- replyData.likes.Add(likeRcd);
- }
- debate.likeCount = debate.replies.SelectMany(z => z.likes).Count();
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, $"{_debateId}", new PartitionKey($"{debateCode}"));
- return Ok(new { reply, replyCount = debate.replies.Count });
- }
- else {
- return BadRequest();
- }
- }
- catch (CosmosException ex)
- {
- return BadRequest();
- }
- case "unlike":
- try
- {
- Debate debate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_debateId}", new PartitionKey($"{debateCode}"));
- if (!request.TryGetProperty("likeData", out JsonElement _likeData)) { return BadRequest(); }
- LikeRcd likeRcd = _likeData.ToObject<LikeRcd>();
- if (likeRcd != null && !string.IsNullOrWhiteSpace(likeRcd.replyId))
- {
- var replyData = debate.replies.Find(x => $"{likeRcd.replyId}".Equals(x.id) );
- replyData.likes.RemoveAll(c => !string.IsNullOrWhiteSpace(c.tmdid) && c.tmdid.Equals(likeRcd.tmdid) && !string.IsNullOrWhiteSpace(c.userType) && c.userType.Equals(likeRcd.userType));
- debate.likeCount = debate.replies.SelectMany(z => z.likes).Count();
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, $"{_debateId}", new PartitionKey($"{debateCode}"));
- return Ok(new { reply, replyCount = debate.replies.Count });
- }
- else
- {
- return BadRequest();
- }
- }
- catch (CosmosException ex)
- {
- return BadRequest();
- }
- case "del":
- try
- {
- Debate debate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_debateId}", new PartitionKey($"{debateCode}"));
- if (!request.TryGetProperty("replyId", out JsonElement _replyId)) { return BadRequest(); }
- var findall = debate.replies.FindAll(x => $"{_replyId}" .Equals(x.id));
- if (findall.IsNotEmpty())
- {
- foreach (var find in findall)
- {
- if (find.tmdid .Equals(userid)||debate.tmdid .Equals(userid))
- {
- debate.replies.Remove(find);
- }
- else {
- //不能删除别人的
- return Ok(new { status = 2, replyCount = debate.replies.Count });
- }
- }
- debate.likeCount = debate.replies.SelectMany(z => z.likes).Count();
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, $"{_debateId}", new PartitionKey($"{debateCode}"));
- //删除成功
- return Ok(new { status = 0 , replyCount = debate.replies.Count });
- }
- else {
- return Ok(new { status = 0, replyCount = debate.replies.Count });
- }
- }
- catch (CosmosException ex)
- { //删除失败,话题不存在
- return Ok(new { status=1});
- }
- default:
- return BadRequest("opt only is del or add");
- }
- }
- else { return BadRequest(); }
- }
- /*
- {
- "comid":"uuid",
- "source":"normal",
- "debate":
- {
- "id":"uuid",
- "code":"hbcn",
- "tmdid":"153445tmdid",
- "tmdname":"醍摩豆。昵称",
- "title":"本次教研活动有哪些建议?",
- "comment":"请大家踊跃讨论!",
- "time":0,
- "school":"hbcn",
- "wordCount":500,//字数限制
- "timeoutReply":false,
- "expire":11255522
- }
- }
- */
- /// <summary>
- /// 创建话题
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [HttpPost("upsert")]
- [AuthToken(Roles = "teacher,admin,student")]
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> upsert(JsonElement request) {
- var (tid, tname, _, tschool) = HttpContext.GetAuthTokenInfo();
- /// 评论/话题的统一id,用于被关联
- request.TryGetProperty("comid", out JsonElement _comid);
- /// 创建来源
- if (!request.TryGetProperty("source", out JsonElement _source)) { return BadRequest("source param is null!"); }
- request.TryGetProperty("debate", out JsonElement _debate);
- string comid = $"{_comid}";
- ///如果位空则表示来源并非 技能点话题或者作品成果话题 或者以及其他已经定义的业务类型关联的comid,为保证数据完整性,则需要重新生成。
- if (string.IsNullOrEmpty(comid)) {
- comid = Guid.NewGuid().ToString();
- }
- Debate debate= _debate.ToObject<Debate>();
- debate.comid = comid;
- debate.source = $"{_source}";
- if ($"{_source}".Equals("normal") || $"{_source}".Equals("ability")) {
- debate.openType = 1;
- }
- else { debate.openType = 0; }
- debate.pk = "Debate";
- if (string.IsNullOrEmpty(debate.code))
- {
- return BadRequest("debate.code param is null!");
- }
- else {
- debate.code = debate.code.StartsWith("Debate-") ? debate.code : $"Debate-{debate.code}";
- }
- ///个人的不建立分区键
- if (debate.code.Contains(tid)) {
- debate.scope="private";
- debate.code="Debate";
- }
- if (!string.IsNullOrWhiteSpace(tschool) && debate.code.Contains(tschool))
- {
- debate.scope="school";
- }
- if (string.IsNullOrEmpty(debate.id)) {
- debate.id = Guid.NewGuid().ToString();
- debate.time= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(debate, new PartitionKey(debate.code));
- }
- else {
- try
- {
- Debate _DBdebate = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>(debate.id, new PartitionKey(debate.code));
- ///保证记录回复记录和点赞记录正常
- debate.replies = _DBdebate.replies;
- debate.likeCount = _DBdebate.likeCount;
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(debate, debate.id, new PartitionKey(debate.code));
- }
- catch (CosmosException ex) {
- if (ex.Status == 404) {
- await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(debate, new PartitionKey(debate.code));
- }
- }
- }
- return Ok(new { debate= debate,now= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
- }
- }
- }
|