CrazyIter_Bin 1 year ago
parent
commit
1b686b307d

+ 52 - 1
TEAMModelOS.SDK/Models/Cosmos/School/CourseBase.cs

@@ -201,8 +201,51 @@ namespace TEAMModelOS.SDK.Models
         /// 在个人课程展示这个的时候,只展示教师登录所在的学校,而且要检查当前名单是否与学校一致
         /// </summary>
         public string school { get; set; }
+        /// <summary>
+        /// 助教id集合
+        /// </summary>
+        public HashSet<string> assistants { get; set; } = new HashSet<string>();
 
     }
+    public class ScheduleTaskDto
+    {
+        /// <summary>
+        /// 教室id
+        /// </summary>
+        public string roomId { get; set; }
+        /// <summary>
+        /// 班级名单id:  行政班|教学班
+        /// </summary>
+        public string groupId { get; set; }
+        /// <summary>
+        /// type class行政班 teach教学班 
+        /// </summary>
+        public string type { get; set; }
+        /// <summary>
+        /// 教师的醍摩豆id
+        /// </summary>
+        public string teacherId { get; set; }
+        /// <summary>
+        /// 个人课程,讲座,研讨会,直播开始时间。用通知预报开始时间。
+        /// </summary>
+        public long startTime { get; set; }
+        /// <summary>
+        /// 开课通知内容,比如临时调整上课地点,或需要准备的资料,开课主讲内容等。
+        /// </summary>
+        public string notice { get; set; }
+        /// <summary>
+        /// 设计该字段的目的在于可能会出现教师个人课程,使用某一学校名单进行上课,或者教师临时自己开课,使用学校名单。
+        /// 在个人课程展示这个的时候,只展示教师登录所在的学校,而且要检查当前名单是否与学校一致
+        /// </summary>
+        public string school { get; set; }
+        /// <summary>
+        /// 助教id集合
+        /// </summary>
+        public HashSet<string> assistants { get; set; } = new HashSet<string>();
+        public int invalidCode { get; set; } = -1;
+        public string invalidMsg { get; set; }
+    }
+    
 
     public class ScheduleTime {
         /// <summary>
@@ -280,11 +323,17 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public string etime { get; set; }
         /// <summary>
+        /// 助教
+        /// </summary>
+        public string assistants { get; set; }
+        /// <summary>
         /// -1未验证的,0.验证通过的,1.课程名称无效的,2.醍摩豆ID无效的,3.教学班名称无效的,4.教室编号无效的,5.开学日期无效的,6.课程结束日期无效的,
         /// 7.排课时间格式不满足[1-n]-[1|2|3|4|5|6|7]-[A|D|C],8.没有对应的上课时间段,9.上课时间不在星期一至星期日,10.自定义模式下,需要配置对应的上课周,11.自定义模式下,上课周不在1-20周
         /// 12.班级入学年-编号不存在,13.导入的班级入学年-编号在系统中重复,请检查行政班设置,14.班级入学年-编号格式错误,15根据开学时间无法获取学期信息
         /// </summary>
         public int invalidCode { get; set; } = -1;
+        public string invalidMsg { get; set; }
+
     }
     public class CourseTaskInsert
     {
@@ -332,11 +381,13 @@ namespace TEAMModelOS.SDK.Models
         /// -1未验证的,0.验证通过的,1.课程名称无效的,2.醍摩豆ID无效的,3.教学班名称无效的,4.教室编号无效的,5.开学日期无效的,6.课程结束日期无效的,
         /// 7.排课时间格式不满足[1-n]-[1|2|3|4|5|6|7]-[A|D|C],8.没有对应的上课时间段,9.上课时间不在星期一至星期日,10.自定义模式下,需要配置对应的上课周,11.自定义模式下,上课周不在1-20周
         /// 12.班级入学年-编号不存在,13.导入的班级入学年-编号在系统中重复,请检查行政班设置,14.班级入学年-编号格式错误,15根据开学时间无法获取学期信息,16学期不存在,17,修改的信息必须要有教师或名单中的一项或两项。
-        /// 18.修改的名单不存在,19修改的教师不存在
+        /// 18.修改的名单不存在,19修改的教师不存在,20.同一教师,同一班级,同一课程,只能有一条记录,21助教老师不存在
         /// </summary>
         public int invalidCode { get; set; } = -1;
         //个人的课程 引用其他学校的名单
         public string school { get; set; }
+        public HashSet<string> assistants { get; set; } = new HashSet<string>();
+        public string invalidMsg { get; set; }
     }
     public class CourseTaskChanged : CourseTaskInsert
     {

+ 77 - 1
TEAMModelOS.SDK/Models/Service/OverallEducationService.cs

@@ -1,9 +1,14 @@
-using System;
+using Azure.Cosmos;
+using DocumentFormat.OpenXml.Drawing.Charts;
+using HTEXLib.COMM.Helpers;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
 
 namespace TEAMModelOS.SDK.Models
 {
@@ -21,5 +26,76 @@ namespace TEAMModelOS.SDK.Models
             }
             return dict;
         }
+
+        public async static Task<(List<Class> classes, List<Student> students, List<Class> grade_classes, List<Student> grade_students, List<OverallEducation> overallEducations)> 
+            GetGradeData(CosmosClient client, HashSet<int> years,string _periodId,string _school,HashSet<string> classIds,string _studyYear,string _semesterId, AzureRedisFactory _azureRedis) {
+            List<Class> classes = new List<Class>();
+            List<Student> students = new List<Student>();
+            List<Class> grade_classes = new List<Class>();
+            List<Student> grade_students = new List<Student>();
+            //StringBuilder sql = new StringBuilder($"select value c from  c where c.year in ({string.Join(",", years)}) and c.periodId='{_periodId}' ");
+            //if (classIds.Any()  && classIds.Count>0)
+            //{
+            //    sql.Append($" and c.id in ({string.Join(",", classIds.Select(z => $"'{z}'"))})");
+            //}
+            //当前条件的班级
+          //  var result = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sql.ToString(), $"Class-{_school}");
+            //classes = result.list;
+            //StringBuilder studentCountSQL = new StringBuilder($"select c.id,c.name ,c.picture, c.classId,c.periodId ,c.year from  c  " +
+              //  $"where  ( c.graduate = 0 or  IS_DEFINED(c.graduate) = false) and c.classId  in ({string.Join(",", classes.Select(z => $"'{z.id}'"))})   ");
+            //当前条件的学生
+           // var data = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>(studentCountSQL.ToString(), $"Base-{_school}");
+
+
+            //获取年级的所有的班级
+            StringBuilder gradeSql = new StringBuilder($"select value c from  c where c.year in ({string.Join(",", years)}) and c.periodId='{_periodId}' ");
+            var result_grade_classes = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(gradeSql.ToString(), $"Class-{_school}");
+            grade_classes = result_grade_classes.list;
+            //------获取当前条件的班级
+            classes= grade_classes.FindAll(z => classIds!=null  &&  classIds.Any() && classIds.Count>0 ? classIds.Contains(z.id):true && z.periodId.Equals(_periodId) && years.Contains(z.year));
+            StringBuilder grade_studentCountSQL = new StringBuilder($"select c.id,c.name ,c.picture, c.classId,c.periodId ,c.year from  c " +
+                $" where c.classId in ( {string.Join(",", grade_classes.Select(z => $"'{z.id}'"))}) and c.periodId='{_periodId}'  and   ( c.graduate = 0 or  IS_DEFINED(c.graduate) = false) ");
+            //获取年级所有学生
+            var gradeData = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>(grade_studentCountSQL.ToString(), $"Base-{_school}");
+            grade_students = gradeData.list;
+            //------获取当前条件的学生
+            students = grade_students.FindAll(z => classes.Select(x => x.id).Contains(z.classId) && z.periodId.Equals(_periodId)); 
+
+            //获取缓存的五育数据
+            //1.先从redis获取部分。
+            List<OverallEducation> overallEducations = new List<OverallEducation>();
+            foreach (var grade_class in grade_classes)
+            {
+                string key = $"OverallEducation:{_school}:{_school}:{_studyYear}:{_semesterId}:{grade_class.id}";
+                var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync(key);
+                foreach (var rcd in records)
+                {
+                    var value = rcd.Value.ToString().ToObject<OverallEducation>();
+                    if (value != null && string.IsNullOrWhiteSpace(value.studentId))
+                    {
+                        overallEducations.Add(value);
+                    }
+                }
+            }
+            //2.整个年级的学生基础信息,对比redis获取的差,看是否是有部门未缓存在Redis,缓存没有数据的学生。
+            var no_overall_stduents = grade_students.ExceptBy(overallEducations.Select(z => z.studentId), v => v.id);
+            if (no_overall_stduents.Any() && no_overall_stduents.Count() > 0)
+            {
+                string oesql = $"select value c from c where c.semesterId='{_semesterId}' and  c.year={_studyYear} and c.periodId='{_periodId}' and c.studentId in ({string.Join(",", no_overall_stduents.Select(z => $"'{z.id}'"))}) ";
+                var oeresults = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<OverallEducation>(oesql, $"OverallEducation-{_school}");
+                if (oeresults.list.IsNotEmpty())
+                {
+                    overallEducations.AddRange(oeresults.list);
+                    //将获取到的最新数据缓存在redis中。下次则不需要再次获取
+                    foreach (var item in oeresults.list)
+                    {
+                        string key = $"OverallEducation:{item.schoolCode}:{item.periodId}:{item.year}:{item.semesterId}:{item.classId}";
+                        await _azureRedis.GetRedisClient(8).HashSetAsync(key, item.studentId, item.ToJsonString());
+                        await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 * 24, 0, 0));
+                    }
+                }
+            }
+            return (classes, students, grade_classes, grade_students, overallEducations);
+        }
     }
 }

+ 78 - 0
TEAMModelOS.SDK/Models/Service/SchoolService.cs

@@ -425,6 +425,84 @@ namespace TEAMModelOS.SDK
                 return semesterList;
             }
         }
+        /// <summary>
+        /// 校验
+        /// </summary>
+        /// <param name="courseTaskInsert"></param>
+        public static ScheduleTaskDto CheckCourseTask(string scope, ScheduleTaskDto courseTaskInsert, string school,  List<GroupListDto> groupListDtos, List<Room> rooms,
+            List<SchoolTeacher> schoolTeachers, List<Teacher> teachers)
+        {
+            if (scope.Equals("school", StringComparison.OrdinalIgnoreCase))
+            {   
+                //教师
+                var schoolteachers = schoolTeachers.Where(z => z.id.Equals(courseTaskInsert.teacherId));
+                if (!schoolteachers.Any())
+                {
+                    courseTaskInsert.invalidCode = 2;//教师不存在
+
+                    return courseTaskInsert;
+                }
+                var invalidAssistants=  courseTaskInsert.assistants.Except(schoolTeachers.Select(x => x.id));
+                if (invalidAssistants != null && invalidAssistants.Any())
+                {
+                    courseTaskInsert.invalidCode = 21;
+                    courseTaskInsert.invalidMsg = $"{string.Join(",", invalidAssistants)}";
+                    return courseTaskInsert;
+                }
+            }
+            else
+            {
+                //教师
+                var teachersbase = teachers.Where(z => z.id.Equals(courseTaskInsert.teacherId));
+                if (!teachersbase.Any())
+                {
+                    courseTaskInsert.invalidCode = 2;//教师不存在
+                    return courseTaskInsert;
+                }
+                var invalidAssistants = courseTaskInsert.assistants.Except(teachers.Select(x => x.id));
+                if (invalidAssistants != null && invalidAssistants.Any())
+                {
+                    courseTaskInsert.invalidCode = 21;
+                    courseTaskInsert.invalidMsg = $"{string.Join(",", invalidAssistants)}";
+                    return courseTaskInsert;
+                }
+            }
+          
+            //名单
+            var groupList = groupListDtos.Where(z => z.id.Equals(courseTaskInsert.groupId) && z.type.Equals(courseTaskInsert.type));
+            if (!groupList.Any())
+            {
+                courseTaskInsert.invalidCode = 3;//名单不存在
+                return courseTaskInsert;
+            }
+            else
+            {
+                if (scope.Equals("private", StringComparison.OrdinalIgnoreCase))
+                {
+                    if (!groupList.First().scope.Equals("private", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(school) && school.Equals(groupList.First().school))
+                    {
+                        courseTaskInsert.school = school;
+                    }
+                }
+                else
+                {
+                    courseTaskInsert.school = school;
+                }
+            }
+            //教室
+            if (!string.IsNullOrWhiteSpace(courseTaskInsert.roomId))
+            {
+                var room = rooms.Where(z => z.id.Equals(courseTaskInsert.roomId));
+                if (!room.Any())
+                {
+                    courseTaskInsert.invalidCode = 4;//教室不存在
+                    return courseTaskInsert;
+                }
+            }
+             
+            courseTaskInsert.invalidCode = 0;
+            return courseTaskInsert;
+        }
 
         /// <summary>
         /// 校验

+ 361 - 35
TEAMModelOS/Controllers/Both/CourseBaseController.cs

@@ -26,6 +26,7 @@ using DocumentFormat.OpenXml.Drawing.Charts;
 using FastJSON;
 using OpenXmlPowerTools;
 using DocumentFormat.OpenXml.Drawing.Spreadsheet;
+using System.Text.RegularExpressions;
 
 namespace TEAMModelOS.Controllers.Both
 {
@@ -89,7 +90,7 @@ namespace TEAMModelOS.Controllers.Both
                             {
                                 courseBases.Add(item);
                             }
-                            return Ok(new { courseBases });
+                            return Ok(new { courseBases=courseBases.OrderByDescending(z=>z._ts) });
                         }
                     case bool when $"{grant_type}".Equals("delete", StringComparison.OrdinalIgnoreCase):
                         {
@@ -320,7 +321,283 @@ namespace TEAMModelOS.Controllers.Both
                                 return Ok(new { courseTask });
                             }
                         }
-                   case bool when $"{grant_type}".Equals("insert-scheduleTask", StringComparison.OrdinalIgnoreCase)
+                    case bool when $"{grant_type}".Equals("upsert-scheduleTask", StringComparison.OrdinalIgnoreCase):
+                        {
+                            List<ScheduleTaskDto> invalidCourseTask = new List<ScheduleTaskDto>();
+                            JsonElement _year= default, _semesterId=default, _courseId=default, _periodId=default;
+                        
+                            if (!request.TryGetProperty("datas", out JsonElement _datas)  && !request.TryGetProperty("courseId", out   _courseId))
+                            {
+                                return BadRequest();
+                            }
+                            if ($"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase)) {
+                                if (!request.TryGetProperty("periodId", out   _periodId)) return BadRequest();
+                                if (  !request.TryGetProperty("year", out _year)
+                                && !request.TryGetProperty("semesterId", out _semesterId)) {
+                                    return BadRequest();
+                                }
+                            }
+                            string tbname = $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
+                            List<ScheduleTaskDto> datas = _datas.ToObject<List<ScheduleTaskDto>>();
+                            //过滤掉名单,教师空的数据
+                            var invalids =  datas.FindAll(z => string.IsNullOrWhiteSpace(z.teacherId) || string.IsNullOrWhiteSpace(z.groupId) || string.IsNullOrWhiteSpace(z.type));
+                            if (invalids != null) {
+                                datas.RemoveAll(z => string.IsNullOrWhiteSpace(z.teacherId) || string.IsNullOrWhiteSpace(z.groupId) || string.IsNullOrWhiteSpace(z.type));
+                                foreach (var invalid in invalids) {
+                                    if (string.IsNullOrWhiteSpace(invalid.groupId) || string.IsNullOrWhiteSpace(invalid.type)) {
+                                        invalid.invalidCode = 3;
+                                    }
+                                    if (string.IsNullOrWhiteSpace(invalid.teacherId))
+                                    {
+                                        invalid.invalidCode = 2;
+                                    }
+                                    invalidCourseTask.Add(invalid);
+                                }
+                            }
+                            var groups= datas.GroupBy(z => new { z.teacherId, z.groupId }).Select(x => new { key = x.Key, list = x.ToList() });
+                            foreach (var item in groups) {
+                                if (item.list.Count > 1) { 
+                                    return Ok(new { invalidCourseTask=item.list.Select(z=>z.invalidCode=20) });//同一教师,同一班级,同一课程,只能有一条记录
+                                }
+                            }
+                            HashSet<CourseTask> courseTasks = new HashSet<CourseTask>();
+                            if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
+                            {
+                                string taskCode = $"CourseTask-{school}";
+                                string taskId = $"{_year}-{_semesterId}-{_courseId}";
+                                CourseTask courseTask = null;
+                                School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
+                                var period = schoolBase.period.Find(x => x.id.Equals($"{_periodId}"));
+
+                                //学年
+                                if (int.Parse(_year.ToString()) < 2000)
+                                {
+                                    return Ok(new { invalidCode = 17 });//学年应大于2000
+                                }
+                                //学期
+                                var semester = period.semesters.Where(z => z.id.Equals(_semesterId.ToString()));
+                                if (!semester.Any())
+                                {
+                                    return Ok(new { invalidCode = 16 });//学期不存在
+                                }
+                                CourseBase courseBase = null;
+                                Azure.Response responseBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync($"{_courseId.ToString()}", new PartitionKey($"CourseBase-{school}"));
+                                if (responseBase.Status == 200)
+                                {
+                                    courseBase = JsonDocument.Parse(responseBase.Content).RootElement.ToObject<CourseBase>();
+                                }
+                                else {
+                                    return Ok(new { invalidCode = 1 });//课程不存在
+                                }
+                                Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(taskId, new PartitionKey(taskCode));
+                                if (response.Status == 200)
+                                {
+                                    courseTask = JsonDocument.Parse(response.Content).RootElement.ToObject<CourseTask>();
+                                }
+                                else
+                                {
+                                    courseTask = new CourseTask
+                                    {
+                                        id = taskId,
+                                        code = taskCode,
+                                        pk = "CourseTask",
+                                        ttl = -1,
+                                        courseId = _courseId.ToString(),
+                                        year = int.Parse(_year.ToString()),
+                                        semesterId = _semesterId.ToString(),
+                                    };
+                                }
+                                //获取相关的名单
+                                List<GroupListDto> groupListDtos = await GroupListService.GetGroupListByListids(client, _dingDing, datas.Select(z => z.groupId).ToHashSet().ToList(), school);
+                                //获取相关的教室
+                                var roomIds = datas.Where(x => !string.IsNullOrWhiteSpace(x.roomId)).Select(c => $"'{c.roomId}'");
+                                List<Room> rooms = new List<Room>();
+                                if (roomIds.Any())
+                                {
+                                    string sqlRoom = $"select value c from c where c.id in ({string.Join(",", roomIds)})";
+                                    var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Room>(sqlRoom, $"Room-{school}");
+                                    if (result.list.IsNotEmpty())
+                                    {
+                                        rooms.AddRange(result.list);
+                                    }
+                                }
+                                //获取教师
+                                List<SchoolTeacher> schoolTeachers = new List<SchoolTeacher>();
+                                var teacherIds = datas.Where(x => !string.IsNullOrWhiteSpace(x.teacherId)).Select(c => $"'{c.teacherId}'");
+                                var assistants = datas.SelectMany(x => x.assistants);
+                                teacherIds = teacherIds.Union(assistants).ToHashSet();
+                                if (teacherIds.Any())
+                                {
+                                    string sqlTeacher = $"select value c from c where c.id in ({string.Join(",", teacherIds)}) ";
+                                    var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<SchoolTeacher>(sqlTeacher, $"Teacher-{school}");
+                                    if (result.list.IsNotEmpty())
+                                    {
+                                        schoolTeachers.AddRange(result.list);
+                                    }
+                                }
+                                foreach (var data in datas)
+                                {
+                                    var courseTaskInsert = SchoolService.CheckCourseTask($"{scope}",data,school,groupListDtos,rooms,schoolTeachers,null);
+                                    if (courseTaskInsert.invalidCode == 0)
+                                    {
+                                        
+                                        
+                                        var scheduleTask = courseTask.schedules.Find(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId) );
+                                        if (scheduleTask == null)
+                                        {
+                                            scheduleTask = new ScheduleTask()
+                                            {
+                                                roomId = courseTaskInsert.roomId,
+                                                groupId = courseTaskInsert.groupId,
+                                                type = courseTaskInsert.type,
+                                                teacherId = courseTaskInsert.teacherId,
+                                                times = new List<ScheduleTime>(),
+                                                school = school,
+                                            };
+                                            courseTask.schedules.Add(scheduleTask);
+                                            //新增
+                                        }
+                                        else
+                                        {
+                                            //编辑
+                                           
+                                            scheduleTask.roomId = courseTaskInsert.roomId;
+                                            scheduleTask.school = school;
+                                            scheduleTask.teacherId = courseTaskInsert.teacherId;
+                                            scheduleTask.startTime= courseTaskInsert.startTime>0?courseTaskInsert.startTime:scheduleTask.startTime;
+                                            scheduleTask.notice=string.IsNullOrWhiteSpace(courseTaskInsert.notice)?scheduleTask.notice:courseTaskInsert.notice;
+                                            scheduleTask.assistants= courseTaskInsert.assistants!=null?courseTaskInsert.assistants:courseTaskInsert.assistants;
+                                        }
+                                        //如果被删除完了,就删除该条记录。
+                                        if (courseTask.schedules.Count <= 0)
+                                        {
+                                            courseTasks.Remove(courseTask);
+                                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).DeleteItemStreamAsync(courseTask.id, new PartitionKey(courseTask.code));
+                                        }
+                                        else
+                                        {
+                                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(courseTask, new PartitionKey(taskCode));
+                                        }
+                                    }
+                                    else
+                                    {
+                                        invalidCourseTask.Add(courseTaskInsert);
+                                    }
+                                }
+                            }
+                            else {
+                                string taskCode = $"CourseTask-{tmdid}";
+                                string taskId = $"{_courseId}";
+                                CourseTask courseTask = null;
+                                CourseBase courseBase = null;
+                                Azure.Response responseBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync($"{_courseId.ToString()}", new PartitionKey($"CourseBase-{tmdid}"));
+                                if (responseBase.Status == 200)
+                                {
+                                    courseBase = JsonDocument.Parse(responseBase.Content).RootElement.ToObject<CourseBase>();
+                                }
+                                else
+                                {
+                                    return Ok(new { invalidCode = 1 });//课程不存在
+                                }
+                                Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(taskId, new PartitionKey(taskCode));
+                                if (response.Status == 200)
+                                {
+                                    courseTask = JsonDocument.Parse(response.Content).RootElement.ToObject<CourseTask>();
+                                }
+                                else
+                                {
+                                    courseTask = new CourseTask
+                                    {
+                                        id = taskId,
+                                        code = taskCode,
+                                        pk = "CourseTask",
+                                        ttl = -1,
+                                        courseId = _courseId.ToString(),
+                                        year = int.Parse(_year.ToString()),
+                                        semesterId = _semesterId.ToString(),
+                                    };
+                                }
+                                //获取相关的名单
+                                List<GroupListDto> groupListDtos = await GroupListService.GetGroupListByListids(client, _dingDing, datas.Select(z => z.groupId).ToHashSet().ToList(), school);
+                                //获取相关的教室
+                                var roomIds = datas.Where(x => !string.IsNullOrWhiteSpace(x.roomId)).Select(c => $"'{c.roomId}'");
+                                List<Room> rooms = new List<Room>();
+                                if (roomIds.Any()  && !string.IsNullOrWhiteSpace(school))
+                                {
+                                    string sqlRoom = $"select value c from c where c.id in ({string.Join(",", roomIds)})";
+                                    var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Room>(sqlRoom, $"Room-{school}");
+                                    if (result.list.IsNotEmpty())
+                                    {
+                                        rooms.AddRange(result.list);
+                                    }
+                                }
+                                //获取教师
+                                List<Teacher> teachers = new List<Teacher>();
+                                var teacherIds = datas.Where(x => !string.IsNullOrWhiteSpace(x.teacherId)).Select(c => $"'{c.teacherId}'");
+                                var assistants = datas.SelectMany(x => x.assistants);
+                                teacherIds = teacherIds.Union(assistants).ToHashSet();
+                                if (teacherIds.Any())
+                                {
+                                    string sqlTeacher = $"select value c from c where c.id in ({string.Join(",", teacherIds)}) ";
+                                    var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<Teacher>(sqlTeacher, $"Base");
+                                    if (result.list.IsNotEmpty())
+                                    {
+                                        teachers.AddRange(result.list);
+                                    }
+                                }
+                                foreach (var data in datas)
+                                {
+                                    var courseTaskInsert = SchoolService.CheckCourseTask($"{scope}", data, school, groupListDtos, rooms, null, teachers);
+                                    if (courseTaskInsert.invalidCode == 0)
+                                    {
+
+
+                                        var scheduleTask = courseTask.schedules.Find(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId));
+                                        if (scheduleTask == null)
+                                        {
+                                            scheduleTask = new ScheduleTask()
+                                            {
+                                                roomId = courseTaskInsert.roomId,
+                                                groupId = courseTaskInsert.groupId,
+                                                type = courseTaskInsert.type,
+                                                teacherId = courseTaskInsert.teacherId,
+                                                times = new List<ScheduleTime>(),
+                                                school = school,
+                                            };
+                                            courseTask.schedules.Add(scheduleTask);
+                                            //新增
+                                        }
+                                        else
+                                        {
+                                            //编辑
+
+                                            scheduleTask.roomId = courseTaskInsert.roomId;
+                                            scheduleTask.school = school;
+                                            scheduleTask.teacherId = courseTaskInsert.teacherId;
+                                            scheduleTask.startTime = courseTaskInsert.startTime > 0 ? courseTaskInsert.startTime : scheduleTask.startTime;
+                                            scheduleTask.notice = string.IsNullOrWhiteSpace(courseTaskInsert.notice) ? scheduleTask.notice : courseTaskInsert.notice;
+                                            scheduleTask.assistants = courseTaskInsert.assistants != null ? courseTaskInsert.assistants : courseTaskInsert.assistants;
+                                        }
+                                        //如果被删除完了,就删除该条记录。
+                                        if (courseTask.schedules.Count <= 0)
+                                        {
+                                            courseTasks.Remove(courseTask);
+                                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemStreamAsync(courseTask.id, new PartitionKey(courseTask.code));
+                                        }
+                                        else
+                                        {
+                                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(courseTask, new PartitionKey(taskCode));
+                                        }
+                                    }
+                                    else
+                                    {
+                                        invalidCourseTask.Add(courseTaskInsert);
+                                    }
+                                }
+                            }
+                            return Ok(new { invalidCourseTask, courseTasks });
+                        }
+                    case bool when $"{grant_type}".Equals("insert-scheduleTask", StringComparison.OrdinalIgnoreCase)
                                     || $"{grant_type}".Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase) 
                                     || $"{grant_type}".Equals("delete-scheduleTask", StringComparison.OrdinalIgnoreCase):
                         {
@@ -411,9 +688,22 @@ namespace TEAMModelOS.Controllers.Both
                                                 };
                                             }
                                         }
-                                        var scheduleTask = courseTask.schedules.Find(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId) && z.teacherId.Equals(courseTaskInsert.teacherId));
-                                        if (scheduleTask == null)
+                                        ScheduleTask scheduleTask = null;
+                                        var scheduleTasks = courseTask.schedules.FindAll(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId) );
+                                        if (scheduleTasks.IsNotEmpty())
                                         {
+                                            if (scheduleTasks.Count > 2) {
+                                                courseTask.schedules.RemoveRange(1, scheduleTasks.Count - 1);
+                                            }
+                                            scheduleTask= scheduleTasks.First();
+                                            scheduleTask.roomId = courseTaskInsert.roomId;
+                                            scheduleTask.school = school;
+                                            scheduleTask.teacherId = courseTaskInsert.teacherId;
+                                            scheduleTask.startTime = courseTaskInsert.startTime > 0 ? courseTaskInsert.startTime : scheduleTask.startTime;
+                                            scheduleTask.notice = string.IsNullOrWhiteSpace(courseTaskInsert.notice) ? scheduleTask.notice : courseTaskInsert.notice;
+                                            scheduleTask.assistants = courseTaskInsert.assistants != null ? courseTaskInsert.assistants : courseTaskInsert.assistants;
+                                        }
+                                        else {
                                             scheduleTask = new ScheduleTask()
                                             {
                                                 roomId = courseTaskInsert.roomId,
@@ -425,11 +715,6 @@ namespace TEAMModelOS.Controllers.Both
                                             };
                                             courseTask.schedules.Add(scheduleTask);
                                         }
-                                        else
-                                        {
-                                            scheduleTask.roomId = courseTaskInsert.roomId;
-                                            scheduleTask.school=school;
-                                        }
                                         //修改教师或名单
                                         if (grant_type.ToString().Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase)) {
                                             if (!string.IsNullOrWhiteSpace(courseTaskInsert.teacherIdChanged)) {
@@ -540,8 +825,23 @@ namespace TEAMModelOS.Controllers.Both
                                                 };
                                             }
                                         }
-                                        var scheduleTask = courseTask.schedules.Find(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId) && z.teacherId.Equals(courseTaskInsert.teacherId));
-                                        if (scheduleTask == null)
+                                        ScheduleTask scheduleTask  = null;
+                                        var scheduleTasks = courseTask.schedules.FindAll(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId));
+                                        if (scheduleTasks.IsNotEmpty())
+                                        {
+                                            if (scheduleTasks.Count > 2)
+                                            {
+                                                courseTask.schedules.RemoveRange(1, scheduleTasks.Count - 1);
+                                            }
+                                            scheduleTask = scheduleTasks.First();
+                                            scheduleTask.roomId = string.IsNullOrWhiteSpace(courseTaskInsert.roomId) ? scheduleTask.roomId : courseTaskInsert.roomId ;
+                                            scheduleTask.school = school;
+                                            scheduleTask.teacherId = courseTaskInsert.teacherId;
+                                            scheduleTask.startTime = courseTaskInsert.startTime > 0 ? courseTaskInsert.startTime : scheduleTask.startTime;
+                                            scheduleTask.notice = string.IsNullOrWhiteSpace(courseTaskInsert.notice) ? scheduleTask.notice : courseTaskInsert.notice;
+                                            scheduleTask.assistants = courseTaskInsert.assistants != null ? courseTaskInsert.assistants : courseTaskInsert.assistants;
+                                        }
+                                        else
                                         {
                                             scheduleTask = new ScheduleTask()
                                             {
@@ -550,15 +850,10 @@ namespace TEAMModelOS.Controllers.Both
                                                 type = courseTaskInsert.type,
                                                 teacherId = courseTaskInsert.teacherId,
                                                 times = new List<ScheduleTime>(),
-                                                school = courseTaskInsert.school,
+                                                school = school,
                                             };
                                             courseTask.schedules.Add(scheduleTask);
                                         }
-                                        else
-                                        {
-                                            scheduleTask.roomId = courseTaskInsert.roomId;
-                                            scheduleTask.school = courseTaskInsert.school;
-                                        }
                                         //修改教师或名单
                                         if (grant_type.ToString().Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase))
                                         {
@@ -651,6 +946,8 @@ namespace TEAMModelOS.Controllers.Both
                                 }
                                 courseCheckImports.RemoveAll(z => tmdidInvalidImports.Contains(z));
                             }
+                             
+
                             //3.检查导入的教学班名称是否有效
                             IEnumerable<CourseCheckImport> teachInvalidImports = null;
                             List<GroupList> groupLists = new List<GroupList>();
@@ -896,6 +1193,21 @@ namespace TEAMModelOS.Controllers.Both
                                     var groupList= groupLists.Find(z => z.name.Equals(item.list));
                                     groupId=groupList?.id;
                                 }
+                                //检查助教是否存在
+                                string[] assistants = null;
+                                if (!string.IsNullOrWhiteSpace(item.assistants)) {
+                                    Regex.Split(item.assistants, "\\.|\\.|\\、|\\:|\\:|\\,|\\,|\\;|\\;");
+                                }
+                                var invalidAssistants = assistants.Except(teachers.Select(x => x.id));
+                                if (invalidAssistants != null && invalidAssistants.Any())
+                                {
+                                    item.invalidCode = 21;
+                                    item.invalidMsg = $"{string.Join(",", invalidAssistants)}";
+                                    courseInvalidImports.Add(item);
+                                    continue;
+                                }
+
+
                                 Room room = rooms.Find(z =>!string.IsNullOrWhiteSpace(item.roomNo) &&  z.no.Equals(item.roomNo));
                                 string roomId= room?.id;
                                 string teacherId = teachers.Find(z => z.id.Equals(item.tmdid))?.id;
@@ -937,38 +1249,52 @@ namespace TEAMModelOS.Controllers.Both
                                     courseTasks.Add(courseTask);
                                 }
                                 else {
-                                    var scheduleTask= courseTask.schedules.Find(z => z.type.Equals(item.type) && z.groupId.Equals(groupId) && z.teacherId.Equals(teacherId));
-                                    if (scheduleTask == null)
+                                    ScheduleTask scheduleTask = null;
+                                    var scheduleTasks = courseTask.schedules.FindAll(z => z.type.Equals(item.type) && z.groupId.Equals(groupId));
+                                    if (scheduleTasks.IsNotEmpty())
                                     {
-                                        courseTask.schedules.Add(new ScheduleTask()
+                                        if (scheduleTasks.Count > 2)
                                         {
-                                            roomId = roomId,
-                                            groupId = groupId,
-                                            type = item.type,
-                                            teacherId = teacherId,
-                                            times = scheduleTime!=null ? new List<ScheduleTime> { scheduleTime }: new List<ScheduleTime> {  },
-                                            school = school,
-                                        });
-                                    }
-                                    else {
-                                        scheduleTask.roomId = roomId;
+                                            courseTask.schedules.RemoveRange(1, scheduleTasks.Count - 1);
+                                        }
+                                        scheduleTask = scheduleTasks.First();
+                                        scheduleTask.roomId = string.IsNullOrWhiteSpace(roomId) ? scheduleTask.roomId : roomId;
                                         scheduleTask.school = school;
-                                        if (scheduleTime != null) {
-                                            var shtime =  scheduleTask.times.Find(z => z.id.Equals(scheduleTime.id) && z.week.Equals(scheduleTime.week) && z.mode.Equals(scheduleTime.mode));
+                                        scheduleTask.teacherId = teacherId;
+                                        scheduleTask.assistants = assistants != null ? assistants.ToHashSet() : scheduleTask.assistants;
+                                        if (scheduleTime != null)
+                                        {
+                                            var shtime = scheduleTask.times.Find(z => z.id.Equals(scheduleTime.id) && z.week.Equals(scheduleTime.week) && z.mode.Equals(scheduleTime.mode));
                                             if (shtime == null)
                                             {
                                                 scheduleTask.times.Add(scheduleTime);
                                             }
-                                            else {
-                                                if (scheduleTime.index.Any()) 
+                                            else
+                                            {
+                                                if (scheduleTime.index.Any())
                                                 {
-                                                    foreach (var ind in scheduleTime.index) {
+                                                    foreach (var ind in scheduleTime.index)
+                                                    {
                                                         shtime.index.Add(ind);
                                                     }
                                                 }
                                             }
                                         }
                                     }
+                                    else
+                                    {
+                                        scheduleTask = new ScheduleTask()
+                                        {
+
+                                            roomId = roomId,
+                                            groupId = groupId,
+                                            type = item.type,
+                                            teacherId = teacherId,
+                                            times = scheduleTime != null ? new List<ScheduleTime> { scheduleTime } : new List<ScheduleTime> { },
+                                            school = school,
+                                        };
+                                        courseTask.schedules.Add(scheduleTask);
+                                    }
                                 }
                                 checkedCount++;
                             }

+ 43 - 55
TEAMModelOS/Controllers/Student/OverallEducationController.cs

@@ -2,6 +2,7 @@
 using DocumentFormat.OpenXml.Drawing.Charts;
 using DocumentFormat.OpenXml.Office2010.Excel;
 using DocumentFormat.OpenXml.Office2013.Drawing.Chart;
+using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle;
 using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
 using DocumentFormat.OpenXml.VariantTypes;
 using DocumentFormat.OpenXml.Wordprocessing;
@@ -132,68 +133,55 @@ namespace TEAMModelOS.Controllers
                 }
             }
             List<Class> classes = new List<Class>();
+            List<Student> students = new List<Student>();
             List<Class> grade_classes = new List<Class>();
-            if (years.Any() && years.Count > 0)
+            List<Student> grade_students = new List<Student>();
+            List<OverallEducation> grade_overallEducations = new List<OverallEducation>() ;
+            List<OverallEducation> overallEducations = new List<OverallEducation>();
+            HashSet<string> classIds = null;
+            if (json.TryGetProperty("classIds", out JsonElement _classIds))
             {
-                List<string> classIds = null;
-                if (json.TryGetProperty("classIds", out JsonElement _classIds))
-                {
-                    classIds = _classIds.ToObject<List<string>>();
-                }
-                StringBuilder sql = new StringBuilder($"select value c from  c where c.year in ({string.Join(",", years)}) and c.periodId='{_periodId}' ");
-                if (classIds.IsNotEmpty())
-                {
-                    sql.Append($" and c.id in ({string.Join(",", classIds.Select(z => $"'{z}'"))})");
-                }
-
-                var result = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sql.ToString(), $"Class-{_school}");
-                classes = result.list;
-
-                //获取年级的所有的班级
-                StringBuilder gradeSql = new StringBuilder($"select value c from  c where c.year in ({string.Join(",", years)}) and c.periodId='{_periodId}' ");
-                var result_grade_classes = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sql.ToString(), $"Class-{_school}");
-                grade_classes = result_grade_classes.list;
+                classIds = _classIds.ToObject<HashSet<string>>();
             }
-            //获取年级的所有学生五育,以做排名需要
-            //1.先从redis获取部分。
-            List< OverallEducation > overallEducations = new List<OverallEducation>();
-            foreach (var grade_class in grade_classes) {
-                string key = $"OverallEducation:{_school}:{_school}:{_studyYear}:{_semesterId}:{grade_class.id}";
-                var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync(key);
-                foreach (var rcd in records)
-                {
-                    var value = rcd.Value.ToString().ToObject<OverallEducation>();
-                    if (value != null && string.IsNullOrWhiteSpace(value.studentId)) {
-                        overallEducations.Add(value);
-                    }
-                }
-            }
-
-            //2.获取整个年级的学生基础信息,对比redis获取的差,看是否是有部门未缓存在Redis
-            List<Student> grade_students = new List<Student>();
-            StringBuilder studentCountSQL = new StringBuilder($"select c.id,c.name ,c.picture, c.classId,c.periodId ,c.year from  c  where c.classId in ( {string.Join(",",grade_classes.Select(z=>$"'{z.id}'"))}) and c.periodId='{_periodId}'  and   ( c.graduate = 0 or  IS_DEFINED(c.graduate) = false) ");
-            var data = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>(studentCountSQL.ToString(), $"Base-{_school}"); 
-            grade_students= data.list;
-            //缓存没有数据的学生。
-            var no_overall_stduents =  grade_students.ExceptBy(overallEducations.Select(z => z.studentId), v => v.id);
-            if (no_overall_stduents.Any() && no_overall_stduents.Count() > 0) 
+            if (years.Any() && years.Count > 0)
             {
-                string oesql = $"select value c from c where c.semesterId='{_semesterId}' and  c.year={_studyYear} and c.periodId='{_periodId}' and c.studentId in ({string.Join(",",no_overall_stduents.Select(z=>$"'{z.id}'"))}) ";
-                var oeresults = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<OverallEducation>(oesql, $"OverallEducation-{_school}");
-                if (oeresults.list.IsNotEmpty()) {
-                    overallEducations.AddRange(oeresults.list);
-                    //将获取到的最新数据缓存在redis中。下次则不需要再次获取
-                    foreach (var item in oeresults.list) {
-                        string key = $"OverallEducation:{item.schoolCode}:{item.periodId}:{item.year}:{item.semesterId}:{item.classId}";
-                        await _azureRedis.GetRedisClient(8).HashSetAsync(key, item.studentId, item.ToJsonString());
-                        await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 * 24, 0, 0));
-                    }
-                }
+                var gradeData =   await OverallEducationService.GetGradeData(client, years, $"{_periodId}", $"{_school}", classIds, $"{_studyYear}", $"{_semesterId}", _azureRedis);
+                classes=gradeData.classes;
+                students=gradeData.students;
+                grade_classes = gradeData.grade_classes;
+                grade_students=gradeData.grade_students;
+                grade_overallEducations = gradeData.overallEducations;
+                overallEducations=gradeData.overallEducations.FindAll(x=>students.Select(k=>k.id).Contains(x.studentId));
             }
-            
-
+            #endregion
+            #region
+            double dataCount = 0;
+            double sports_count90 = 0;
+            double sports_count60 = 0;
+            double sports_count = 0;
+            double art_count90 = 0;
+            double art_count60 = 0;
+            double art_count = 0;
+            double intelligence_count90 = 0;
+            double intelligence_count60 = 0;
+            double intelligence_count = 0;
+            double labour_count90 = 0;
+            double labour_count60 = 0;
+            double labour_count = 0;
+            double virtue_count90 = 0;
+            double virtue_count60 = 0;
+            double virtue_count = 0;
+            double rate90 = 0;
+            double rate60 = 0;
+            double activityCount = 0;
             #endregion
 
+            List<(double score, OverallEducation student, string className, string picture)> ranking = new List<(double score, OverallEducation student, string className, string picture)>();
+            List<(string classId, string className, double last, double best, double sum, double avg, int count)> classDatas = new List<(string classId, string className, double last, double best, double sum, double avg, int count)>();
+            if (overallEducations.IsNotEmpty()) {
+                dataCount = overallEducations.Count();
+                //pr计算  100 - (100 * (index + 1) - 50) / stuCount;  index  整体排名  stuCount 总人数
+            }
 
             return Ok();
         }