|
@@ -6,7 +6,9 @@ using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Azure.Amqp.Framing;
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
+using NUnit.Framework;
|
|
|
using OfficeOpenXml;
|
|
|
+using OpenXmlPowerTools;
|
|
|
using StackExchange.Redis;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
@@ -59,15 +61,67 @@ namespace TEAMModelOS.Controllers
|
|
|
_configuration = configuration;
|
|
|
_httpTrigger = httpTrigger;
|
|
|
}
|
|
|
+ // [AuthToken(Roles = "teacher,admin")]
|
|
|
+ [HttpPost("read-excel-virtue")]
|
|
|
+ //[Authorize(Roles = "IES")]
|
|
|
+ [AuthToken(Roles = "teacher,admin,business")]
|
|
|
+ [RequestSizeLimit(102_400_000_00)] //最大10000m左右
|
|
|
+ public async Task<IActionResult> ReadExcelVirtue([FromForm] IFormFile file, [FromForm] string periodId) {
|
|
|
+ List<KeyValuePair<string, List<string>>> error = new List<KeyValuePair<string, List<string>>>();
|
|
|
+ List<KeyValuePair<string, List<string>>> warn = new List<KeyValuePair<string, List<string>>>();
|
|
|
+ var (id, _, _, school) = HttpContext.GetAuthTokenInfo();
|
|
|
+ ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
|
|
+ List<VirtueImport> virtueImports = new List<VirtueImport> { };
|
|
|
+ using (ExcelPackage package = new ExcelPackage(file.OpenReadStream())) {
|
|
|
+ ExcelWorksheets sheet = package.Workbook.Worksheets;
|
|
|
+ //德育数据导入
|
|
|
+ School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new Azure.Cosmos.PartitionKey("Base"));
|
|
|
+ Period period = schoolBase.period.Find(x => x.id.Equals(periodId));
|
|
|
+ var daily_sheets = sheet.Where(z => !z.Name.Equals("栏位说明"));
|
|
|
+ HashSet<IdNameCode> rightStudents = new HashSet<IdNameCode>();
|
|
|
+ List<Class> classes = new List<Class>();
|
|
|
+ foreach (var daily_sheet in daily_sheets)
|
|
|
+ {
|
|
|
+ if (DateTimeOffset.TryParse(daily_sheet.Name, out DateTimeOffset sheetNameTime))
|
|
|
+ {
|
|
|
|
|
|
+ var data = GetSubSheetData(daily_sheet, error);
|
|
|
+ Dictionary<string, object> dailyData = new Dictionary<string, object> { { "subject", "德育" }, { "students", data.students } };
|
|
|
+ ImportExamSubject importExamDaily = dailyData.ToJsonString().ToObject<ImportExamSubject>();
|
|
|
+ var subject = period.subjects.Find(z => z.name.Equals(importExamDaily.subject));
|
|
|
+ if (subject != null)
|
|
|
+ {
|
|
|
+ List<ResultImportStudent> examImportStudents = new List<ResultImportStudent>();
|
|
|
+ //学生
|
|
|
+ await ExamImportStudent(importExamDaily.students, rightStudents, school, period, examImportStudents, error, warn, classes, daily_sheet.Name);
|
|
|
+
|
|
|
+ VirtueImport virtueImport = new VirtueImport {
|
|
|
+ time = sheetNameTime.ToUnixTimeMilliseconds(),
|
|
|
+ id = $"{}",
|
|
|
+ students = examImportStudents
|
|
|
+ };
|
|
|
+ virtueImport.students.AddRange(examImportStudents);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("subject_invalid", new List<string> { importExamDaily.subject }));// 科目不存在
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Ok(new { virtueImports, error,warn});
|
|
|
+ }
|
|
|
// [AuthToken(Roles = "teacher,admin")]
|
|
|
- [HttpPost("read-excel")]
|
|
|
+ [HttpPost("read-excel-exam")]
|
|
|
//[Authorize(Roles = "IES")]
|
|
|
[AuthToken(Roles = "teacher,admin,business")]
|
|
|
[RequestSizeLimit(102_400_000_00)] //最大10000m左右
|
|
|
public async Task<IActionResult> ReadExcel([FromForm] IFormFile file,[FromForm] string periodId) {
|
|
|
- List<string> error = new List<string>();
|
|
|
- List<string> warn = new List<string>();
|
|
|
+ List<KeyValuePair<string, List<string>>> error = new List<KeyValuePair<string, List<string>>>();
|
|
|
+ List<KeyValuePair<string, List<string>>> warn = new List<KeyValuePair<string, List<string>>>();
|
|
|
var (id, _, _, school) = HttpContext.GetAuthTokenInfo();
|
|
|
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
|
|
using (ExcelPackage package = new ExcelPackage(file.OpenReadStream()))
|
|
@@ -166,8 +220,8 @@ namespace TEAMModelOS.Controllers
|
|
|
item.Add(itemTitle[j], index);
|
|
|
}
|
|
|
else {
|
|
|
- error.Add("index_invalid");// 题目序列只能是正整数
|
|
|
- return Ok(new { code = 400, error, data = itemDatas[i][j] });
|
|
|
+
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("index_invalid",new List<string> { itemDatas[i][j] } ));// 题目序列只能是正整数
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -182,8 +236,7 @@ namespace TEAMModelOS.Controllers
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- error.Add("score_invalid");// 配分只能是数字
|
|
|
- return Ok(new { code = 400, error, data = itemDatas[i][j] });
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("score_invalid", new List<string> { itemDatas[i][j] }));// 配分只能是数字
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -201,198 +254,296 @@ namespace TEAMModelOS.Controllers
|
|
|
foreach (var subject in subjects) {
|
|
|
|
|
|
var subject_sheet = sheet.Where(z => z.Name.StartsWith($"Sub_{subject}")).FirstOrDefault();
|
|
|
- var data = GetSubSheetData(subject_sheet);
|
|
|
+ var data = GetSubSheetData(subject_sheet,error);
|
|
|
var items = itemInfo.FindAll(x => x["subject"].Equals(subject));
|
|
|
- if (data.error.Any()) {
|
|
|
- return Ok(new { code = 400, error= data.error, data = data.errorData});
|
|
|
- }
|
|
|
+
|
|
|
Dictionary<string, object> subjectData = new Dictionary<string, object> { { "subject", subject } ,{ "items",items },{ "students", data.students } };
|
|
|
subjectDatas.Add(subjectData);
|
|
|
}
|
|
|
}
|
|
|
- //德育数据导入
|
|
|
- {
|
|
|
- var subject_sheet = sheet.Where(z => z.Name.StartsWith($"Sub_德育")).FirstOrDefault();
|
|
|
- var data = GetSubSheetData(subject_sheet);
|
|
|
- if (data.error.Any())
|
|
|
- {
|
|
|
- return Ok(new { code = 400, error= data.error, data = data.errorData });
|
|
|
- }
|
|
|
- Dictionary<string, object> subjectData = new Dictionary<string, object> { { "subject", "德育" }, { "students", data.students } };
|
|
|
- subjectDatas.Add(subjectData);
|
|
|
- }
|
|
|
+
|
|
|
baseInfo.Add("periodId", periodId);
|
|
|
baseInfo.Add("school", school);
|
|
|
baseInfo.Add("subjects", subjectDatas);
|
|
|
var importExam =baseInfo.ToJsonString().ToObject<ImportExam>();
|
|
|
var validData = importExam.Valid();
|
|
|
- if (!validData.isVaild)
|
|
|
+ ExamImport examImport = null;
|
|
|
+ if (validData.isVaild)
|
|
|
{
|
|
|
- return Ok(new { code = 400, error = validData.errors.SelectMany(z => z.Value).ToList() });
|
|
|
+ string sql = $"select value c from c where c.name ='{importExam.name}'";
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<ExamImport>(sql, $"ExamImport-{importExam.school}", pageSize: 1);
|
|
|
+
|
|
|
+ if (string.IsNullOrEmpty(result.continuationToken))
|
|
|
+ {
|
|
|
+ warn.Add(new KeyValuePair<string, List<string>>("name_duplicate", new List<string> { importExam.name }));//评测名称重复
|
|
|
+ }
|
|
|
+ if (result.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ examImport = result.list[0];
|
|
|
+ warn.Add(new KeyValuePair<string, List<string>>("name_update", new List<string> { importExam.name }));//同名评测数据更新
|
|
|
+
|
|
|
+ }
|
|
|
+ if (examImport == null)
|
|
|
+ {
|
|
|
+ examImport = new ExamImport { name = importExam.name, type = importExam.type, school = importExam.school };
|
|
|
+ if (DateTimeOffset.TryParse(importExam.time, out DateTimeOffset dateTime))
|
|
|
+ {
|
|
|
+ examImport.time = dateTime.ToUnixTimeMilliseconds();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("time_format", new List<string> { importExam.time }));// 时间格式错误
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(importExam.school, new Azure.Cosmos.PartitionKey("Base"));
|
|
|
+ Period period = schoolBase.period.Find(x => x.id.Equals(importExam.periodId));
|
|
|
+
|
|
|
+ if (period != null)
|
|
|
+ {
|
|
|
+ //用于处理多学科,不需要重复查询学习基础信息
|
|
|
+ //id 学生id code 行政班id name 学生姓名
|
|
|
+ HashSet<IdNameCode> rightStudents = new HashSet<IdNameCode>();
|
|
|
+ List<Class> classes = new List<Class>();
|
|
|
+ foreach (var item in importExam.subjects)
|
|
|
+ {
|
|
|
+ var subject = period.subjects.Find(z => z.name.Equals(item.subject));
|
|
|
+ if (subject != null)
|
|
|
+ {
|
|
|
+ List<ResultImportStudent> examImportStudents = new List<ResultImportStudent>();
|
|
|
+ //学生
|
|
|
+ await ExamImportStudent(item.students, rightStudents, school, period, examImportStudents, error, warn, classes, item.subject);
|
|
|
+
|
|
|
+ examImport.subjects.Add(new ExamImportSubject { id = subject.id, name = subject.name, students = examImportStudents, }) ;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("subject_invalid", new List<string> { item.subject }));// 科目不存在
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("period_invalid",new List<string> { importExam.periodId }));// 学段不存在
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- string sql = $"select value c from c where c.name ='{importExam.name}'";
|
|
|
- var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<ExamImport>(sql, $"ExamImport-{importExam.school}", pageSize: 1);
|
|
|
- ExamImport examImport = null;
|
|
|
- if (string.IsNullOrEmpty(result.continuationToken))
|
|
|
+ else {
|
|
|
+ validData.errors.SelectMany(z => z.Value).ToList().ForEach(x => {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>(x, new List<string> { }));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ List<KeyValuePair<string, HashSet<string>>> errorData = new List<KeyValuePair<string, HashSet<string>>>();
|
|
|
+ error.ForEach(x => {
|
|
|
+ var value = errorData.Find(z => z.Key.Equals(x.Key));
|
|
|
+ if (!string.IsNullOrWhiteSpace(value.Key))
|
|
|
+ {
|
|
|
+ x.Value.ForEach(z => { value.Value.Add(z); });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ errorData.Add(new KeyValuePair<string, HashSet<string>>(x.Key,x.Value.ToHashSet()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return Ok(new { code = 400, error = errorData, examImport });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task ExamImportStudent(List<ImportResultStudent> importExamStudents, HashSet<IdNameCode> rightStudents,string school,
|
|
|
+ Period period, List<ResultImportStudent> examImportStudents, List<KeyValuePair<string, List<string>>> error,
|
|
|
+ List<KeyValuePair<string, List<string>>> warn, List<Class> classes, string sheetName)
|
|
|
+ {
|
|
|
+ // 学号确定的学生
|
|
|
+ var hasIdStudents = importExamStudents.Where(z => !string.IsNullOrWhiteSpace(z.id));
|
|
|
+ var needSearch = hasIdStudents.ExceptBy(rightStudents.Select(x => x.id), hasId => hasId.id).ToList();
|
|
|
+ List<ImportResultStudent> notExistIds = new List<ImportResultStudent>();
|
|
|
+ //通过id在数据库和rightStudents 都找不到的学生
|
|
|
+ List<ImportResultStudent> evenNotExistIds = new List<ImportResultStudent>();
|
|
|
+ if (needSearch.Any())
|
|
|
+ {
|
|
|
+ ///在rightStudents找不到的学生需要查询数据库。
|
|
|
+ string stuidsql = $"select c.id,c.classId as code , c.name from c where c.id in ({string.Join(",", needSearch.Select(x => $"'{x.id}'"))}) and c.periodId='{period.id}' ";
|
|
|
+ var sturesult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<IdNameCode>(stuidsql, $"Base-{school}");
|
|
|
+ if (sturesult.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ sturesult.list.ForEach(x => {
|
|
|
+ var exist = rightStudents.Where(y => y.id.Equals(x.id));
|
|
|
+ if (!exist.Any())
|
|
|
+ {
|
|
|
+ rightStudents.Add(x);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //needSearch与 sturesult.list(数据库)查找的对比,仍然没有找到的学生。
|
|
|
+ var notInDb = needSearch.ExceptBy(sturesult.list.Select(x => x.id), y => y.id);
|
|
|
+ if (notInDb.Any())
|
|
|
+ {
|
|
|
+ evenNotExistIds.AddRange(notInDb);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- warn.Add("name_duplicate");//评测名称重复
|
|
|
+ evenNotExistIds.AddRange(needSearch);
|
|
|
}
|
|
|
- if (result.list.IsNotEmpty())
|
|
|
+ }
|
|
|
+ foreach (var item in hasIdStudents)
|
|
|
+ {
|
|
|
+ var existStudent = rightStudents.Where(n => n.id.Equals(item.id));
|
|
|
+ if (existStudent .Any())
|
|
|
{
|
|
|
- examImport = result.list[0];
|
|
|
- warn.Add("name_update");//同名评测数据更新
|
|
|
+ long time = 0;
|
|
|
+ if (DateTimeOffset.TryParse(item.time, out DateTimeOffset dateTime))
|
|
|
+ {
|
|
|
+ time = dateTime.ToUnixTimeMilliseconds();
|
|
|
+ }
|
|
|
+ examImportStudents.Add(new ResultImportStudent
|
|
|
+ {
|
|
|
+ id = item.id,
|
|
|
+ name = existStudent.First().name,
|
|
|
+ classId = existStudent.First().code,
|
|
|
+ score = item.score,
|
|
|
+ scores = item.scores,
|
|
|
+ time = time,
|
|
|
+ items = item.items,
|
|
|
+ });
|
|
|
}
|
|
|
- if (examImport == null)
|
|
|
+ }
|
|
|
+ //id信息在数据库找不到的 且班级和姓名不全,
|
|
|
+ var hasNameClassid = evenNotExistIds.Where(x => !string.IsNullOrWhiteSpace(x.name) && !string.IsNullOrWhiteSpace(x.classId));
|
|
|
+ var notexistStudent = evenNotExistIds.Except(hasNameClassid);
|
|
|
+ if (notexistStudent.Any())
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("student_notexist", notexistStudent.Select(x => $"id:{x.id}_name:{x.name}_classId:{x.classId}").ToList()));//没有班级和姓名不全,且id信息在数据库找不到的
|
|
|
+ }
|
|
|
+ //没有学号 ,且姓名和班级信息不全的
|
|
|
+ var studentInvalid = importExamStudents.Where(z => string.IsNullOrWhiteSpace(z.id) && (string.IsNullOrWhiteSpace(z.name) || string.IsNullOrWhiteSpace(z.classId)));
|
|
|
+ if (studentInvalid.Any())
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("student_invalid", studentInvalid.Select(x => $"id:{x.id}_name:{x.name}_classId:{x.classId}").ToList()));// 学生信息不全
|
|
|
+ }
|
|
|
+ //没有id ,但是存在姓名和班级信息
|
|
|
+ var classesStu = importExamStudents.Where(z => !string.IsNullOrWhiteSpace(z.classId) && !string.IsNullOrWhiteSpace(z.name) && string.IsNullOrWhiteSpace(z.id)).ToHashSet();
|
|
|
+ if (hasNameClassid.Any())
|
|
|
+ {
|
|
|
+ hasNameClassid.ToList().ForEach(x => classesStu.Add(x));
|
|
|
+ }
|
|
|
+ var group = classesStu.GroupBy(x => x.classId);
|
|
|
+
|
|
|
+ //不能被拆分的以班级名称查找。
|
|
|
+ foreach (var classGroupStudents in group)
|
|
|
+ {
|
|
|
+ Class clzz = null;
|
|
|
+ bool isClassName = false;
|
|
|
+ string className = string.Empty;
|
|
|
+ var cls = classGroupStudents.Key.Split("-");
|
|
|
+ var classStudents = classGroupStudents.ToList();
|
|
|
+ var duplicateStudents = new List<ImportResultStudent>();
|
|
|
+ classStudents.GroupBy(z => z.name).Select(z => new { key = z.Key, list = z.ToList() }).ToList().ForEach(y => {
|
|
|
+ if (y.list.Count > 1)
|
|
|
+ {
|
|
|
+ duplicateStudents.AddRange(y.list);
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("stuname_duplicate", y.list.Select(z => $"{sheetName}-{z.name}").ToList()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (duplicateStudents.IsNotEmpty())
|
|
|
+ {
|
|
|
+ duplicateStudents.ForEach(z => { classStudents.Remove(z); });
|
|
|
+ }
|
|
|
+ if (cls.Length == 2 && int.TryParse(cls[0], out int year) && year > 2000 && int.TryParse(cls[1], out int no) && no > 0)
|
|
|
{
|
|
|
- examImport = new ExamImport { name = importExam.name, type = importExam.type, school = importExam.school };
|
|
|
- if (DateTimeOffset.TryParse(importExam.time, out DateTimeOffset dateTime))
|
|
|
+
|
|
|
+ var existInTemp = classes.FindAll(z => z.year == year && z.no.Equals(cls[1]));
|
|
|
+ if (existInTemp.Any())
|
|
|
{
|
|
|
- examImport.time = dateTime.ToUnixTimeMilliseconds();
|
|
|
+ clzz = existInTemp.First();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- error.Add("time_format");// 时间格式错误
|
|
|
- return Ok(new { code = 400, error,data=new List<string>() { importExam.time } });
|
|
|
+ string sqlClazz = $"select value c from c where c.year={year} and c.no ='{cls[1]}' and c.periodId='{period.id}' ";
|
|
|
+ var classresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sqlClazz, $"Class-{school}", pageSize: 1);
|
|
|
+ if (classresult.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ clzz = classresult.list[0];
|
|
|
+ classes.Add(clzz);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ className = classGroupStudents.Key;
|
|
|
+ isClassName = true;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(importExam.school, new Azure.Cosmos.PartitionKey("Base"));
|
|
|
- Period period = schoolBase.period.Find(x => x.id.Equals(importExam.periodId));
|
|
|
-
|
|
|
- if (period != null)
|
|
|
- {
|
|
|
- //用于处理多学科,不需要重复查询学习基础信息
|
|
|
- //id 学生id code 行政班id name 学生姓名
|
|
|
- HashSet<IdNameCode> rightStudents = new HashSet<IdNameCode>();
|
|
|
- foreach (var item in importExam.subjects)
|
|
|
+ else
|
|
|
+ {
|
|
|
+ className = classGroupStudents.Key;
|
|
|
+ isClassName = true;
|
|
|
+ }
|
|
|
+ if (isClassName)
|
|
|
+ {
|
|
|
+ var existInTemp = classes.FindAll(z => z.name.Equals(className));
|
|
|
+ if (existInTemp.Any())
|
|
|
{
|
|
|
- var subject = period.subjects.Find(z => z.name.Equals(item.subject));
|
|
|
- if (subject != null)
|
|
|
+ clzz = existInTemp.First();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ string sqlClazz = $"select value c from c where c.name ='{className}' and c.periodId='{period.id}' ";
|
|
|
+ var classresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sqlClazz, $"Class-{school}", pageSize: 1);
|
|
|
+ if (classresult.list.IsNotEmpty())
|
|
|
{
|
|
|
- List<ExamImportStudent> examImportStudents = new List<ExamImportStudent>();
|
|
|
- //学生
|
|
|
+ clzz = classresult.list[0];
|
|
|
+ classes.Add(clzz);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("class_invalid", new List<string> { $"{sheetName}-{className}" }));// 班级错误
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (clzz != null)
|
|
|
+ {
|
|
|
+ string stuClassIdsql = $"select c.id,c.classId as code , c.name from c where c.name in ({string.Join(",", classStudents.Select(x => $"'{x.name}'"))}) and c.classId ='{clzz.id}' and c.periodId='{period.id}' ";
|
|
|
+ var sturesult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<IdNameCode>(stuClassIdsql, $"Base-{school}");
|
|
|
+ //检查重名
|
|
|
+ if (sturesult.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ var groupNames = sturesult.list.GroupBy(x => x.name).Select(x => new { key = x.Key, list = x.ToList() }).Where(y => y.list.Count > 1);
|
|
|
+ if (groupNames.Any())
|
|
|
+ {
|
|
|
+ warn.Add(new KeyValuePair<string, List<string>>("stuname_duplicate", groupNames.Select(x => $"{sheetName}-{x.key}").ToList()));//学生姓名重复
|
|
|
+ }
|
|
|
+ foreach (var stu in classesStu)
|
|
|
+ {
|
|
|
+ var student = sturesult.list.FindAll(x => x.name.Equals(stu.name));
|
|
|
+ if (student.Any())
|
|
|
{
|
|
|
- // 学号确定的学生
|
|
|
- var hasIdStudents = item.students.Where(z => !string.IsNullOrWhiteSpace(z.id));
|
|
|
- var needSearch = hasIdStudents.ExceptBy(rightStudents.Select(x => x.id), hasId => hasId.id);
|
|
|
- List<ImportExamStudent> notExistIds = new List<ImportExamStudent>();
|
|
|
- //通过id在数据库和rightStudents 都找不到的学生
|
|
|
- List<ImportExamStudent> evenNotExistIds = new List<ImportExamStudent>();
|
|
|
- if (needSearch.Any())
|
|
|
- {
|
|
|
- ///在rightStudents找不到的学生需要查询数据库。
|
|
|
- string stuidsql = $"select c.id,c.classId as code , c.name from c where c.id in ({needSearch.Select(x => $"'{x.id}'")}) and c.periodId='{period.id}' ";
|
|
|
- var sturesult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<IdNameCode>(stuidsql, $"Base-{school}");
|
|
|
- if (sturesult.list.IsNotEmpty())
|
|
|
- {
|
|
|
- sturesult.list.ForEach(x => {
|
|
|
- var exist = rightStudents.Where(x => x.id.Equals(x.id));
|
|
|
- if (!exist.Any())
|
|
|
- {
|
|
|
- rightStudents.Add(x);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- var existStudent = needSearch.Where(n => n.id.Equals(x.id)).FirstOrDefault();
|
|
|
- if (existStudent!=null) {
|
|
|
- long time = 0;
|
|
|
- if (DateTimeOffset.TryParse(existStudent.time, out DateTimeOffset dateTime))
|
|
|
- {
|
|
|
- time = dateTime.ToUnixTimeMilliseconds();
|
|
|
- }
|
|
|
- examImportStudents.Add(new ExamImportStudent {
|
|
|
- id = existStudent.id,
|
|
|
- name = x.name,
|
|
|
- classId = x.code,
|
|
|
- score = existStudent.score,
|
|
|
- scores = existStudent.scores,
|
|
|
- time = time
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- //needSearch与 sturesult.list(数据库)查找的对比,仍然没有找到的学生。
|
|
|
- var notInDb = needSearch.ExceptBy(sturesult.list.Select(x => x.id), y => y.id);
|
|
|
- if (notInDb.Any())
|
|
|
- {
|
|
|
- evenNotExistIds.AddRange(notInDb);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- evenNotExistIds.AddRange(needSearch);
|
|
|
- }
|
|
|
- }
|
|
|
- //id信息在数据库找不到的 且班级和姓名不全,
|
|
|
- var hasNameClassid = evenNotExistIds.Where(x => !string.IsNullOrWhiteSpace(x.name) && !string.IsNullOrWhiteSpace(x.classId));
|
|
|
- var notexistStudent = evenNotExistIds.Except(hasNameClassid);
|
|
|
- if (notexistStudent.Any())
|
|
|
- {
|
|
|
- error.Add("student_notexist");//没有班级和姓名不全,且id信息在数据库找不到的
|
|
|
- return Ok(new { code = 400, error, data = notexistStudent.Select(x => $"id:{x.id}_name:{x.name}_classId:{x.classId}") });
|
|
|
- }
|
|
|
- //没有学号 ,且姓名和班级信息不全的
|
|
|
- var studentInvalid = item.students.Where(z => string.IsNullOrWhiteSpace(z.id) && (string.IsNullOrWhiteSpace(z.name) || string.IsNullOrWhiteSpace(z.classId)));
|
|
|
- if (studentInvalid.Any())
|
|
|
- {
|
|
|
- error.Add("student_invalid");// 学生信息不全
|
|
|
- return Ok(new { code = 400, error, data = studentInvalid.Select(x => $"id:{x.id}_name:{x.name}_classId:{x.classId}") });
|
|
|
- }
|
|
|
- //没有id ,但是存在姓名和班级信息
|
|
|
- var classesStu = item.students.Where(z => !string.IsNullOrWhiteSpace(z.classId) && !string.IsNullOrWhiteSpace(z.name) && string.IsNullOrWhiteSpace(z.id)).ToHashSet();
|
|
|
- if (hasNameClassid.Any())
|
|
|
- {
|
|
|
- hasNameClassid.ToList().ForEach(x => classesStu.Add(x));
|
|
|
- }
|
|
|
- var group = classesStu.GroupBy(x => x.classId);
|
|
|
|
|
|
- //不能被拆分的以班级名称查找。
|
|
|
- HashSet<string> classNames = new HashSet<string>();
|
|
|
- foreach (var clazz in group)
|
|
|
+ long time = 0;
|
|
|
+ if (DateTimeOffset.TryParse(stu.time, out DateTimeOffset dateTime))
|
|
|
{
|
|
|
- var cls = clazz.Key.Split("-");
|
|
|
- if (cls.Length == 2 && int.TryParse(cls[0], out int year) && year > 2000 && int.TryParse(cls[1], out int no) && no > 0)
|
|
|
- {
|
|
|
- string sqlClazz = $"select value c from c where c.year={year} and c.no ='{cls[1]}' and c.periodId='{period.id}' ";
|
|
|
- var classresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<Class>(sqlClazz, $"Class-{school}");
|
|
|
- if (classresult.list.IsNotEmpty())
|
|
|
- {
|
|
|
- Class clzz = classresult.list[0];
|
|
|
- string stuClassIdsql = $"select c.id,c.classId as code , c.name from c where c.name in ({clazz.ToList().Select(x => $"'{x.name}'")}) and c.classId ='{clzz.id}' and c.periodId='{period.id}' ";
|
|
|
- var sturesult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<IdNameCode>(stuClassIdsql, $"Base-{school}");
|
|
|
- //检查重名
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- classNames.Add(clazz.Key);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- classNames.Add(clazz.Key);
|
|
|
- }
|
|
|
+ time = dateTime.ToUnixTimeMilliseconds();
|
|
|
}
|
|
|
+ examImportStudents.Add(new ResultImportStudent
|
|
|
+ {
|
|
|
+ id = student[0].id,
|
|
|
+ name = student[0].name,
|
|
|
+ classId = student[0].code,
|
|
|
+ score = stu.score,
|
|
|
+ scores = stu.scores,
|
|
|
+ time = time,
|
|
|
+ items = stu.items
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- error.Add("subject_invalid");// 科目不存在
|
|
|
- return Ok(new { code = 400, error, data =new List<string>() { item.subject } });
|
|
|
- }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("student_invalid", classGroupStudents.ToList().Select(x => $"{sheetName}-{x.name}").ToList()));
|
|
|
}
|
|
|
}
|
|
|
- else {
|
|
|
- error.Add("period_invalid");// 学段不存在
|
|
|
- return Ok(new { code = 400, error, data = new List<string>() { importExam.periodId } });
|
|
|
- }
|
|
|
- return Ok(new {baseInfo });
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- private (List<Dictionary<string, object>> students, HashSet<string> error, HashSet<string> errorData) GetSubSheetData(ExcelWorksheet subject_sheet) {
|
|
|
- HashSet<string> error = new HashSet<string>();
|
|
|
- HashSet<string> errorData = new HashSet<string>();
|
|
|
+
|
|
|
+ private (List<Dictionary<string, object>> students, List<KeyValuePair<string, List<string>>> error) GetSubSheetData(ExcelWorksheet subject_sheet, List<KeyValuePair<string, List<string>>> error) {
|
|
|
List<Dictionary<string, object>> students = new List<Dictionary<string, object>>();
|
|
|
List<string> titles = new List<string>();
|
|
|
List<List<string>> datas = new List<List<string>>();
|
|
@@ -461,8 +612,7 @@ namespace TEAMModelOS.Controllers
|
|
|
items.Add(new ItemVlaue() { code = titles[j].Replace("item_", ""), value = score });
|
|
|
}
|
|
|
else {
|
|
|
- error.Add("score_invalid");// 得分只能是数字
|
|
|
- errorData.Add(datas[i][j]);
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("score_invalid",new List<string> { datas[i][j] }));// 得分只能是数字
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -479,8 +629,7 @@ namespace TEAMModelOS.Controllers
|
|
|
item.Add(titles[j], 0);
|
|
|
}
|
|
|
else {
|
|
|
- error.Add("score_invalid");// 得分只能是数字
|
|
|
- errorData.Add(datas[i][j]);
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("score_invalid", new List<string> { datas[i][j] }));// 得分只能是数字
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
@@ -504,8 +653,7 @@ namespace TEAMModelOS.Controllers
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- error.Add("score_invalid");// 得分只能是数字
|
|
|
- errorData.Add(datas[i][orders[j].Value]);
|
|
|
+ error.Add(new KeyValuePair<string, List<string>>("score_invalid", new List<string> { datas[i][orders[j].Value] }));// 得分只能是数字
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -520,7 +668,7 @@ namespace TEAMModelOS.Controllers
|
|
|
students.Add(item);
|
|
|
}
|
|
|
|
|
|
- return (students,error,errorData);
|
|
|
+ return (students, error);
|
|
|
}
|
|
|
|
|
|
|