123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988 |
- using Azure.Cosmos;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Models;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using Azure;
- using Microsoft.Extensions.Configuration;
- using TEAMModelOS.Filter;
- using HTEXLib.COMM.Helpers;
- using System.Globalization;
- using TEAMModelOS.SDK;
- using Microsoft.AspNetCore.Authorization;
- using StackExchange.Redis;
- using Azure.Storage.Blobs.Models;
- using Microsoft.Azure.Amqp.Sasl;
- using DocumentFormat.OpenXml.Drawing.Charts;
- using FastJSON;
- using OpenXmlPowerTools;
- using DocumentFormat.OpenXml.Drawing.Spreadsheet;
- namespace TEAMModelOS.Controllers.Both
- {
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- [Route("course-base")]
- [ApiController]
- public class CourseBaseController : ControllerBase
- {
- private AzureCosmosFactory _azureCosmos;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- private readonly AzureServiceBusFactory _serviceBus;
- private readonly AzureStorageFactory _azureStorage;
- private readonly AzureRedisFactory _azureRedis;
- private static List<string> weekDays = new List<string> { "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };
- public IConfiguration _configuration { get; set; }
- public CourseBaseController(AzureRedisFactory azureRedis,AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration)
- {
- _azureCosmos = azureCosmos;
- _dingDing = dingDing;
- _option = option?.Value;
- _serviceBus = serviceBus;
- _configuration = configuration;
- _azureStorage = azureStorage;
- _azureRedis = azureRedis;
- }
- /// <summary>
- /// 更新保存课程
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- [ProducesDefaultResponseType]
- [AuthToken(Roles = "teacher,admin")]
- [HttpPost("manage")]
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> upsert(JsonElement request)
- {
- try {
- (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
- if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
- if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
- var client = _azureCosmos.GetCosmosClient();
- switch (true)
- {
- case bool when $"{grant_type}".Equals("list", StringComparison.OrdinalIgnoreCase):
- {
- if ( !request.TryGetProperty("code", out JsonElement _code))
- {
- return BadRequest();
- }
- string tbname = $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase)?Constant.School:Constant.Teacher;
- string code = $"CourseBase-{_code}";
- string baseSql = $"select value c from c ";
- List<CourseBase> courseBases = new List<CourseBase>();
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
- .GetItemQueryIterator<CourseBase>(queryText: baseSql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(code) }))
- {
- courseBases.Add(item);
- }
- return Ok(new { courseBases });
- }
- case bool when $"{grant_type}".Equals("delete", StringComparison.OrdinalIgnoreCase):
- {
- if (!request.TryGetProperty("id", out JsonElement _id) || !request.TryGetProperty("code", out JsonElement _code))
- {
- return BadRequest();
- }
- 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}";
- 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) }))
- {
- courseTasks.Add(item);
- }
- if (courseTasks.Count > 0)
- {
- await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemsStreamAsync(courseTasks.Select(x=>x.id).ToList(), taskCode);
- }
- return Ok(new {code= response .Status});
- }
- case bool when $"{grant_type}".Equals("import-base", StringComparison.OrdinalIgnoreCase) && $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase):
- {
- if (!request.TryGetProperty("courses", out JsonElement _courses))
- {
- return BadRequest();
- }
- if (!request.TryGetProperty("periodId", out JsonElement _periodId)) return BadRequest();
- List<CourseBase> courseBases = _courses.ToObject<List<CourseBase>>();
- //1.检查导入的课程名称是否有效
- StringBuilder sqlName = new StringBuilder(" select value c from c ");
- sqlName.Append($" where c.name in {string.Join(",",courseBases.Select(z=>$"'{z.name}'"))} and c.period.id='{_periodId}' ");
- string tbname = Constant.School;
- List<CourseBase> courseBasesDB = new List<CourseBase>();
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
- .GetItemQueryIterator<CourseBase>(queryText: sqlName.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"CourseBase-{school}") }))
- {
- courseBasesDB.Add(item);
- }
- 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 (period != null) {
- foreach (var item in courseBases)
- {
- item.pk = "CourseBase";
- if (string.IsNullOrWhiteSpace(item.id))
- {
- item.id = Guid.NewGuid().ToString();
- }
- item.scope = "school";
- item.school = school;
- item.creatorId = tmdid;
- item.code = $"CourseBase-{school}";
- item.period = new IdName { id = period.id, name = period.name };
- if (!string.IsNullOrWhiteSpace(item.subject?.id))
- {
- var subject = period.subjects.Find(x => x.id.Equals(item.subject.id));
- if (subject != null)
- {
- item.subject.name = subject.name;
- }
- }
- else {
- }
- var dbcoursebase = courseBasesDB.Find(x => x.name.Equals(item.name));
- if (dbcoursebase != null)
- {
- item.id = dbcoursebase.id;
- item.major = item.major == null ? dbcoursebase.major : item.major;
- item.desc = string.IsNullOrWhiteSpace(item.desc) ? dbcoursebase.desc : item.desc;
- item.color = string.IsNullOrWhiteSpace(item.color) ? dbcoursebase.color : item.color;
- item.no = string.IsNullOrWhiteSpace(item.no) ? dbcoursebase.no : item.no;
- item.grades = !item.grades.Any() ? dbcoursebase.grades : item.grades;
- }
- }
- }
- return Ok(new { course = courseBases });
- }
- case bool when $"{grant_type}".Equals("upsert", StringComparison.OrdinalIgnoreCase) :
- {
- if (!request.TryGetProperty("course", out JsonElement _course))
- {
- return BadRequest();
- }
- CourseBase courseBase = _course.ToObject<CourseBase>();
- courseBase.pk = "CourseBase";
- if (string.IsNullOrWhiteSpace(courseBase.id))
- {
- courseBase.id = Guid.NewGuid().ToString();
- }
- string tbname = $"{courseBase.scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
- //1.检查导入的课程名称是否有效
- StringBuilder sqlName = new StringBuilder(" select value c from c ");
- sqlName.Append($" where c.name ='{courseBase.name}' ");
- if (courseBase.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
- {
- courseBase.school = school;
- courseBase.creatorId = tmdid;
- courseBase.code = $"CourseBase-{school}";
- if (string.IsNullOrWhiteSpace(courseBase.subject?.id) || !courseBase.grades.Any()) {
- return BadRequest();
- }
- if (string.IsNullOrWhiteSpace(courseBase.period?.id))
- {
- return BadRequest();
- }
- else {
- sqlName.Append($" and c.period.id='{courseBase.period.id}' ");
- }
- }
- else
- {
- courseBase.creatorId = tmdid;
- courseBase.code = $"CourseBase-{tmdid}";
- }
- List<CourseBase> courseBases = new List<CourseBase>();
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname)
- .GetItemQueryIterator<CourseBase>(queryText: sqlName.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(courseBase.code) }))
- {
- if (courseBase.scope.Equals(item.scope))
- {
- //不是同一条数据,但是名字相同,则判定名字重复。
- if (!item.id.Equals(courseBase.id) && item.name.Equals(courseBase.name))
- {
- return Ok(new { code = 409, course = courseBase });
- }
- }
- }
- await client.GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(courseBase, new PartitionKey(courseBase.code));
- return Ok(new {code =200, course = courseBase });
- }
- case bool when $"{grant_type}".Equals("read-task", StringComparison.OrdinalIgnoreCase):
- {
-
- 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();
-
- int studyYear = -1;
- string semesterId = string.Empty;
- 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 (!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;
- }
- else {
- studyYear = _year.GetInt32();
- semesterId=_semesterId.GetString();
- }
- 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;
- if (response.Status == 200) {
- courseTask=JsonDocument.Parse(response.Content).RootElement.ToObject<CourseTask>();
- if (courseTask != null && courseTask.schedules.IsNotEmpty())
- {
- has_schedule = true;
- }
- }
- //匹配建议的班级和教师
- List<Class> classes = new List<Class>();
- List<SchoolTeacher> teachers = new List<SchoolTeacher>();
- if (!has_schedule)
- {
- //如果没有找到排课安排信息。则可以进行建议升学年方式处理
- CourseBase courseBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<CourseBase>(_courseId.ToString(), new PartitionKey($"CourseBase-{school}"));
- if (courseBase.grades.Any()) {
- var yearsdata = SchoolService.GetYears(schoolBase, _periodId.ToString(), courseBase.grades);
- List<int> years = yearsdata.years.ToList();
- if (years.IsNotEmpty())
- {
- StringBuilder sql = new StringBuilder($"select value c from c where c.year in ({string.Join(",", years)}) and c.periodId='{_periodId}' ");
- var result = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sql.ToString(), $"Class-{school}");
- classes = result.list;
- }
- }
- if (!string.IsNullOrWhiteSpace(courseBase.subject?.id)) {
- string teacherSQL = $"select distinct value c from c join b in c.subjectIds where b in ('{courseBase.subject.id}') and c.code = 'Teacher-{school}'";
- var result = await client.GetContainer(Constant.TEAMModelOS, Constant.School).GetList<SchoolTeacher>(teacherSQL.ToString(), $"Teacher-{school}");
- teachers = result.list;
- }
- }
- //当courseTask 为空,则matchedClasses可能会有年级匹配建议升学年的班级清单,
- //注:比如高二可能会将高三的课程学完,则该高三的课程的学年级应该是手动处理为高中二年级。不区分学期的目的,也是可能存在提前一学期学完第二学期的课程。
- 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-{tmdid}";
- 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 });
- }
- }
- case bool when $"{grant_type}".Equals("insert-scheduleTask", StringComparison.OrdinalIgnoreCase)
- || $"{grant_type}".Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase)
- || $"{grant_type}".Equals("delete-scheduleTask", StringComparison.OrdinalIgnoreCase):
- {
- if ( !request.TryGetProperty("datas", out JsonElement _datas))
- {
- return BadRequest();
- }
- string tbname = $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase) ? Constant.School : Constant.Teacher;
- List<CourseTaskChanged> datas = _datas.ToObject<List<CourseTaskChanged>>();
- 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<CourseTaskChanged> invalidCourseTaskInsert= new List<CourseTaskChanged>();
- foreach (var data in datas)
- {
- var courseTaskInsert = SchoolService.CheckCourseTaskInsertOrChanged($"{grant_type}", scope.ToString(),data, school, period, courseBases, groupListDtos, rooms, schoolTeachers,null);
- 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>(),
- school=school,
- } }
- };
- }
- }
- 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 = 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;
- }
- //修改教师或名单
- if (grant_type.ToString().Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase)) {
- if (!string.IsNullOrWhiteSpace(courseTaskInsert.teacherIdChanged)) {
- scheduleTask.teacherId = courseTaskInsert.teacherIdChanged;
- }
- if (!string.IsNullOrWhiteSpace(courseTaskInsert.typeChanged) && !string.IsNullOrWhiteSpace(courseTaskInsert.groupIdChanged)) {
- scheduleTask.groupId = courseTaskInsert.groupIdChanged;
- scheduleTask.type = courseTaskInsert.typeChanged;
- }
- }
- //删除教师及名单的排课信息
- if (grant_type.ToString().Equals("delete-scheduleTask", StringComparison.OrdinalIgnoreCase))
- {
- courseTask.schedules.Remove(scheduleTask);
- }
- //如果被删除完了,就删除该条记录。
- 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 {
- invalidCourseTaskInsert.Add(courseTaskInsert);
- }
- }
- return Ok(new { invalidCourseTaskInsert, courseTasks });
- }
- else {
- //获取相关的名单
- 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}'");
- 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);
- }
- }
- //获取课程
- 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.Teacher).GetList<CourseBase>(sqlCourse, $"CourseBase-{tmdid}");
- if (result.list.IsNotEmpty())
- {
- courseBases.AddRange(result.list);
- }
- }
- HashSet<CourseTask> courseTasks = new HashSet<CourseTask>();
- List<CourseTaskChanged> invalidCourseTaskInsert = new List<CourseTaskChanged>();
- foreach (var data in datas)
- {
- var courseTaskInsert = SchoolService.CheckCourseTaskInsertOrChanged($"{grant_type}", scope.ToString(),data, null, null, courseBases, groupListDtos, rooms,null, teachers);
- if (courseTaskInsert.invalidCode == 0)
- {
- string taskCode = $"CourseTask-{tmdid}";
- string taskId = 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.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 = courseTaskInsert.courseId,
- 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>(),
- school=courseTaskInsert.school,
- } }
- };
- }
- }
- 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 = new ScheduleTask()
- {
- roomId = courseTaskInsert.roomId,
- groupId = courseTaskInsert.groupId,
- type = courseTaskInsert.type,
- teacherId = courseTaskInsert.teacherId,
- times = new List<ScheduleTime>(),
- school = courseTaskInsert.school,
- };
- courseTask.schedules.Add(scheduleTask);
- }
- else
- {
- scheduleTask.roomId = courseTaskInsert.roomId;
- scheduleTask.school = courseTaskInsert.school;
- }
- //修改教师或名单
- if (grant_type.ToString().Equals("change-scheduleTask", StringComparison.OrdinalIgnoreCase))
- {
- if (!string.IsNullOrWhiteSpace(courseTaskInsert.teacherIdChanged))
- {
- scheduleTask.teacherId = courseTaskInsert.teacherIdChanged;
- }
- if (!string.IsNullOrWhiteSpace(courseTaskInsert.typeChanged) && !string.IsNullOrWhiteSpace(courseTaskInsert.groupIdChanged))
- {
- scheduleTask.groupId = courseTaskInsert.groupIdChanged;
- scheduleTask.type = courseTaskInsert.typeChanged;
- }
- }
- 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 });
- }
- }
- //按照模板导入进行数据转换并且进行检查
- case bool when $"{grant_type}".Equals("import-check") && $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase):
- {
- //检查完成,生成一个检查通过的token+检查结果(pass,warn,error), 在正式导入的时候,只需要检查token是否存在则进行数据保存。 以确保每次被导入的数据都是检查通过的。
- //并标记相关检查状态对于的具体数值。
- //数据转换是必须的,可选是否开启数据检查,数据检查包括导入数据自检(逻辑,排他,教室-名单-教师-时间段,重复),导入数据与数据库数据库的比对检查。
- //课程 批量升学年 学期.
- if (!request.TryGetProperty("courseCheckImports", out JsonElement _courseCheckImports)) return BadRequest();
- if (!request.TryGetProperty("periodId", out JsonElement _periodId)) return BadRequest();
- request.TryGetProperty("majorId", out JsonElement _majorId) ;
- 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 (period == null) {
- return Ok(new { code = 1, msg = "学段不存在!" });
- }
- List<CourseCheckImport> courseCheckImports= _courseCheckImports.ToObject<List<CourseCheckImport>>();
- //数据检查
- //1.检查导入的课程名称是否有效
- StringBuilder sqlName = new StringBuilder(" select value c from c ");
- sqlName.Append($" where c.name in({string.Join(",", courseCheckImports.Select(z=>$"'{z.name}'"))}) and c.period.id='{_periodId}' ");
- if (!string.IsNullOrWhiteSpace($"{_majorId}"))
- {
- var major = period.majors.Find(z => z.id.Equals($"{_majorId}"));
- if (major==null) {
- return Ok(new { code = 2, msg = "专业不存在!" });
- }
- sqlName.Append($" and c.major.id='{_majorId}'");
- }
- List<CourseBase> courseBases = new List<CourseBase>() ;
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
- .GetItemQueryIterator<CourseBase>(queryText: sqlName.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"CourseBase-{school}") }))
- {
- courseBases.Add(item);
- }
- HashSet<CourseCheckImport> courseInvalidImports = new HashSet<CourseCheckImport>();
- var nameInvalidImports = courseCheckImports.ExceptBy(courseBases.Select(x => x.name),z=>z.name);
- //保留课程名称存在的排课信息
- if (nameInvalidImports != null && nameInvalidImports.Any())
- {
- foreach (var nameInvalidImport in nameInvalidImports)
- {
- nameInvalidImport.invalidCode =1;
- courseInvalidImports.Add(nameInvalidImport);
- }
- courseCheckImports.RemoveAll(z=> nameInvalidImports.Contains(z));
- }
- //2.检查导入的醍摩豆教师ID是否有效
- StringBuilder sqlTmdid = new StringBuilder(" select c.id,c.name ,c.code ,c.picture from c ");
- sqlTmdid.Append($" where c.id in({string.Join(",", courseCheckImports.Select(z => $"'{z.tmdid}'"))}) ");
- List<IdNameCode> teachers = new List<IdNameCode>();
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
- .GetItemQueryIterator<IdNameCode>(queryText: sqlTmdid.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
- {
- teachers.Add(item);
- }
- var tmdidInvalidImports = courseCheckImports.ExceptBy(teachers.Select(x => x.id), z => z.tmdid);
- //保留课程名称存在的及醍摩豆ID有效的排课信息
- if (tmdidInvalidImports != null && tmdidInvalidImports.Any())
- {
- foreach (var tmdidInvalidImport in tmdidInvalidImports)
- {
- tmdidInvalidImport.invalidCode = 2;
- courseInvalidImports.Add(tmdidInvalidImport);
- }
- courseCheckImports.RemoveAll(z => tmdidInvalidImports.Contains(z));
- }
- //3.检查导入的教学班名称是否有效
- IEnumerable<CourseCheckImport> teachInvalidImports = null;
- List<GroupList> groupLists = new List<GroupList>();
- var teachList = courseCheckImports.Where(x => x.type.Equals("teach"));
- if (teachList.Any() && teachList.Count()>0) {
- StringBuilder sqlTeach = new StringBuilder(" select value c from c ");
- sqlTeach.Append($" where c.name in({string.Join(",", teachList.Select(z => $"'{z.list}'"))}) ");
-
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
- .GetItemQueryIterator<GroupList>(queryText: sqlTeach.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"GroupList-{school}") }))
- {
- groupLists.Add(item);
- }
- teachInvalidImports = courseCheckImports.ExceptBy(groupLists.Select(x => x.name), z => z.list);
- //保留课程名称存在的及醍摩豆ID有效的排课信息
- if (teachInvalidImports != null && teachInvalidImports.Any())
- {
- foreach (var teachInvalidImport in teachInvalidImports)
- {
- teachInvalidImport.invalidCode = 3;
- courseInvalidImports.Add(teachInvalidImport);
- }
- courseCheckImports.RemoveAll(z => teachInvalidImports.Contains(z));
- }
- }
- //4.检查导入的教室编号是否有效
- //获取填写了教室编号的数据
- var roomNos= courseCheckImports.Where(z => !string.IsNullOrWhiteSpace(z.roomNo));
- IEnumerable<CourseCheckImport> roomNoInvalidImports = null;
- List<Room> rooms = new List<Room>();
- if (roomNos.Any() && roomNos.Count() > 0)
- {
- StringBuilder sqlRoom = new StringBuilder(" select value c from c ");
- sqlRoom.Append($" where c.no in({string.Join(",", roomNos.Select(z => $"'{z.roomNo}'"))}) ");
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
- .GetItemQueryIterator<Room>(queryText: sqlRoom.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Room-{school}") }))
- {
- rooms.Add(item);
- }
- roomNoInvalidImports = courseCheckImports.ExceptBy(rooms.Select(x => x.no), z => z.roomNo);
- //保留课程名称存在的及醍摩豆ID有效的排课信息
- if (roomNoInvalidImports != null && roomNoInvalidImports.Any())
- {
- foreach (var roomNoInvalidImport in roomNoInvalidImports)
- {
- roomNoInvalidImport.invalidCode = 4;
- courseInvalidImports.Add(roomNoInvalidImport);
- }
- courseCheckImports.RemoveAll(z => roomNoInvalidImports.Contains(z));
- }
- }
- //5.检查开学日期,行政班编号是否有效
- //List<CourseCheckImport> stimeInvalidImports = new List<CourseCheckImport>() ;
- //List<CourseCheckImport> etimeInvalidImports = new List<CourseCheckImport>();
- //List<CourseCheckImport> scheduleInvalidImports = new List<CourseCheckImport>();
- //List<CourseCheckImport> classIdNoInvalidImports = new List<CourseCheckImport>();
- Dictionary<string,List<Class>> duplicateClasses= new Dictionary<string, List<Class>>();
- //1 上课时间段的
- var timeTables = period.timetable.Where(z => z.type.Equals("1")).ToList();
- HashSet< CourseTask > courseTasks = new HashSet<CourseTask>();
- int checkedCount = 0;
- foreach (var item in courseCheckImports)
- {
- DateTimeOffset sdateTime = default;
- DateTimeOffset edateTime = default;
-
- //5.1.检查开学日期格式是否正确
- if (!DateTimeOffset.TryParseExact(item.stime, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out sdateTime))
- {
- item.invalidCode = 5;
- courseInvalidImports.Add(item);
- continue;
- }
- //获取当前学年,当前学期,当前导入时间的日期,以及下学期开学时间
- (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) info = SchoolService.GetSemester(period, item.stime);
- if (info.currSemester != null)
- {
- //5.2检查课程结束日期格式是否正确
- if (!string.IsNullOrWhiteSpace(item.etime))
- {
- if (!DateTimeOffset.TryParseExact(item.etime, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out edateTime))
- {
- item.invalidCode = 6;
- courseInvalidImports.Add(item);
- continue;
- }
- }
- else
- {
- //未设置课程结束时间,开学前一天
- edateTime = info.nextSemester.AddDays(-1);
- }
- }
- else {
- //15.根据开学时间无法获取学期信息
- item.invalidCode = 15;
- courseInvalidImports.Add(item);
- continue;
- }
- ScheduleTime scheduleTime = null;
- //5.3检查排课字段格式,数据是否符合要求
- if (!string.IsNullOrWhiteSpace(item.schedule)) {
- string[] datas= item.schedule.Split('-');
-
- if (datas.Length >= 3) {
- int timeIndex = -1;
- int weekIndex = -1;
- string mode =string.Empty;
- if (int.TryParse(datas[0], out timeIndex) && timeIndex > 0
- && int.TryParse(datas[1], out weekIndex) && weekIndex > 0
- && (datas[2].Equals("A", StringComparison.OrdinalIgnoreCase) || datas[2].Equals("D", StringComparison.OrdinalIgnoreCase) || datas[2].Equals("C", StringComparison.OrdinalIgnoreCase)))
- {
- mode = datas[2];
- HashSet<int> weekIndexs = new HashSet<int>();
- if (mode.Equals("C"))
- {
- if (datas.Length == 4)
- {
- var customWeeks = datas[3].Split(',');
- bool hasInvalidData = false;
- HashSet<int> weeks = new HashSet<int>();
- foreach (var customWeek in customWeeks)
- {
- if (int.TryParse(customWeek, out int customWeekIndex) && customWeekIndex > 0)
- {
- weeks.Add(customWeekIndex);
- }
- else {
- hasInvalidData = true;
- break;
- }
- }
- if (hasInvalidData)
- {
- //C 自定义模式下,配置的上课周是大于等于1的整数
- item.invalidCode = 11;
- courseInvalidImports.Add(item);
- continue;
- }
- else {
- weekIndexs = weeks;
- }
- }
- else {
- //C 自定义模式下,需要配置对应的上课周
- item.invalidCode = 10;
- courseInvalidImports.Add(item);
- continue;
- }
- }
- scheduleTime = new ScheduleTime();
- try {
- var timeTable = timeTables[timeIndex-1];
- scheduleTime.id= timeTable.id;
- }
- catch (Exception ex)
- {
- //数组越界,表示导入的不存在,没有对应的上课时间段
- item.invalidCode = 8;
- courseInvalidImports.Add(item);
- continue;
- }
- try
- {
- var week = weekDays[weekIndex - 1];
- scheduleTime.week = week;
- }
- catch (Exception ex)
- {
- //数组越界,表示导入的不存在
- //上课时间不在星期一至星期日
- item.invalidCode = 9;
- courseInvalidImports.Add(item);
- continue;
- }
- scheduleTime.mode= mode;
- scheduleTime.index = weekIndexs;
- }
- else {
- //不满足最基本的1-1-A格式,可能是不是数字,或者不是A,D,C模式,
- //排课时间格式不满足[1-n]-[1|2|3|4|5|6|7]-[A|D|C]
- item.invalidCode = 7;
- courseInvalidImports.Add(item);
- continue;
- }
- }
- else
- {
- //不满足最基本的1-1-A格式
- //排课时间格式不满足[1-n]-[1|2|3|4|5|6|7]-[A|D|C]
- item.invalidCode = 7;
- courseInvalidImports.Add(item);
- continue;
- }
- }
- string groupId = string.Empty;
- //5.4 检查导入的行政班编号是否有效
- if (item.type.Equals("class"))
- {
- var yearNo = item.list.Split("-");
- if (yearNo.Length == 2)
- {
- StringBuilder sqlYearNo = new StringBuilder(" select value c from c ");
- sqlYearNo.Append($" where c.year ={yearNo[0]} and c.no ='{yearNo[1]}' and c.periodId='{period.id}' ");
- List<Class> classes = new List<Class>();
- await foreach (var classInfo in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
- .GetItemQueryIterator<Class>(queryText: sqlYearNo.ToString(), requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Class-{school}") }))
- {
- classes.Add(classInfo);
- }
- if (classes.Count > 1)
- {
- ///班级入学年-编号重复的班级
- duplicateClasses.Add(item.list, classes);
- //导入的班级入学年-编号在系统中重复,请检查行政班设置。
- item.invalidCode = 13;
- courseInvalidImports.Add(item);
- continue;
- }
- else if (classes.Count <= 0)
- {
- //班级入学年-编号不存在
- item.invalidCode = 12;
- courseInvalidImports.Add(item);
- continue;
- }
- else
- {
- Class @class = classes[0];
- groupId = @class.id;
- }
- }
- else
- {
- courseInvalidImports.Add(item);
- //导入的班级入学年-编号格式错误
- item.invalidCode = 14;
- continue;
- }
- }
- else {
- var groupList= groupLists.Find(z => z.name.Equals(item.list));
- groupId=groupList?.id;
- }
- 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;
- CourseBase courseBase = courseBases.Find(z => z.name.Equals(item.name));
- 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));
- if (courseTaskResponse.Status == 200) {
- courseTask = JsonDocument.Parse(courseTaskResponse.Content).RootElement.ToObject<CourseTask>();
- }
- }
- if (courseTask == null)
- {
- courseTask = new CourseTask()
- {
- id = taskId,
- code = taskCode,
- expire = edateTime.ToUnixTimeMilliseconds(),
- pk = "CourseTask",
- ttl = -1,
- courseId = courseBase.id,
- year = info.studyYear,
- semesterId = info.currSemester.id,
- schedules = new List<ScheduleTask>
- {
- new ScheduleTask()
- {
- roomId=roomId,
- groupId=groupId,
- type=item.type,
- teacherId=teacherId,
- times= new List<ScheduleTime> { scheduleTime },
- school=school,
- }
- }
- };
- 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)
- {
- courseTask.schedules.Add(new ScheduleTask()
- {
- roomId = roomId,
- groupId = groupId,
- type = item.type,
- teacherId = teacherId,
- times = new List<ScheduleTime> { scheduleTime },
- school = school,
- });
- }
- else {
- 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));
- if (shtime == null)
- {
- scheduleTask.times.Add(scheduleTime);
- }
- else {
- if (scheduleTime.index.Any())
- {
- foreach (var ind in scheduleTime.index) {
- shtime.index.Add(ind);
- }
- }
- }
- }
- }
- }
- checkedCount++;
- }
- //生成检查结果token,有效期5分钟
- string checkToken=$"CourseTask:CheckToken:{scope}:{school}:{Guid.NewGuid()}" ;
- await _azureRedis.GetRedisClient(8).StringSetAsync(checkToken, courseTasks.ToJsonString(),expiry:new TimeSpan(0,5,0));
- return Ok(new { courseCheckedImports = courseTasks , checkedCount, invalidCount= courseInvalidImports.Count, courseInvalidImports, checkToken });
- }
- case bool when $"{grant_type}".Equals("import-task", StringComparison.OrdinalIgnoreCase) && $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase):
- {
- request.TryGetProperty("checkToken", out JsonElement _checkToken);
- if (!string.IsNullOrWhiteSpace($"{_checkToken}") && $"{_checkToken}".StartsWith($"CourseTask:CheckToken:{scope}:{school}:"))
- {
- RedisValue value = await _azureRedis.GetRedisClient(8).StringGetAsync($"{_checkToken}");
- List<CourseTask> courseTasks = value.ToString().ToObject<List<CourseTask>>();
- if (courseTasks.IsNotEmpty())
- {
- foreach (var task in courseTasks)
- {
- await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(task, new PartitionKey(task.code));
- }
- return Ok(new { code=200 });
- }
- }
- return BadRequest();
- }
- }
- } catch (Exception ex) {
- await _dingDing.SendBotMsg($"{_option.Location},课程处理异常,{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
- }
- return Ok();
- }
- }
-
- }
|