CrazyIter_Bin 2 سال پیش
والد
کامیت
d15c66c6c9

+ 28 - 5
TEAMModelOS.SDK/Models/Cosmos/School/CourseBase.cs

@@ -79,8 +79,8 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public string color { get; set; }
         /// <summary>
-        /// 年级
-        ///  注:比如高二可能会将高三的课程学完,则该高三的课程的学年级应该是手动处理为高中二年级。可能不区分学期的目的,也是可能存在提前一学期学完第二学期的课程。
+        /// 年级,此处的下标是从0-n开始的。
+        ///  注:比如高二可能会将高三的课程学完,则该高三的课程的学年级应该是手动处理为高中二年级。不区分学期的目的,也是可能存在提前一学期学完第二学期的课程。
         /// </summary>
         public HashSet<int> grades { get; set; } = new HashSet<int>();
 
@@ -129,11 +129,15 @@ namespace TEAMModelOS.SDK.Models
      */
     /// <summary>
     /// 课程任务
+    /// 学校课程
+    /// id 2022-semesterId-courseId
+    /// code CourseTask-hbcn
+    /// 个人课程
+    /// id $"{_courseId}";
+    ///  $"CourseTask-{tmdid}";
     /// </summary>
     public class CourseTask : CosmosEntity
     {
-        // id 2022-semesterId
-        // code CourseTask-hbcn-courseId
         /// <summary>
         /// 过期时间,-1永不过期, 1577808000000 2020-01-01。  学校的课程则自动根据学期的时间变化。
         /// </summary>
@@ -185,6 +189,14 @@ namespace TEAMModelOS.SDK.Models
         /// 排课时间表
         /// </summary>
         public List<ScheduleTime> times { get; set; } = new List<ScheduleTime>();
+        /// <summary>
+        /// 个人课程,讲座,研讨会,直播开始时间。用通知预报开始时间。
+        /// </summary>
+        public long startTime { get; set; }
+        /// <summary>
+        /// 开课通知内容,比如临时调整上课地点,或需要准备的资料,开课主讲内容等。
+        /// </summary>
+        public string notice { get; set; }
         
     }
 
@@ -301,10 +313,21 @@ namespace TEAMModelOS.SDK.Models
         /// 教室编号 选题,表示网课或不确定上课教室,编号需要与现有教室列表的编号匹配,才能导入
         /// </summary>
         public string roomId { get; set; }
+
+        /// <summary>
+        /// 个人课程,讲座,研讨会,直播开始时间。用通知预报开始时间。
+        /// </summary>
+        public long startTime { get; set; }
+        /// <summary>
+        /// 开课通知内容,比如临时调整上课地点,或需要准备的资料,开课主讲内容等。
+        /// </summary>
+        public string notice { 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根据开学时间无法获取学期信息
+        /// 12.班级入学年-编号不存在,13.导入的班级入学年-编号在系统中重复,请检查行政班设置,14.班级入学年-编号格式错误,15根据开学时间无法获取学期信息,16学期不存在
         /// </summary>
         public int invalidCode { get; set; } = -1;
     }

+ 77 - 4
TEAMModelOS.SDK/Models/Service/SchoolService.cs

@@ -288,7 +288,9 @@ namespace TEAMModelOS.SDK
             DateTimeOffset date = default;
             if (!(!string.IsNullOrWhiteSpace(time) && DateTimeOffset.TryParse(time, out date)))
             {
-                date = DateTimeOffset.UtcNow;
+                //date = DateTimeOffset.FromUnixTimeSeconds(1672506061);
+               //date = DateTimeOffset.UtcNow;
+                date = DateTimeOffset.FromUnixTimeSeconds(1662688000);
             }
             //年级算法
             //var period = school.period.Find(x => x.id.Equals(periodId));
@@ -340,13 +342,31 @@ namespace TEAMModelOS.SDK
                     break;
                 }
                 else {
-                    if (sortSemesters[i].month >= Month && sortSemesters[i].day >= Day && sortSemesters[next].month < Month && sortSemesters[next].day < Day) 
-                    {
+
+                    var fdate= DateTimeOffset.Parse($"{studyYear}/{sortSemesters[i].month}/{sortSemesters[i].day}");
+                    long lf = fdate.ToUnixTimeSeconds();
+                    var ndate = DateTimeOffset.Parse($"{studyYear}/{sortSemesters[next].month}/{sortSemesters[next].day}");
+                    long ln = ndate.ToUnixTimeSeconds();
+                    //代表有跨年
+                    if (lf > ln) {
+                        ndate = DateTimeOffset.Parse($"{studyYear+1}/{sortSemesters[next].month}/{sortSemesters[next].day}");
+                        ln = ndate.ToUnixTimeSeconds();
+                    }
+                    var cdate = DateTimeOffset.Parse($"{Year}/{Month}/{Day}");
+                    long lc = fdate.ToUnixTimeSeconds();
+                    if (lc >= lf && lc < ln) {
                         semester = sortSemesters[i];
                         nextSemester = DateTimeOffset.Parse($"{studyYear}/{sortSemesters[next].month}/{sortSemesters[next].day}");
                         //nextSemester = sortSemesters[next];
-                        break; 
+                        break;
                     }
+                    //if (sortSemesters[i].month <=Month && sortSemesters[i].day >= Day && sortSemesters[next].month < Month && sortSemesters[next].day < Day) 
+                    //{
+
+                    //    semester = sortSemesters[i];
+                    //    nextSemester = DateTimeOffset.Parse($"{studyYear}/{sortSemesters[next].month}/{sortSemesters[next].day}");
+                    //    break; 
+                    //}
                 }
             }
             return (semester,studyYear,date, nextSemester); 
@@ -395,6 +415,59 @@ namespace TEAMModelOS.SDK
             }
         }
 
+        /// <summary>
+        /// 校验
+        /// </summary>
+        /// <param name="courseTaskInsert"></param>
+        public static  CourseTaskInsert CheckCourseTaskInsert(CourseTaskInsert courseTaskInsert,School school,Period period, List<CourseBase> courseBases, List<GroupListDto> groupListDtos, List<Room> rooms, List<SchoolTeacher> schoolTeachers)
+        {
+            //学年
+            if (courseTaskInsert.year < 2000)
+            {
+                courseTaskInsert.invalidCode = 17;//学年应大于2000
+                return courseTaskInsert;
+            }
+            //学期
+            var semester =  period.semesters.Where(z => z.id.Equals(courseTaskInsert.semesterId));
+            if (!semester.Any()) {
+                courseTaskInsert.invalidCode = 16;//学期不存在
+                return courseTaskInsert;
+            }
+            //课程
+            var courseBase = courseBases.Where(z => z.id.Equals(courseTaskInsert.courseId));
+            if (!courseBase.Any())
+            {
+                courseTaskInsert.invalidCode = 1;//课程不存在
+                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;
+            }
+            //教室
+            if (!string.IsNullOrWhiteSpace(courseTaskInsert.roomId)) {
+                var room = rooms.Where(z => z.id.Equals(courseTaskInsert.roomId));
+                if (!room.Any())
+                {
+                    courseTaskInsert.invalidCode = 4;//教室不存在
+                    return courseTaskInsert;
+                }
+            }
+            //教师
+            var teachers = schoolTeachers.Where(z => z.id.Equals(courseTaskInsert.teacherId));
+            if (!teachers.Any())
+            {
+                courseTaskInsert.invalidCode = 2;//教师不存在
+                return courseTaskInsert;
+            }
+            courseTaskInsert.invalidCode = 0;
+            return courseTaskInsert;
+        }
+
+
         public static async Task<(List<Class> school_classes, List<Class> graduate_classes)> DoGraduateClasses(HttpTrigger _httpTrigger, AzureCosmosFactory _azureCosmos, List<string> periodIds, School school_base, Option _option,DingDing _dingDing, int waite = 0) {
             List<Class> school_classes = new List<Class>();
             List<Class> graduate_classes = new List<Class>();

+ 131 - 13
TEAMModelOS/Controllers/Both/CourseBaseController.cs

@@ -25,6 +25,7 @@ using Microsoft.Azure.Amqp.Sasl;
 using DocumentFormat.OpenXml.Drawing.Charts;
 using FastJSON;
 using OpenXmlPowerTools;
+using DocumentFormat.OpenXml.Drawing.Spreadsheet;
 
 namespace TEAMModelOS.Controllers.Both
 {
@@ -99,8 +100,8 @@ namespace TEAMModelOS.Controllers.Both
                             string tbname = $"{_scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
                             Azure.Response response= await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemStreamAsync(_id.ToString(), new PartitionKey($"CourseBase-{_code}"));
                             //需要联动删除排课
-                            string taskCode = $"CourseTask-{_code}-{_id}";
-                            string taskSql = $"select value c from c ";
+                            string taskCode = $"CourseTask-{_code}";
+                            string taskSql = $"select value c from c where c.courseId='{_id}'";
                             List<CourseTask> courseTasks = new List<CourseTask>();
                             await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
                             .GetItemQueryIterator<CourseTask>(queryText: taskSql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(taskCode) }))
@@ -146,12 +147,14 @@ namespace TEAMModelOS.Controllers.Both
                             {
                                 return BadRequest();
                             }
+                            if (!request.TryGetProperty("courseId", out JsonElement _courseId)) return BadRequest();
+
                             string tbname = $"{_scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
                             if (_scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                             {
 
                                 if (!request.TryGetProperty("periodId", out JsonElement _periodId)) return BadRequest();
-                                if (!request.TryGetProperty("courseId", out JsonElement _courseId)) return BadRequest();
+                             
                                 int studyYear = -1;
                                 string semesterId = string.Empty;
                                 School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
@@ -159,8 +162,6 @@ namespace TEAMModelOS.Controllers.Both
                                 if (!request.TryGetProperty("year", out JsonElement _year) || !request.TryGetProperty("semesterId", out JsonElement _semesterId))
                                 {
                                     //如果没传,则以当前时间获取学年和学期信息
-                                  
-                                 
                                     (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) info = SchoolService.GetSemester(period);
                                     semesterId = info.currSemester.id;
                                     studyYear = info.studyYear;
@@ -169,8 +170,8 @@ namespace TEAMModelOS.Controllers.Both
                                     studyYear = _year.GetInt32();
                                     semesterId=_semesterId.GetString();
                                 } 
-                                string taskCode = $"CourseTask-{school}-{_courseId}";
-                                string taskId = $"{studyYear}-{semesterId}";
+                                string taskCode = $"CourseTask-{school}";
+                                string taskId = $"{studyYear}-{semesterId}-{_courseId}";
                                 Azure.Response response =  await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReadItemStreamAsync(taskId, new PartitionKey(taskCode));
                                 bool has_schedule = false;
                                 CourseTask courseTask = default;
@@ -206,21 +207,138 @@ namespace TEAMModelOS.Controllers.Both
                                 }
                                 //当courseTask 为空,则matchedClasses可能会有年级匹配建议升学年的班级清单,
                                 //注:比如高二可能会将高三的课程学完,则该高三的课程的学年级应该是手动处理为高中二年级。不区分学期的目的,也是可能存在提前一学期学完第二学期的课程。
-                                return Ok(new { studyYear, semesterId, courseTask, matchedClasses = classes, matchedTeachers = teachers });
+                                return Ok(new { studyYear, semesterId, courseTask, matchedClasses = classes, matchedTeachers = teachers.Select(z=>new { z.id,z.name,z.subjectIds,z.job,z.periodId,z.picture })});
                             }
                             else
                             {
-                                
+                                string taskCode = $"CourseTask-{id}";
+                                string taskId = $"{_courseId}";
+                                Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReadItemStreamAsync(taskId, new PartitionKey(taskCode));
+                                CourseTask courseTask = default;
+                                if (response.Status == 200)
+                                {
+                                    courseTask = JsonDocument.Parse(response.Content).RootElement.ToObject<CourseTask>();
+                                }
+                                return Ok(new { courseTask });
                             }
-                            break;
                         }
                     case bool when $"{grant_type}".Equals("insert-task", StringComparison.OrdinalIgnoreCase) :
                         {
-                            if ( !request.TryGetProperty("scope", out JsonElement _scope))
+                            if ( !request.TryGetProperty("scope", out JsonElement _scope)|| !request.TryGetProperty("datas", out JsonElement _datas))
                             {
                                 return BadRequest();
                             }
+                            
                             string tbname = $"{_scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
+                            List<CourseTaskInsert> datas = _datas.ToObject<List<CourseTaskInsert>>();
+                            if (_scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
+                            {
+                                if (!request.TryGetProperty("periodId", out JsonElement _periodId)) return BadRequest();
+                                //获取相关的名单
+                                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}'");
+                                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);
+                                    }
+                                }
+                                //获取课程
+                                List<CourseBase> courseBases = new List<CourseBase>();
+                                var courseIds = datas.Where(x => !string.IsNullOrWhiteSpace(x.courseId)).Select(c => $"'{c.courseId}'");
+                                if (courseIds.Any())
+                                {
+                                    string sqlCourse = $"select value c from c where c.id in ({string.Join(",", courseIds)}) ";
+                                    var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<CourseBase>(sqlCourse, $"CourseBase-{school}");
+                                    if (result.list.IsNotEmpty())
+                                    {
+                                        courseBases.AddRange(result.list);
+                                    }
+                                }
+                                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}"));
+                                HashSet<CourseTask> courseTasks = new HashSet<CourseTask>();
+                                List<CourseTaskInsert> invalidCourseTaskInsert= new List<CourseTaskInsert>();
+                                foreach (var data in datas)
+                                {
+                                    var courseTaskInsert =  SchoolService.CheckCourseTaskInsert(data, schoolBase, period, courseBases, groupListDtos, rooms, schoolTeachers);
+                                    if (courseTaskInsert.invalidCode == 0)
+                                    {
+                                        string taskCode = $"CourseTask-{school}";
+                                        string taskId = $"{courseTaskInsert.year}-{courseTaskInsert.semesterId}-{courseTaskInsert.courseId}";
+                                        CourseTask courseTask = courseTasks.Where(z => z.id.Equals(taskId) && z.code.Equals(taskCode)).FirstOrDefault();
+                                        if (courseTask == null)
+                                        {
+                                            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 = courseTaskInsert.courseId,
+                                                    year = courseTaskInsert.year,
+                                                    semesterId = courseTaskInsert.semesterId,
+                                                    schedules = new List<ScheduleTask> { new ScheduleTask {
+                                                        roomId = courseTaskInsert.roomId,
+                                                        groupId = courseTaskInsert.groupId,
+                                                        type = courseTaskInsert.type,
+                                                        teacherId = courseTaskInsert.teacherId,
+                                                        notice=courseTaskInsert.notice,
+                                                        startTime = courseTaskInsert.startTime,
+                                                        times= new List<ScheduleTime>()
+                                                    } }
+                                                };
+                                            }
+                                        }
+                                        var scheduleTask = courseTask.schedules.Find(z => z.type.Equals(courseTaskInsert.type) && z.groupId.Equals(courseTaskInsert.groupId) && z.teacherId.Equals(courseTaskInsert.teacherId));
+                                        if (scheduleTask == null)
+                                        {
+                                            courseTask.schedules.Add(new ScheduleTask()
+                                            {
+                                                roomId = courseTaskInsert.roomId,
+                                                groupId = courseTaskInsert.groupId,
+                                                type = courseTaskInsert.type,
+                                                teacherId = courseTaskInsert.teacherId,
+                                                times = new List<ScheduleTime>()
+                                            });
+                                        }
+                                        else
+                                        {
+                                            scheduleTask.roomId = courseTaskInsert.roomId;
+                                        }
+                                        courseTasks.Add(courseTask);
+                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(courseTask, new PartitionKey(taskCode));
+                                    }
+                                    else {
+                                        invalidCourseTaskInsert.Add(courseTaskInsert);
+                                    }
+                                    return Ok(new { invalidCourseTaskInsert, courseTasks });
+                                }
+                            }
+                            else { 
+                            }
                             break;
                         }
                     //按照模板导入进行数据转换并且进行检查
@@ -539,8 +657,8 @@ namespace TEAMModelOS.Controllers.Both
                                 string roomId= room?.id;
                                 string teacherId = teachers.Find(z => z.id.Equals(item.tmdid))?.id;
                                 CourseBase courseBase = courseBases.Find(z => z.name.Equals(item.name));
-                                string taskId = $"{info.studyYear}-{info.currSemester.id}";
-                                string taskCode = $"CourseTask-{school}-{courseBase.id}";
+                                string taskId = $"{info.studyYear}-{info.currSemester.id}-{courseBase.id}";
+                                string taskCode = $"CourseTask-{school}";
                                 CourseTask courseTask = courseTasks.FirstOrDefault(z => z.id.Equals(taskId) && z.code.Equals(taskCode));
                                 if (courseTask == null) {
                                     Azure.Response courseTaskResponse = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(taskId, new PartitionKey(taskCode));

+ 1 - 1
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -507,7 +507,7 @@ namespace TEAMModelOS.Controllers
         {
             var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
           
-            List< ScTeacher > teachers = await table.FindListByDict<ScTeacher>(new Dictionary<string, object>() { { "PartitionKey", "ScTeacher" }, { "ProjectItemID", 1350 } });
+            List< ScTeacher > teachers = await table.FindListByDict<ScTeacher>(new Dictionary<string, object>() { { "PartitionKey", "ScTeacher" }, { "ProjectItemID", 1249 } });
             List<dynamic> unbind = new List<dynamic>();
             List<dynamic> unupload_rzcl = new List<dynamic>();
             List<dynamic> uploads_rzcl = new List<dynamic>();