Ver código fonte

处理投票活动

CrazyIter_Bin 4 anos atrás
pai
commit
c03deca934

+ 128 - 1
TEAMModelFunction/VoteTrigger.cs

@@ -9,10 +9,11 @@ using System.Threading.Tasks;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Student;
 
 namespace TEAMModelFunction
 {
-  public static  class VoteTrigger
+    public static class VoteTrigger
     {
 
         public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
@@ -49,6 +50,130 @@ namespace TEAMModelFunction
                     }
                     break;
                 case "going":
+                     var tcode = code.Replace("Vote-", "");
+                    //处理教师可投票信息初始化
+                    if (vote.teachers != null && vote.scope == "school")
+                    {
+                        List<CommonData> teacherDatas = new List<CommonData>();
+                        vote.teachers.ForEach(x => {
+                            teacherDatas.Add(new CommonData
+                            {
+                                id = vote.id,
+                                code = $"Common-{x}",
+                                type = "vote",
+                                name = vote.name,
+                                startTime = vote.startTime,
+                                endTime = vote.endTime,
+                                scode = vote.code,
+                               // spcode = tcode
+                            });
+                        });
+                        List<Task<ItemResponse<CommonData>>> tasks = new List<Task<ItemResponse<CommonData>>>();
+                        foreach (var data in teacherDatas) {
+                           tasks.Add(client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<CommonData>(data, new Azure.Cosmos.PartitionKey(data.code)));
+                        }
+                      var response= await Task.WhenAll(tasks);
+                    }
+                    //处理学校教室或私人教师可投票信息初始化
+                    if (vote.classes != null) {
+
+                        List<Task<ItemResponse<CommonData>>> tasks = new List<Task<ItemResponse<CommonData>>>();
+                        //学校教室
+                        if (vote.scope == "school")
+                        {
+                            List<CommonData> classDatas = new List<CommonData>();
+                            foreach (var clazz in vote.classes) {
+                                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(clazz, new Azure.Cosmos.PartitionKey($"Class-{tcode}"));
+                                if (response.Status == 200) {
+                                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                                    Class clss = json.ToObject<Class>();
+                                    if (clss.students != null && clss.students.Count > 0) {
+                                        clss.students.ForEach(x => {
+                                            classDatas.Add(new CommonData
+                                            {
+                                                id = vote.id,
+                                                code = $"Common-{x.id}",
+                                                type = "vote",
+                                                name = vote.name,
+                                                startTime = vote.startTime,
+                                                endTime = vote.endTime,
+                                                scode = vote.code,
+                                               // spcode = x.scode
+                                            }); 
+                                        });
+                                    }
+                                }
+                            }
+                            foreach (var data in classDatas)
+                            {
+                                tasks.Add(client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync<CommonData>(data, new Azure.Cosmos.PartitionKey(data.code)));
+                            }
+
+                        }
+                        //私人教室
+                        else if (vote.scope == "private") {
+                         
+                            foreach (var clazz in vote.classes)
+                            {
+                                var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(clazz, new Azure.Cosmos.PartitionKey($"Class-{tcode}"));
+                                if (response.Status == 200)
+                                {
+                                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                                    Class clss = json.ToObject<Class>();
+                                    //处理私人教室的学生数据来源问题
+                                    //从不同学校的学生账号
+                                    if (clss.source == 1) {
+                                        List<CommonData> classDatas = new List<CommonData>();
+                                        if (clss.students != null && clss.students.Count > 0)
+                                        {
+                                            clss.students.ForEach(x => {
+                                                classDatas.Add(new CommonData
+                                                {
+                                                    id = vote.id,
+                                                    code = $"Common-{x.id}",
+                                                    type = "vote",
+                                                    name = vote.name,
+                                                    startTime = vote.startTime,
+                                                    endTime = vote.endTime,
+                                                    scode = vote.code,
+                                                   // spcode = x.scode
+                                                }); 
+                                            });
+                                            foreach (var data in classDatas)
+                                            {
+                                                tasks.Add(client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync<CommonData>(data, new Azure.Cosmos.PartitionKey(data.code)));
+                                            }
+                                        }
+                                    }
+                                    //从扫码加入的醍摩豆ID
+                                    if (clss.source == 2) {
+                                        List<CommonData> classDatas = new List<CommonData>();
+                                        if (clss.students != null && clss.students.Count > 0)
+                                        {
+                                            clss.students.ForEach(x => {
+                                                classDatas.Add(new CommonData
+                                                {
+                                                    id = vote.id,
+                                                    code = $"Common-{x.id}",
+                                                    type = "vote",
+                                                    name = vote.name,
+                                                    startTime = vote.startTime,
+                                                    endTime = vote.endTime,
+                                                    scode = vote.code,
+                                                    //spcode = x.scode
+                                                }) ; 
+                                            });
+                                            foreach (var data in classDatas)
+                                            {
+                                                tasks.Add(client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<CommonData>(data, new Azure.Cosmos.PartitionKey(data.code)));
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        var task =  await Task.WhenAll(tasks);
+                    }
                     var messageVoteEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString());
                     messageVoteEnd.ApplicationProperties.Add("name", "Vote");
                     if (voteRecords.Count > 0)
@@ -73,6 +198,8 @@ namespace TEAMModelFunction
                         //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
                     }
                     break;
+                case "finish":
+                    break;
             }
         }
     }

+ 10 - 2
TEAMModelOS.SDK/Models/Cosmos/Common/CommonData.cs

@@ -14,8 +14,16 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Student
         /// </summary>
         public string type { get; set; }
         public string name { get; set; }
-        public string startTime { get; set; }
-        public string endTime { get; set; }
+        public long  startTime { get; set; }
+        public long endTime { get; set; }
+        /// <summary>
+        /// 活动的分区键 Vote-hbcn/Vote-1606294378
+        /// </summary>
         public string scode { get; set; }
+        /// <summary>
+        /// 学校分区键或私人教室的分区键 hbcn/1606294378
+        /// </summary>
+       // public string spcode { get; set; }
+
     }
 }

+ 51 - 37
TEAMModelOS.SDK/Models/Cosmos/Common/Vote.cs

@@ -1,3 +1,4 @@
+
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
@@ -20,77 +21,90 @@ namespace TEAMModelOS.SDK.Models
 
         }
 
+        public string school { get; set; }
         /// <summary>
         /// 投票名称
         /// </summary>
         public string name { get; set; }
-        public string school { get; set; }
+        /// <summary>
+        /// 创建者的id 
+        /// </summary>
         public string creatorId { get; set; }
-        public int year { get; set; }
+        /// <summary>
+        /// pending 待发布|going 已发布|finish 已结束
+        /// </summary>
         public string progress { get; set; }
+        /// <summary>
+        /// 投票选项
+        /// </summary>
         public List<OptionsVote> options { get; set; }
+        /// <summary>
+        /// //匿名投票,不公布投票人相关信息
+        /// </summary>
         public bool secret { get; set; }
-        public int selectMax { get; set; }
-        public int stuCount { get; set; }
+        /// <summary>
+        /// 投票周期/once一次,day天,week周,month月,年year等
+        /// </summary>
+        public string times { get; set; }
+        //周期内可投票数
+        public int voteNum { get; set; }
+        /// <summary>
+        /// school|private
+        /// </summary>
         public string scope { get; set; }
-        public List<string> targetClassIds { get; set; }
         /// <summary>
-        /// 发布模式 0 立即发布 1 定时
+        /// 参与投票的教师醍摩豆id
         /// </summary>
-        public string publishModel { get; set; }
-
+        public List<string> teachers { get; set; }
+        /// <summary>
+        ///  scope 为school时 是学校的班级  为private 时是私人班级
+        /// </summary>
+        public List<string> classes { get; set; }
         /// <summary>
         /// 开始时间
         /// </summary>
         public long startTime { get; set; }
+        /// <summary>
+        /// 创建时间
+        /// </summary>
         public long createTime { get; set; }
-
         /// <summary>
         /// 结束时间
         /// </summary>
         public long endTime { get; set; }
-
-
+        /// <summary>
+        /// 更新时间
+        /// </summary>
+        public long updateTime { get; set; }
         /// <summary>
         /// 投票描述
         /// </summary>
         public string description { get; set; }
-
-
-        /*        /// <summary>
-                /// 投票附件
-                /// </summary>
-                [ProtoMember(9)]
-                public List<ProcessRes> resource { get; set; }
-        */
-
         /// <summary>
-        /// 状态 (100:待发布 200:已发布 300:已结束)
+        /// (100:待发布 200:已发布 300:已结束)
         /// </summary>
         public int status { get; set; }
 
 
-        /*        /// <summary>
-                /// 模式
-                /// </summary>
-                [ProtoMember(11)]
-                public List<string> other { get; set; }*/
-
-        /*
-                public string url { get; set; }
-
-                /// <summary>
-                /// 选项
-                /// </summary>
-                [ProtoMember(12)]
-                public List<Option> option { get; set; }*/
-
-        //public long sequenceNumber { get; set; }
     }
+    /// <summary>
+    /// 投票选项
+    /// </summary>
     public class OptionsVote
     {
+        /// <summary>
+        /// 投票编号
+        /// </summary>
         public string code { get; set; }
+        /// <summary>
+        /// 投票对象
+        /// </summary>
         public string value { get; set; }
+        /// <summary>
+        /// 投票对象描述
+        /// </summary>
         public string desc { get; set; }
     }
+    
 }
+

+ 8 - 1
TEAMModelOS.SDK/Models/Cosmos/School/Class.cs

@@ -43,6 +43,10 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public string openType { get; set; }
         public string scope { get; set; }
+        /// <summary>
+        /// 学生名单数据来源 1是不同学校的学生账号,2是扫码加入的醍摩豆ID
+        /// </summary>
+        public int source { get; set; }
         
     }
 }
@@ -54,7 +58,10 @@ public class Point
 }
 public class StudentSimple
 {
-
+    /// <summary>
+    /// 数据来源的分区键 如果是学校的编码 则是学校编码,如果是tmdid则是Base
+    /// </summary>
+    public string scode { get; set; }
     public string id { get; set; }
 
     public string name { get; set; }

+ 254 - 326
TEAMModelOS/Controllers/Common/VoteController.cs

@@ -17,6 +17,10 @@ using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
+using TEAMModelOS.Models;
+using Microsoft.Extensions.Options;
+using TEAMModelOS.SDK.Models.Cosmos.Student;
+using Microsoft.AspNetCore.Authorization;
 
 namespace TEAMModelOS.Controllers.Learn
 {
@@ -30,15 +34,22 @@ namespace TEAMModelOS.Controllers.Learn
     [ApiController]
     public class VoteController : ControllerBase
     {
-        private readonly SnowflakeId _snowflakeId;
+        private readonly AzureRedisFactory _azureRedis;
         private readonly AzureCosmosFactory _azureCosmos;
+        private readonly SnowflakeId _snowflakeId;
         private readonly AzureServiceBusFactory _serviceBus;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
 
-        public VoteController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId)
+        public VoteController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option,
+            AzureRedisFactory azureRedis)
         {
-            _snowflakeId = snowflakeId;
             _azureCosmos = azureCosmos;
             _serviceBus = serviceBus;
+            _snowflakeId = snowflakeId;
+            _dingDing = dingDing;
+            _option = option?.Value;
+            _azureRedis = azureRedis;
         }
 
 
@@ -48,234 +59,288 @@ namespace TEAMModelOS.Controllers.Learn
         /// <param name="request"></param>
         /// <returns></returns>
         [ProducesDefaultResponseType]
-        [HttpPost("upsert")]
-        public async Task<IActionResult> Upsert(VoteDto request)
+        [HttpPost("save")]
+        public async Task<IActionResult> Save(Vote request)
         {
-            /*ResponseBuilder builder = ResponseBuilder.custom();
-            //新增
-            if (string.IsNullOrEmpty(request.vote.id))
-            {
-                request.vote.id = _snowflakeId.NextId()+"";
-                request.vote.status = 100;
-                request.vote.code = typeof(Vote).Name + "-" + request.vote.code;
-            }
-            if (request.vote.publishModel.Equals("0"))
-            {
-                request.vote.startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-                request.vote.status = 200;
-                
-            } else if (request.vote.publishModel.Equals("1")) {
-
-                string msgId = _snowflakeId.NextId() + "";
-                long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime, 200, msgId);
-                request.vote.sequenceNumber = SequenceNumber;
-            }*/
-
-
-            //新增ote
-            //string code = request.vote.code;
-            var client = _azureCosmos.GetCosmosClient();
-            Vote vote = new Vote();
-            request.vote.school = request.vote.code;
-            request.vote.code = request.vote.pk + "-" + request.vote.code;
-            request.vote.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-            /*if (request.vote.publishModel.Equals("0"))
-            {
-                //request.vote.startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-                request.vote.progress = "going";
-            }
-            else if (request.vote.publishModel.Equals("1"))
+            try
             {
+                //新增Vote
+                var client = _azureCosmos.GetCosmosClient();
+                request.code = request.pk + "-" + request.code;
+                request.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 
-                string msgId = _snowflakeId.NextId() + "";
-                long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime, "going", msgId);
-                request.vote.sequenceNumber = SequenceNumber;
-
-            }*/
-            if (string.IsNullOrEmpty(request.vote.id))
-            {
-                request.vote.id = Guid.NewGuid().ToString();
-                //request.survey.status = 100;
-                request.vote.progress = "pending";
-                /* long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime);
-                 request.vote.sequenceNumber = SequenceNumber;*/
-                vote = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request.vote, new PartitionKey($"{request.vote.code}"));
-                /*if (request.vote.scope.Equals("school"))
+                if (string.IsNullOrEmpty(request.id))
                 {
-                    vote = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request.vote, new PartitionKey($"Vote-{code}"));
+                    request.id = Guid.NewGuid().ToString();
+                    request.progress = "pending";
+                    request = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request, new PartitionKey($"{request.code}"));
                 }
                 else
                 {
-                    vote = await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(request.vote, new PartitionKey($"Vote-{code}"));
-                }*/
+                    Vote info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(request.id, new PartitionKey($"{request.code}"));
+                    if (info.progress.Equals("going"))
+                    {
+                        return Ok(new { v = "活动正在进行中" });
+                    }
+                    request.progress = info.progress;
+                    request = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request, info.id, new PartitionKey($"{info.code}"));
+                   
+                }
+                return Ok(new { request });
             }
-            else
+            catch (Exception e)
             {
-                Vote info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(request.vote.id, new PartitionKey($"{request.vote.code}"));
-                if (info.progress.Equals("going"))
-                {
-                    return Ok(new { v = "活动正在进行中" });
-                }
-                //request.vote.code = info.code;
-                request.vote.progress = info.progress;
-                /* await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName,info.sequenceNumber);
-                 long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.startTime);
-                 request.vote.sequenceNumber = SequenceNumber;*/
-                vote = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request.vote, info.id, new PartitionKey($"{info.code}"));
-                /*if (request.vote.scope.Equals("school"))
-                {
-                    vote = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(request.vote, request.vote.id, new PartitionKey($"{request.vote.code}"));
-                }
-                else
-                {
-                    vote = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(request.vote, request.vote.id, new PartitionKey($"{request.vote.code}"));
-                }*/
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/save()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest(e.StackTrace);
             }
-            //Vote homeWork = await _azureCosmos.SaveOrUpdate<Vote>(request.vote);
-
-            //设定结束时间
-            //_timerWorkService.TimerWork<Vote>(request.vote.endTime, 300, new Dictionary<string, object> { { "id", request.vote.id } });
-            //设定结束时间
-            //await _serviceBus.GetServiceBusClient().SendLeamMessage<Vote>(Constants.TopicName, request.vote.id, request.vote.code, request.vote.endTime);
-            //清除作业
-            /*  if (!request.reset)
-              {
-                  //根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
-
-                  List<VoteRecord> voteRecords = await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> { { "id", request.vote.id } });
-
-                  if (voteRecords.IsNotEmpty())
-                  {
-                      await _azureCosmos.DeleteAll(voteRecords);
-                  }*/
-            //List<Target> targets = request.@params.vote.target;
-            //List<VoteRecord> votekStudents = new List<VoteRecord>();
-            //foreach (Target target in targets)
-            //{
-            //    //查询之前是否有 关联关系表 HomeWorkStudent 有则删除
-
-            //    List<ClassStudent> classroom = await _cosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", target.classroomCode } });
-            //    if (classroom.IsNotEmpty() && classroom[0].code!=null)
-            //    {
-            //        foreach (ClassStudent student in classroom)
-            //        {
-            //            VoteRecord voteStudent = new VoteRecord();
-            //            voteStudent.id = request.@params.vote.id;
-            //            voteStudent.code = student.code;
-            //            voteStudent.classroom.code = target.classroomCode;
-            //            voteStudent.classroom.name = target.classroomName;
-            //            votekStudents.Add(voteStudent);
-            //        }
-            //    }
-            //}
-            //if (votekStudents.IsNotEmpty())
-            //{
-            //    foreach (VoteRecord voteRecord in votekStudents)
-            //    {
-            //        List<Student> student = await _cosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId", voteRecord.code } });
-            //        if (student.IsNotEmpty())
-            //        {
-            //            voteRecord.name = student[0].name;
-            //            voteRecord.code = student[0].studentId;
-            //        }
-            //    }
-            //    await _cosmos.SaveOrUpdateAll(votekStudents);
-            //}
-            /*            }*/
-            //return builder.Data(homeWork).build();
-            return Ok(new { vote });
         }
-
         /// <summary>
-        /// 查询投票活动
+        /// 查询投票活动,用于列表,编辑,查看
         /// </summary>
+        /// <data>
+        ///Vote-学校/教师编码  活动分区        !"code":"hbcn"/1606285227 
+        ///时间筛选范围开始时间 默认30天之前   ?"stime":1608274766154  
+        ///时间筛选范围结束时间 默认当前时间   ?"etime":1608274766666 
+        ///每页大小     ?"count":10/null/Undefined  
+        ///分页Token    ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
+        /// </data>
         /// <param name="request"></param>
         /// <returns></returns>
-
         [ProducesDefaultResponseType]
         [HttpPost("find")]
         public async Task<IActionResult> Find(JsonElement requert)
         {
-
-            var client = _azureCosmos.GetCosmosClient();
-            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-            if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
-            StringBuilder sql = new StringBuilder();
-            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 ");
-            /*if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-            if (!requert.TryGetProperty("@CURRPAGE", out JsonElement page)) return BadRequest();
-            if (!requert.TryGetProperty("@PAGESIZE", out JsonElement size)) return BadRequest();
-            if (!requert.TryGetProperty("@DESC", out JsonElement desc)) return BadRequest();*/
-            Dictionary<string, object> dict = new Dictionary<string, object>();
-            var emobj = requert.EnumerateObject();
-            while (emobj.MoveNext())
-            {
-                dict[emobj.Current.Name] = emobj.Current.Value;
-            }
-            //处理code
-            if (dict.TryGetValue("code", out object _))
-            {
-                dict.Remove("code");
-            }
-            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
-            List<object> votes = new List<object>();
-            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
+            try
             {
-                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                //必须有学校或者教师编码
+                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
+                //开始时间,默认最近三十天
+                var stimestamp = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds();
+                if (!requert.TryGetProperty("stime", out JsonElement stime)) {
+                    if (stime.TryGetInt64(out long data))
+                    {
+                        stimestamp = data;
+                    };
+                };
+                //默认当前时间
+                var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                if (!requert.TryGetProperty("etime", out JsonElement etime))
+                {
+                    if (stime.TryGetInt64(out long data))
+                    {
+                        etimestamp = data;
+                    };
 
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                };
+                
+                string continuationToken = null;
+                //默认不指定返回大小
+                int? topcout=null;
+                if (!requert.TryGetProperty("count", out JsonElement jcount)) {
+                    if(jcount.TryGetInt32(out int data))
+                    {
+                        topcout = data;
+                    };
+                };
+                //是否需要进行分页查询,默认不分页
+                bool iscontinuation = false;
+                //如果指定了返回大小
+                if (!requert.TryGetProperty("continuationToken", out JsonElement continuation))
                 {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                    //指定了cancellationToken 表示需要进行分页
+                    if (!continuation.ValueKind.Equals(JsonValueKind.Null) && !continuation.ValueKind.Equals(JsonValueKind.String))
                     {
-                        votes.Add(obj.ToObject<object>());
+                        continuationToken = continuation.GetString();
+                        iscontinuation = true;
                     }
-                }
-            }
-            /*if (scope.ToString().Equals("school"))
-            {
-                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
+                };
+                List<object> votes = new List<object>();
+                var client = _azureCosmos.GetCosmosClient();
+             
+                var query =$"select   c.id,c.name,c.code,c.startTime,c.endTime,c.progress from c where c.createTime >= {stimestamp} and c.createTime <= {etimestamp} ";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query,
+                    requestOptions: new QueryRequestOptions() {MaxItemCount = topcout, PartitionKey = new PartitionKey($"Vote-{code}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
-
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
                         foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                         {
-                            votes.Add(obj.ToObject<object>());
+                            votes.Add(obj.ToObject<JsonElement>());
+                        }
+                        //如果需要分页则跳出
+                        if (iscontinuation) {
+                            continuationToken = item.GetContinuationToken();
+                            break;
                         }
                     }
                 }
+                return Ok(new { votes, continuationToken });
             }
-            else
+            catch (Exception ex)
             {
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
-                {
-                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest(ex.StackTrace);
+            }
+        }
+        /// <summary>
+        /// 查询投票活动,用于教师投票的列表
+        /// </summary>
+        /// <data>
+        ///Common-学生/教师编码 对象分区       !"code":"habook01"/"1606285227" 
+        ///时间筛选范围开始时间 默认30天之前   ?"stime":1608274766154  
+        ///时间筛选范围结束时间 默认当前时间   ?"etime":1608274766666 
+        ///每页大小     ?"count":10/null/Undefined  
+        ///分页Token    ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
+        /// </data>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("find-tch")]
+        [Authorize(Roles = "teacher")]
+        public async Task<IActionResult> FindTch(JsonElement requert)
+        {
+            (List<CommonData> datas, string continuationToken) = await FindByRole("Teacher", requert);
+            return Ok(new { datas, continuationToken });
+        }
 
-                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+        /// <summary>
+        /// 查询投票活动,用于学生可以投票的列表
+        /// </summary>
+        /// </summary>
+        /// <data>
+        ///Common-学生/教师编码 对象分区       !"code":"habook01"/"1606285227" 
+        //////Common-学生/教师编码 对象分区    ?"type":"vote"/"exam"/"homework"/"learn"/"survey"" // vote投票 survey问卷 exam评测 learn学习活动 homework作业活动
+        ///时间筛选范围开始时间 默认30天之前   ?"stime":1608274766154  
+        ///时间筛选范围结束时间 默认当前时间   ?"etime":1608274766666 
+        ///每页大小     ?"count":10/null/Undefined  
+        ///分页Token    ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
+        /// </data>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("find-stu")]
+        [Authorize(Roles = "student")]
+        public async Task<IActionResult> FindStu(JsonElement requert)
+        {
+            (List<CommonData> datas, string continuationToken)  =await  FindByRole("Student", requert);
+            return Ok(new { datas, continuationToken });
+        }
+
+        public async Task<(List<CommonData> datas, string continuationToken)> FindByRole(string containerId, JsonElement requert) {
+            //开始时间,默认最近三十天
+            var stimestamp = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds();
+            if (!requert.TryGetProperty("stime", out JsonElement stime))
+            {
+                if (stime.TryGetInt64(out long data))
+                {
+                    stimestamp = data;
+                };
+            };
+            if (!requert.TryGetProperty("type", out JsonElement type))
+            {
+                if (stime.TryGetInt64(out long data))
+                {
+                    stimestamp = data;
+                };
+            };
+            //默认当前时间
+            var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            if (!requert.TryGetProperty("etime", out JsonElement etime))
+            {
+                if (etime.TryGetInt64(out long data))
+                {
+                    etimestamp = data;
+                };
+
+            };
+            string continuationToken = null;
+            //默认不指定返回大小
+            int? topcout = null;
+            if (!requert.TryGetProperty("count", out JsonElement jcount))
+            {
+                if (jcount.TryGetInt32(out int data))
+                {
+                    topcout = data;
+                };
+            };
+            //是否需要进行分页查询,默认不分页
+            bool iscontinuation = false;
+            //如果指定了返回大小
+            if (!requert.TryGetProperty("continuationToken", out JsonElement continuation))
+            {
+                //指定了cancellationToken 表示需要进行分页
+                if (!continuation.ValueKind.Equals(JsonValueKind.Null) && !continuation.ValueKind.Equals(JsonValueKind.String))
+                {
+                    continuationToken = continuation.GetString();
+                    iscontinuation = true;
+                }
+            };
+            List<CommonData> datas = new List<CommonData>();
+            var query = $"select value(c) from c where c.createTime >= {stimestamp} and c.createTime <= {etimestamp} ";
+            var client = _azureCosmos.GetCosmosClient();
+            var (id, _, _, _) = HttpContext.GetAuthTokenInfo();
+            await foreach (var item in client.GetContainer("TEAMModelOS", containerId).GetItemQueryStreamIterator(query, continuationToken: continuationToken, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Common-{id}") }))
+            {
+                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                {
+                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                     {
-                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
-                        {
-                            votes.Add(obj.ToObject<object>());
-                        }
+                        datas.Add(obj.ToObject<CommonData>());
+                    }
+                    //如果需要分页则跳出
+                    if (iscontinuation)
+                    {
+                        continuationToken = item.GetContinuationToken();
+                        break;
                     }
                 }
-            }*/
-
-
-            return Ok(new { votes, votes.Count });
-            /*ResponseBuilder builder = ResponseBuilder.custom();
-            List<Vote> data = new List<Vote>();
-            if (StringHelper.getKeyCount(request) > 0)
+            }
+            return (datas, continuationToken);
+        }
+        ///<summary>
+        /// 查询投票活动,用于创建者列表,编辑,查看,投票人员查看
+        /// </summary>
+        /// <data>
+        ///    ! "id":"3c075347-75ef-4bcb-ae03-68678d02d5ef",
+        ///    ! "code":"Vote-hbcn"/"code":"Vote-1606285227"
+        /// </data>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("find-id")]
+        public async Task<IActionResult> FindById(JsonElement requert)
+        {
+            try
             {
-                data = await _azureCosmos.FindByDict<Vote>(request);
+                var client = _azureCosmos.GetCosmosClient();
+                //活动id
+                if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
+                //活动分区
+                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
+                Vote vote = null;
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Vote>(queryText: $"select value(c) from c where c.id = '{id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                {
+                    vote = item;
+                    break;
+                }
+                if (vote != null)
+                {
+                   
+                    return Ok(vote);
+                }
+                else
+                {
+                    return BadRequest("id,code不存在!");
+                }
             }
-            else
+            catch (Exception ex)
             {
-                return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常!").build();
-
+                await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote/find-id()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest(ex.StackTrace);
             }
-            return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
+
         }
 
         /// <summary>
@@ -296,122 +361,14 @@ namespace TEAMModelOS.Controllers.Learn
                 var client = _azureCosmos.GetCosmosClient();
                 var response = await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                 return Ok(new { code = response.Status });
-                /*if (scope.ToString().Equals("school"))
-                {
-                    var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
-                    return Ok(new { code = response.Status });
-                }
-                else
-                {
-                    var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
-                    return Ok(new { code = response.Status });
-                }*/
+               
 
             }
             catch (Exception e)
             {
                 return BadRequest();
             }
-            //ResponseBuilder builder = ResponseBuilder.custom();
-            /* List<IdPk> idPks = await _azureCosmos.DeleteAll<Vote>(request);
-             if (idPks.IsNotEmpty())
-             {
-                 foreach (IdPk idPk in idPks) 
-                 { 
-                     List<VoteRecord> votes =  await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> {  { "id", idPk.id } });
-                     await _azureCosmos.DeleteAll(votes);
-                 }
-                 //builder.Data(idPks);
-             }
-             else
-             {
-                 return Ok("删除失败!");
-                 //return builder.Error(ResponseCode.FAILED, "删除失败!").build();
-             }
-             return Ok(idPks);*/
-            //return builder.build();
-        }
-
-        // TODO 优化代码
-
-        /// <summary>
-        /// 撤消投票
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("cancel")]
-        public async Task<IActionResult> Cancel(JsonElement request)
-        {
-            //request.TryGetProperty("id", out JsonElement voteId);
-            ////ResponseBuilder builder = ResponseBuilder.custom();
-            //List<Vote> votes = await _azureCosmos.FindByDict<Vote>(new Dictionary<string, object> { { "id", voteId } });
-
-            //foreach (Vote vote in votes)
-            //{
-            //    vote.status = 100;
-            //    vote.progress = "pending";
-            //}
-            //List<Vote> vote1 = await _azureCosmos.UpdateAll<Vote>(votes);
-
-            ////查询之前是否有 关联关系表 HomeWorkStudent 有则删除
-            //List<VoteRecord> voteStudents = await _azureCosmos.FindByDict<VoteRecord>(new Dictionary<string, object> { { "id", voteId } });
-            //if (voteStudents.IsNotEmpty())
-            //{
-            //    await _azureCosmos.DeleteAll(voteStudents);
-            //}
-            ////return builder.Data(vote1).build();
-            //return Ok(vote1);
-            return Ok();
         }
-
-        // TODO 代码优化
-
-        /// <summary>
-        /// 查询 投票 学生关联
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        [ProducesDefaultResponseType]
-        [HttpPost("find-record")]
-        public async Task<IActionResult> FindRecord(JsonElement request)
-        {
-            //ResponseBuilder builder = ResponseBuilder.custom();
-            //List<VoteRecord> data = new List<VoteRecord>();
-            //List<Options> options = new List<Options>();
-
-            //if (StringHelper.getKeyCount(request) > 0)
-            //{
-            //    data = await _azureCosmos.FindByDict<VoteRecord>(request);
-            //    if (data.IsNotEmpty()) {
-            //        List< Vote > votes = await _azureCosmos.FindByDict<Vote>(new Dictionary<string, object> { { "id", data[0].id } });
-            //        List<OptionsVote> options2 = votes[0].options;
-            //        foreach (IGrouping<string, VoteRecord> voteStudents in data.GroupBy(x => x.option))
-            //        {
-            //            Options options1 = new Options();
-            //            options1.optionKey = voteStudents.Key;
-            //            options2.ForEach(x => { if (x.code == voteStudents.Key) options1.optionValue = x.value; });
-            //            if(options1.optionValue == null) options1.optionValue = "Null";
-            //            foreach (VoteRecord voteStudent in voteStudents)
-            //            {
-            //                options1.students.Add(voteStudent);
-            //            }
-            //            options.Add(options1);
-            //        }
-            //    }
-            //}
-            //else
-            //{
-            //    //return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常!").build();
-            //    return Ok("参数异常!");
-            //}
-            ////return builder.Data(options).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();
-            //return Ok(new { options, data.Count });
-            return Ok();
-        }
-
-        // TODO 代码优化
-
         /// <summary>
         /// 学生投票
         /// </summary>
@@ -421,36 +378,7 @@ namespace TEAMModelOS.Controllers.Learn
         [HttpPost("upsert-record")]
         public async Task<IActionResult> UpsertRecord(List<VoteRecord> request)
         {
-            //ResponseBuilder builder = ResponseBuilder.custom();
-            //await _azureCosmos.SaveOrUpdateAll<VoteRecord>(request);
             return Ok(request);
-            //return builder.Data(request).build();
         }
-
-
-        public class Options
-        {
-
-            public Options()
-            {
-                students = new List<VoteRecord>();
-            }
-
-            /// <summary>
-            /// 选项Key
-            /// </summary>
-            public string optionKey { get; set; }
-
-            /// <summary>
-            /// 选项value
-            /// </summary>
-            public string optionValue { get; set; }
-
-            /// <summary>
-            /// 选项人
-            /// </summary>
-            public List<VoteRecord> students { get; set; }
-        }
-
     }
 }

+ 1 - 1
TEAMModelOS/Startup.cs

@@ -105,7 +105,7 @@ namespace TEAMModelOS
             services.Configure<Option>(options => Configuration.GetSection("Option").Bind(options));
 
             //注入CSRedis  
-            var csredis = new CSRedis.CSRedisClient(Configuration.GetSection("Azure:Redis:ConnectionString").Get<string>());
+            var csredis = new CSRedis.CSRedisClient(Configuration.GetSection("Azure:Redis:ConnectionString").Get<string>()+ ",defaultDatabase=8,writeBuffer=10240,poolsize=50,prefix=habook:");
             CSRedis.CSRedisClient.Serialize = obj => System.Text.Json.JsonSerializer.Serialize(obj);
             CSRedis.CSRedisClient.Deserialize = (json, type) => System.Text.Json.JsonSerializer.Deserialize(json, type);
             RedisHelper.Initialization(csredis);

+ 1 - 1
TEAMModelOS/appsettings.Development.json

@@ -31,7 +31,7 @@
       "ScanModel": [ "TEAMModelOS" ]
     },
     "Redis": {
-      "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False,defaultDatabase=8,writeBuffer=10240,poolsize=50,prefix=habook:"
+      "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"
     },
     "ServiceBus": {
       "ConnectionString": "Endpoint=sb://teammodelos.servicebus.chinacloudapi.cn/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Sy4h4EQ8zP+7w/lOLi1X3tGord/7ShFHimHs1vC50Dc=",

+ 1 - 1
TEAMModelOS/appsettings.json

@@ -30,7 +30,7 @@
       "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"     
     },
     "Redis": {
-      "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False,defaultDatabase=8,writeBuffer=10240,poolsize=50,prefix=habook:"
+      "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"
     },
     "ServiceBus": {
       "ConnectionString": "Endpoint=sb://teammodelos.servicebus.chinacloudapi.cn/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=Sy4h4EQ8zP+7w/lOLi1X3tGord/7ShFHimHs1vC50Dc=",