|
@@ -30,6 +30,10 @@ using TEAMModelOS.Models;
|
|
using TEAMModelOS.SDK.Models.Service;
|
|
using TEAMModelOS.SDK.Models.Service;
|
|
using TEAMModelOS.SDK.Models.Cosmos.BI.BINormal;
|
|
using TEAMModelOS.SDK.Models.Cosmos.BI.BINormal;
|
|
using TEAMModelOS.SDK.Models.Cosmos.Student;
|
|
using TEAMModelOS.SDK.Models.Cosmos.Student;
|
|
|
|
+using Microsoft.OData.Edm;
|
|
|
|
+using TEAMModelOS.Controllers.Core;
|
|
|
|
+using DocumentFormat.OpenXml.VariantTypes;
|
|
|
|
+using static TEAMModelOS.Controllers.CourseController;
|
|
|
|
|
|
namespace TEAMModelOS.Controllers
|
|
namespace TEAMModelOS.Controllers
|
|
{
|
|
{
|
|
@@ -1350,8 +1354,8 @@ namespace TEAMModelOS.Controllers
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// 查询知识
|
|
|
|
- /// [ApiToken(Auth = "1701", Name = "查询知识点",TName ="",EName ="", RWN = "R", Limit = false)]
|
|
|
|
|
|
+ /// 设置学生全面教育画像
|
|
|
|
+ ///[ApiToken(Auth = "1901", Name = "设置学生全面教育画像", TName = "設置學生全面教育畫像", EName = "Set up students overall education portrait", RWN = "W", Limit = false)]
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="_azureCosmos"></param>
|
|
/// <param name="_azureCosmos"></param>
|
|
/// <param name="_dingDing"></param>
|
|
/// <param name="_dingDing"></param>
|
|
@@ -1365,44 +1369,75 @@ namespace TEAMModelOS.Controllers
|
|
{
|
|
{
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "schoolCode为空!" };
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "schoolCode为空!" };
|
|
}
|
|
}
|
|
- if (!json.TryGetProperty("studentId", out JsonElement studentId)) {
|
|
|
|
- return responseData = new() { code = RespondCode.ParamsError, msg = "studentId为空!" };
|
|
|
|
- }
|
|
|
|
- if (!json.TryGetProperty("name", out JsonElement name)) {
|
|
|
|
- return responseData = new() { code = RespondCode.ParamsError, msg = "name为空!" };
|
|
|
|
- }
|
|
|
|
- if (!json.TryGetProperty("classId", out JsonElement classId)) {
|
|
|
|
- return responseData = new() { code = RespondCode.ParamsError, msg = "classId为空!" };
|
|
|
|
- }
|
|
|
|
- if (!json.TryGetProperty("periodId", out JsonElement periodId)) {
|
|
|
|
- return responseData = new() { code = RespondCode.ParamsError, msg = "periodId为空!" };
|
|
|
|
|
|
+ if (!json.TryGetProperty("periodId", out JsonElement periodId)) {
|
|
|
|
+ return responseData = new() { code = RespondCode.ParamsError, msg = "periodId为空!" };
|
|
}
|
|
}
|
|
if (!json.TryGetProperty("subjectId", out JsonElement subjectId)) {
|
|
if (!json.TryGetProperty("subjectId", out JsonElement subjectId)) {
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "subjectId为空!" };
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "subjectId为空!" };
|
|
}
|
|
}
|
|
- if (!json.TryGetProperty("semesterData", out JsonElement semesterData)) {
|
|
|
|
- return responseData = new() { code = RespondCode.ParamsError, msg = "semesterData为空!" };
|
|
|
|
|
|
+ if (!json.TryGetProperty("students", out JsonElement _students)) {
|
|
|
|
+ return responseData = new() { code = RespondCode.ParamsError, msg = "students为空!" };
|
|
}
|
|
}
|
|
- if(!$"{subjectId}".Equals("subject_sport") && !$"{subjectId}".Equals("subject_virtue") && !$"{subjectId}".Equals("subject_labour")
|
|
|
|
|
|
+ if (!$"{subjectId}".Equals("subject_sport") && !$"{subjectId}".Equals("subject_virtue") && !$"{subjectId}".Equals("subject_labour")
|
|
&& !$"{subjectId}".Equals("subject_music") && !$"{subjectId}".Equals("subject_painting"))
|
|
&& !$"{subjectId}".Equals("subject_music") && !$"{subjectId}".Equals("subject_painting"))
|
|
{
|
|
{
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "当前subjectId未开放画像业务!" };
|
|
return responseData = new() { code = RespondCode.ParamsError, msg = "当前subjectId未开放画像业务!" };
|
|
}
|
|
}
|
|
- return responseData = new() { code = RespondCode.Ok, msg = "成功" };
|
|
|
|
School schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
|
|
School schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
|
|
- Period period= schoolBase.period.Find(x => x.id.Equals($"{periodId}"));
|
|
|
|
|
|
+ List<PortraitStudent> students = _students.ToObject<List<PortraitStudent>>();
|
|
|
|
+ List<(Student studentBase, PortraitStudent portrait) > studentsBases = new List<(Student, PortraitStudent)>();
|
|
|
|
+ List<PortraitStudent> unmatch=new List<PortraitStudent>();
|
|
|
|
+ string stusql = $"select c.id,c.classId,c.name from c where c.id in ({string.Join(",", students.Select(f => $"'{f.studentId}'"))})";
|
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
|
|
|
|
+ .GetItemQueryIterator<Student>(queryText: stusql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base-{schoolCode}") }))
|
|
|
|
+ {
|
|
|
|
+ var student = students.Find(x => x.studentId.Equals(item.id));
|
|
|
|
+ if ($"{item.classId}".Equals($"{student.classId}"))
|
|
|
|
+ {
|
|
|
|
+ studentsBases.Add((item,student));
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ unmatch.Add(student);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var unexist = students.FindAll(z => !studentsBases.Select(z => z.studentBase.id).Contains(z.studentId));
|
|
|
|
+ if (unexist.Any()) {
|
|
|
|
+ unmatch.AddRange(unexist);
|
|
|
|
+ }
|
|
|
|
+ Period period = schoolBase.period.Find(x => x.id.Equals($"{periodId}"));
|
|
if (period == null)
|
|
if (period == null)
|
|
{
|
|
{
|
|
return responseData = new() { code = RespondCode.NotFound, msg = "periodId不存在!" };
|
|
return responseData = new() { code = RespondCode.NotFound, msg = "periodId不存在!" };
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
|
|
+ bool periodChange = false;
|
|
|
|
+ if (!period.semesters.Any())
|
|
|
|
+ {
|
|
|
|
+ //未设置学期则默认
|
|
|
|
+ period.semesters.Add(new Semester
|
|
|
|
+ {
|
|
|
|
+ id = Guid.NewGuid().ToString(),
|
|
|
|
+ name = "第一学期",
|
|
|
|
+ start = 1,
|
|
|
|
+ month = 9,
|
|
|
|
+ day = 1
|
|
|
|
+ }); period.semesters.Add(new Semester
|
|
|
|
+ {
|
|
|
|
+ id = Guid.NewGuid().ToString(),
|
|
|
|
+ name = "第二学期",
|
|
|
|
+ start = 0,
|
|
|
|
+ month = 3,
|
|
|
|
+ day = 1
|
|
|
|
+ });
|
|
|
|
+ periodChange = true;
|
|
|
|
+ }
|
|
//是否需要创建科目
|
|
//是否需要创建科目
|
|
- var bind = period.subjects.Find(x => x.bindId.Equals($"{subjectId}"));
|
|
|
|
- if (bind == null)
|
|
|
|
|
|
+ var bind = period.subjects.Find(x =>!string.IsNullOrWhiteSpace(x.bindId) && x.bindId.Equals($"{subjectId}"));
|
|
|
|
+ if (bind == null)
|
|
{
|
|
{
|
|
string subjectName = "";
|
|
string subjectName = "";
|
|
switch (true) {
|
|
switch (true) {
|
|
- case bool when $"{subjectId}".Equals("subject_sport") :
|
|
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_sport"):
|
|
subjectName = "体育";
|
|
subjectName = "体育";
|
|
break;
|
|
break;
|
|
case bool when $"{subjectId}".Equals("subject_virtue"):
|
|
case bool when $"{subjectId}".Equals("subject_virtue"):
|
|
@@ -1424,53 +1459,188 @@ namespace TEAMModelOS.Controllers
|
|
subName.bindId = $"{subjectId}";
|
|
subName.bindId = $"{subjectId}";
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- period.subjects.Add(new Subject { id= Guid.NewGuid().ToString(),name=subjectName,bindId=$"{subjectId}",type=1 });
|
|
|
|
|
|
+ period.subjects.Add(new Subject { id = Guid.NewGuid().ToString(), name = subjectName, bindId = $"{subjectId}", type = 1 });
|
|
}
|
|
}
|
|
- await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync<School>(schoolBase,school, new PartitionKey("Base"));
|
|
|
|
|
|
+ periodChange = true;
|
|
|
|
+
|
|
}
|
|
}
|
|
- List<SemesterData> semesterDatas = semesterData.ToObject<List<SemesterData>>();
|
|
|
|
- if (semesterDatas.Any()) {
|
|
|
|
- semesterDatas.ForEach(data => {
|
|
|
|
- if (!string.IsNullOrWhiteSpace(data.semesterId)) {
|
|
|
|
- if (!period.semesters.Any()) {
|
|
|
|
- period.semesters.Add(new Semester
|
|
|
|
- {
|
|
|
|
- id =Guid.NewGuid().ToString(),
|
|
|
|
- name = "第一学期",
|
|
|
|
- start = 1,
|
|
|
|
- month = 9,
|
|
|
|
- day = 1
|
|
|
|
- }); period.semesters.Add(new Semester
|
|
|
|
|
|
+ if (periodChange) {
|
|
|
|
+ await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync<School>(schoolBase, school, new PartitionKey("Base"));
|
|
|
|
+ }
|
|
|
|
+ List<Semester> sortedSemesters = SchoolService.SortSemester(period.semesters);
|
|
|
|
+ foreach (var studentInfo in studentsBases) {
|
|
|
|
+ Student student = studentInfo.studentBase;
|
|
|
|
+ string studentId = studentInfo.studentBase.id;
|
|
|
|
+ string classId= studentInfo.studentBase.classId;
|
|
|
|
+ List<SemesterData> semesterDatas = studentInfo.portrait.semesterData;
|
|
|
|
+
|
|
|
|
+ if (semesterDatas.Any())
|
|
|
|
+ {
|
|
|
|
+ semesterDatas.ForEach(data => {
|
|
|
|
+ if (!string.IsNullOrWhiteSpace(data.semesterId))
|
|
|
|
+ {
|
|
|
|
+ var semester = period.semesters.Find(s => s.id.Equals(data.semesterId));
|
|
|
|
+ //如果找到对应的semesterId则直接使用当前semesterId
|
|
|
|
+ if (semester == null)
|
|
{
|
|
{
|
|
- id = Guid.NewGuid().ToString(),
|
|
|
|
- name = "第二学期",
|
|
|
|
- start = 0,
|
|
|
|
- month = 3,
|
|
|
|
- day = 1
|
|
|
|
- });
|
|
|
|
|
|
+ //先处理,最后再检查。
|
|
|
|
+ data.semesterId = $"{data.semesterId}--semesterId学期无效";
|
|
|
|
+ if (data.semester > 0)
|
|
|
|
+ {
|
|
|
|
+ int count = period.semesters.Count();
|
|
|
|
+ if (count >= data.semester)
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = sortedSemesters[data.semester - 1].id;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = $"{data.semester}--semester学期无效";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = $"{data.semester}--semester学期无效";
|
|
|
|
+ //无效的学期数
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- var semester = period.semesters.Find(s => s.id.Equals(data.semesterId));
|
|
|
|
- if (semester == null) {
|
|
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = $"{data.semesterId}--semesterId学期无效";
|
|
if (data.semester > 0)
|
|
if (data.semester > 0)
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+ int count = period.semesters.Count();
|
|
|
|
+ if (count >= data.semester)
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = sortedSemesters[data.semester - 1].id;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = $"{data.semester}--semester学期无效";
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- //无效的学期
|
|
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ data.semesterId = $"{data.semester}--semester学期无效";
|
|
|
|
+ //无效的学期数
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ var okSemesterDatas = semesterDatas.Where(z => !z.semesterId.Contains("学期无效"));
|
|
|
|
+ var ids = okSemesterDatas.Select(k => $"{k.year}-{k.semesterId}");
|
|
|
|
+ if (ids.Any())
|
|
|
|
+ {
|
|
|
|
+ List<OverallEducation> overallEducations = new List<OverallEducation>();
|
|
|
|
+ string sql = $"select value c from c where c.id in ({string.Join(",", ids.Select(f => $"'{f}'"))})" +
|
|
|
|
+ $" and c.studentId ='{studentId}' and c.schoolCode='{schoolCode}' and c.periodId='{periodId}' and c.classId='{classId}'";
|
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
|
|
|
|
+ .GetItemQueryIterator<OverallEducation>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"OverallEducation-{schoolCode}-{studentId}") }))
|
|
|
|
+ {
|
|
|
|
+ overallEducations.Add(item);
|
|
|
|
+ }
|
|
|
|
+ var nodbids = ids.Except(overallEducations.Select(x => x.id));
|
|
|
|
+ var newDatas = semesterDatas.FindAll(k => nodbids.Contains($"{k.year}-{k.semesterId}"));
|
|
|
|
+ var updateDatas = semesterDatas.FindAll(k => overallEducations.Select(z => z.id).Contains($"{k.year}-{k.semesterId}"));
|
|
|
|
+ List<OverallEducation> newOverallEducations = new List<OverallEducation>();
|
|
|
|
+ newDatas.ForEach(z => {
|
|
|
|
+ //处理新增的学生学期画像
|
|
|
|
+ var overallEducation = newOverallEducations.Find(o => o.id.Equals($"{z.year}-{z.semesterId}") && o.code.Equals($"{schoolCode}-{studentId}"));
|
|
|
|
+ if (overallEducation == null)
|
|
|
|
+ {
|
|
|
|
+ overallEducation = new OverallEducation
|
|
|
|
+ {
|
|
|
|
+ id = $"{z.year}-{z.semesterId}",
|
|
|
|
+ code = $"OverallEducation-{schoolCode}-{studentId}",
|
|
|
|
+ pk = "OverallEducation",
|
|
|
|
+ ttl = -1,
|
|
|
|
+ name = student.name,
|
|
|
|
+ classId = student.classId,
|
|
|
|
+ schoolCode = $"{schoolCode}",
|
|
|
|
+ semesterId = z.semesterId,
|
|
|
|
+ year = z.year,
|
|
|
|
+ periodId = $"{periodId}",
|
|
|
|
+ stuYear = student.year,
|
|
|
|
+ studentId = student.id,
|
|
|
|
+ };
|
|
|
|
+ newOverallEducations.Add(overallEducation);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ if (newOverallEducations.Any())
|
|
|
|
+ {
|
|
|
|
+ newOverallEducations = FillSemesterData($"{subjectId}", newOverallEducations, newDatas);
|
|
|
|
+ foreach (var edu in newOverallEducations) {
|
|
|
|
+ await client.GetContainer(Constant.TEAMModelOS, Constant.Student).CreateItemAsync(edu, new PartitionKey(edu.code));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (overallEducations.Any())
|
|
|
|
+ {
|
|
|
|
+ overallEducations = FillSemesterData($"{subjectId}", overallEducations, updateDatas);
|
|
|
|
+ foreach (var edu in overallEducations)
|
|
|
|
+ {
|
|
|
|
+ await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync(edu,edu.id, new PartitionKey(edu.code));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- });
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- return responseData = new() { code = RespondCode.Ok, msg = "成功" };
|
|
|
|
- } catch (Exception ex) {
|
|
|
|
|
|
+ return responseData = new() { data = new { unmatch }, code = RespondCode.Ok, msg = "成功" };
|
|
|
|
+ } catch (CosmosException cex) when(cex.Status==404) {
|
|
|
|
+ return new ResponseData<dynamic>() { code = RespondCode.NotFound, msg = "学生ID或学校编码不存在!" };
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex) {
|
|
await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/UpsertStudentPortrait() 参数:bizId:{bizId},school:{school},参数json:{json.ToJsonString()} \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
|
|
await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/UpsertStudentPortrait() 参数:bizId:{bizId},school:{school},参数json:{json.ToJsonString()} \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
|
|
return new ResponseData<dynamic>() { code = RespondCode.Error, msg = "服务器错误!" };
|
|
return new ResponseData<dynamic>() { code = RespondCode.Error, msg = "服务器错误!" };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ public static List<OverallEducation> FillSemesterData(string subjectId, List<OverallEducation> overallEducations, List<SemesterData> semestersDatas) {
|
|
|
|
|
|
|
|
+ semestersDatas.ForEach(z => {
|
|
|
|
+ var oedu= overallEducations.Find(x => x.id.Equals($"{z.year}-{z.semesterId}"));
|
|
|
|
+ if (oedu != null) {
|
|
|
|
+ List<EducationScore> educationScores=null;
|
|
|
|
+ switch (true)
|
|
|
|
+ {
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_sport"):
|
|
|
|
+ educationScores=oedu.sports;
|
|
|
|
+ break;
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_virtue"):
|
|
|
|
+ educationScores = oedu.virtue;
|
|
|
|
+ break;
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_labour"):
|
|
|
|
+ educationScores = oedu.labour;
|
|
|
|
+ break;
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_music"):
|
|
|
|
+ educationScores = oedu.art;
|
|
|
|
+ break;
|
|
|
|
+ case bool when $"{subjectId}".Equals("subject_painting"):
|
|
|
|
+ educationScores = oedu.art;
|
|
|
|
+ break;
|
|
|
|
+ default:educationScores = new List<EducationScore>();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ var edu= educationScores.Find(m => m.examId.Equals(z.examId));
|
|
|
|
+ z.totalScore = z.totalScore <= 0 ? 100 : z.totalScore;
|
|
|
|
+ if (edu == null)
|
|
|
|
+ {
|
|
|
|
+ edu = new EducationScore();
|
|
|
|
+ educationScores.Add(edu);
|
|
|
|
+ }
|
|
|
|
+ edu.examId = z.examId;
|
|
|
|
+ edu.examDate = z.examDate;
|
|
|
|
+ edu.examName = z.examName;
|
|
|
|
+ edu.examType = z.examType;
|
|
|
|
+ edu.excellenceRate = z.excellenceRate;
|
|
|
|
+ edu.totalScore = z.totalScore;
|
|
|
|
+ edu.rate = z.sumScore / z.totalScore;
|
|
|
|
+ edu.level = z.sumScore / z.totalScore;
|
|
|
|
+ edu.sumScore = z.sumScore;
|
|
|
|
+ edu.passRate = z.passRate;
|
|
|
|
+ edu.itemScore = z.itemScore;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ return overallEducations;
|
|
|
|
+ }
|
|
public static void GenApiTableRecord(AzureStorageFactory azureStorage)
|
|
public static void GenApiTableRecord(AzureStorageFactory azureStorage)
|
|
{
|
|
{
|
|
|
|
|