CrazyIter_Bin 2 年之前
父節點
當前提交
4b6c612029

+ 6 - 2
TEAMModelOS.SDK/Context/Attributes/Filter/ApiTokenAttribute.cs

@@ -145,7 +145,11 @@ namespace TEAMModelOS.Filter
                             string issuer = "";
                             if (_option.Location.Equals("China-Dep"))
                             {
+#if !DEBUG
                                 issuer = keys[0];
+#else
+                                issuer= keys[1];
+#endif
                             }
                             else if (_option.Location.Equals("China-Test"))
                             {
@@ -282,7 +286,7 @@ namespace TEAMModelOS.Filter
                     }
                     else
                     {
-                        JsonResult jsonResult = new JsonResult(new {  msg,code});
+                        JsonResult jsonResult = new JsonResult(new {  msg="未授权",code=401});
                         jsonResult.StatusCode = 401;
                         context.Result = jsonResult;
                     }
@@ -290,7 +294,7 @@ namespace TEAMModelOS.Filter
                 else {
                     msg = "该接口暂未授权访问!";
                     code = 401010;
-                    JsonResult jsonResult = new JsonResult(new { msg,code});
+                    JsonResult jsonResult = new JsonResult(new { msg = "未授权", code = 401 });
                     jsonResult.StatusCode = 401;
                     context.Result = jsonResult;
                 }

+ 200 - 1
TEAMModelOS/Controllers/OpenApi/Business/BizOverallEducationController.cs

@@ -61,7 +61,206 @@ namespace TEAMModelOS.Controllers
             var responseData = await OpenApiService.UpsertStudentPortrait(_azureCosmos, _dingDing, id, school, jsonElement);
             return Ok(new { responseData });
         }
-
+        ///数据结构说明
+        /**
+         *
+url[post]https: //www.teammodel.cn/business/upsert-student-portrait
+header:
+X-Auth-School:hbcn  授权访问的学校
+X-Auth-ApiToken:授权token eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9
+Content-Type: application/json
+params [body json]: 
+{
+    "schoolCode": "hbcn",
+    "periodId": "463db08d-cbe7-48a0-a81a-fc39b3c1fep1",
+    "subjectId": "subject_sport",
+    "students": [
+        {
+            "studentId": "202001001",
+            "name": "卢三诗",
+            "classId": "2ffbd7f9-2445-4139-90a7-59e27c0d097e",
+            "semesterData": [
+                {
+                    "examName": "评测名称",
+                    "examId": "评测id2",
+                    "examDate": 1629947402486,
+                    "examType": "期末",
+                    "year": 2020,
+                    "semester": 1,
+                    "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s21",
+                    "totalScore": 100,
+                    "sumScore": 80,
+                    "excellenceRate": 61.73,
+                    "passRate": 91.88,
+                    "itemScore": [
+                        {
+                            "name": "立定跳远",
+                            "score": 99.95
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
+//正确返回
+{
+    "responseData": {
+        "code": 200,
+        "msg": "成功",
+        "data": {
+            "unmatchStuInfo": [],//如果数组长度大于0则,学生信息或班级信息不匹配
+            "unmatchSemester":[],//如果数组长度大于0则,包含的学期信息不匹配
+            "upsertDatas":[],//如果数组长度大于0则,表示更新或保存成功的数据
+        }
+    }
+}
+//错误返回
+{
+    "responseData": {
+        "code": 500,
+        "msg": "返回信息"
+        
+    }
+}
+code:
+500 服务端异常
+404 学校编码不存在
+404 periodId不存在
+400 当前subjectId未开放画像业务
+400 students为空或格式错误
+400 subjectId为空
+400 periodId为空
+400 schoolCode为空
+//接口规范
+{
+    "schoolCode": "hbcn", //学校简码
+    "periodId": "52076c94-7581-fbae-4487-4b162a61fea3", //学段id
+    "subjectId": "subject_sport", //体育科目id
+    "students": [
+        {
+            "studentId": "20220901", //学生编号
+            "name": "海献仪", //学生姓名
+            "classId": "c406eee2-1ce9-caf4-5fc0-57351604b615", //行政班id
+            "semesterData": [ //学期数据
+                {
+                    "examName": "评测名称", //评测名称
+                    "examId": "评测id", //用于数据新增或更新
+                    "examDate": 1629947402486, //评测时间,13位时间戳
+                    "examType": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+                    "year": 2021, //所属学年,学年跨年,按上一年。
+                    "semester": 2, //学期,与semesterId选填其一
+                    "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s2", //学期id 
+                    "totalScore": 100, //配分,总分
+                    "sumScore": 74.29, //总成绩
+                    "excellenceRate": 61.73, //优秀率
+                    "passRate": 91.88, //及格率
+                    "itemScore": [ //考核项目数据
+                        {
+                            "name": "立定跳远", //项目名称
+                            "score": 99.95 //项目分数
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
+//五育数据看板结构
+{
+    "id": "年份2021-学期id",
+    "semesterName": "上学期",
+    "year": 2021,
+    "semesterId": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+    "code": "hbcn-20220901",
+    "schoolCode": "hbcn",
+    "studentId": "20220901",
+    "name": "海献仪",
+    "classId": [
+        "c406eee2-1ce9-caf4-5fc0-57351604b615"
+    ],
+    "periodId": "52076c94-7581-fbae-4487-4b162a61fea3",
+    "grade": 1,
+    "virtue": //德
+    [
+        {
+            "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+            "name": "评测名称",
+            "type": "日常", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+            "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
+            "examDate": 1629947402486,
+            "sumScore": 74.29,
+            "excellenceRate": 61.73,
+            "passRate": 91.88,
+            "itemScore": [ //考核项目数据
+                {
+                    "name": "迟到", //
+                    "score": -1, //计分
+                    "time": 1629947402486,
+                }
+            ]
+        }
+    ],
+    "intelligence": //智
+    [
+        {
+            "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+            "name": "评测名称",
+            "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+            "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
+            "examDate": 1629947402486,
+            "level": 1
+        }
+    ],
+    "sports": //体
+    [
+        {
+            "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+            "name": "评测名称",
+            "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+            "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
+            "examDate": 1629947402486,
+            "sumScore": 74.29,
+            "excellenceRate": 61.73,
+            "passRate": 91.88,
+            "itemScore": [ //考核项目数据
+                {
+                    "name": "立定跳远", //项目名称
+                    "score": 99.95 //项目分数
+                }
+            ]
+        }
+    ],
+    "art": //美
+    [
+        {
+            "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+            "name": "评测名称",
+            "type": "期末", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+            "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
+            "examDate": 1629947402486,
+            "level": 1,
+        }
+    ],
+    "labour": //劳
+    [
+        {
+            "id": "17f85c96-253d-4f84-84ad-c819f0b605s2",
+            "name": "任务名称",
+            "type": "日常", //期末,期中,季考,月考,周考,测验,练习,作业,日常,课中
+            "subjectId": "52076c94-7581-fbae-4487-4b162a61fea3",
+            "examDate": 1629947402486,
+            "itemScore": [ //考核项目数据
+                {
+                    "name": "洗碗", //洗碗,倒垃圾,打扫卫生等...
+                    "score": 1, //项目计分
+                    "time": 1629947402486,
+                }
+            ]
+        }
+    ]
+}
+* **/
 
     }
 }

+ 99 - 66
TEAMModelOS/Controllers/OpenApi/OpenApiService.cs

@@ -71,7 +71,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetSchools()   参数:bizId:{bizId} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<BizSchool>>() { code = RespondCode.Error, msg = "服务器错误" };
+                return new ResponseData<List<BizSchool>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -445,7 +445,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetSchoolInfo()   参数:bizId:{bizId},school:{schoolId} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<dynamic>() { code = RespondCode.Error, msg = "服务器错误" };
+                return new ResponseData<dynamic>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -568,7 +568,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetGroupList()   参数:bizId:{bizId},school:{school},json:{json.ToJsonString()} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<OGroupList>>() { code = RespondCode.Error, msg = "服务器错误" };
+                return new ResponseData<List<OGroupList>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -612,7 +612,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetGroupMembers()   参数: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 = "服务端异常" };
                 
             }
         }
@@ -653,7 +653,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetCourseList()   参数: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 = "服务端异常" };
 
             }
         }
@@ -686,7 +686,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetCourseInfo()   参数: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 = "服务端异常" };
             }
         }
 
@@ -718,7 +718,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetPaperExamCondition()   参数: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 = "服务端异常" };
             }
         }
 
@@ -766,7 +766,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetRoomList()   参数:bizId:{bizId},school:{school},json:{json.ToJsonString()} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<ORoom>>() { code = RespondCode.Error, msg = "服务器错误" };
+                return new ResponseData<List<ORoom>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -800,7 +800,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetRoomInfo()   参数: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 = "服务端异常" };
             }
         }
 
@@ -869,7 +869,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetTeacherList()   参数: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 = "服务端异常" };
             }
         }
 
@@ -958,7 +958,7 @@ namespace TEAMModelOS.Controllers
                 }
             } catch (Exception ex) {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetTeacherTeach()   参数: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 = "服务端异常" };
             }
         }
 
@@ -988,7 +988,7 @@ namespace TEAMModelOS.Controllers
                     teacher = JsonDocument.Parse(responseTch.Content).RootElement.Deserialize<Teacher>();
                 }
                 else
-                    return new ResponseData<dynamic> { code = RespondCode.NotFound, msg = "账号未创建" };
+                    return new ResponseData<dynamic> { code = RespondCode.NotFound, msg = "账号未创建" };
                 if (responseSchoolTch.Status == 200 && teacher != null)
                 {
                     SchoolTeacher schoolTeacher = JsonDocument.Parse(responseSchoolTch.Content).RootElement.Deserialize<SchoolTeacher>();
@@ -996,12 +996,12 @@ namespace TEAMModelOS.Controllers
                     return new ResponseData<dynamic> { code = RespondCode.Ok, msg = "成功", data = new { teacher.id, teacher.name, teacher.picture, schoolTeacher.job, schoolTeacher.status, schoolTeacher.roles, schoolTeacher.subjectIds, school = teacher.schools?.Find(x => x.schoolId.Equals(school)) } };
                 }
                 else
-                    return new ResponseData<dynamic> { code = RespondCode.NotFound, msg = "教师未就职该学校" };
+                    return new ResponseData<dynamic> { code = RespondCode.NotFound, msg = "教师未就职该学校" };
             }
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetTeacherInfo()   参数: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 = "服务端异常" };
             }
         }
 
@@ -1181,7 +1181,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetTeacherInfo()   参数:bizId:{bizId},school:{school},json:{json} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<OTeachers>>() { code = RespondCode.Error, msg = "服务器错误" };
+                return new ResponseData<List<OTeachers>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -1258,7 +1258,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetSyllabus()  参数:bizId:{bizId},school:{school},参数json:{json.ToJsonString()} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<OSyllabusTreeNode>>() { code = RespondCode.Error, msg = "服务器错误!" };
+                return new ResponseData<List<OSyllabusTreeNode>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -1301,7 +1301,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetVolumes()  参数:bizId:{bizId},school:{school},参数json:{json.ToJsonString()} \n  {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
-                return new ResponseData<List<OVolume>>() { code = RespondCode.Error, msg = "服务器错误!" };
+                return new ResponseData<List<OVolume>>() { code = RespondCode.Error, msg = "服务端异常" };
             }
         }
 
@@ -1350,7 +1350,7 @@ namespace TEAMModelOS.Controllers
             catch (Exception ex)
             {
                 await _dingDing.SendBotMsg($"OpenApi,{Environment.GetEnvironmentVariable("Option:Location")} OpenApiService/GetKnowledges()  参数: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 = "服务端异常" };
             }
         }
         /// <summary>
@@ -1367,26 +1367,29 @@ namespace TEAMModelOS.Controllers
                 var client = _azureCosmos.GetCosmosClient();
                 if (!json.TryGetProperty("schoolCode", out JsonElement schoolCode))
                 {
-                    return responseData = new() { code = RespondCode.ParamsError, msg = "schoolCode为空" };
+                    return responseData = new() { code = RespondCode.ParamsError, msg = "schoolCode为空" };
                 }
                 if (!json.TryGetProperty("periodId", out JsonElement periodId)) {
-                    return responseData = new() { code = RespondCode.ParamsError, msg = "periodId为空" };
+                    return responseData = new() { code = RespondCode.ParamsError, msg = "periodId为空" };
                 }
                 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("students", out JsonElement _students)) {
-                    return responseData = new() { code = RespondCode.ParamsError, msg = "students为空" };
+                if (!json.TryGetProperty("students", out JsonElement _students) && !_students.ValueKind.Equals(JsonValueKind.Array)) {
+                    return responseData = new() { code = RespondCode.ParamsError, msg = "students为空或格式错误" };
                 }
                 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") 
+                    && !$"{subjectId}".Equals("subject_art"))
                 {
-                    return responseData = new() { code = RespondCode.ParamsError, msg = "当前subjectId未开放画像业务" };
+                    return responseData = new() { code = RespondCode.ParamsError, msg = "当前subjectId未开放画像业务" };
                 }
                 School schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
                 List<PortraitStudent> students = _students.ToObject<List<PortraitStudent>>();
                 List<(Student studentBase, PortraitStudent portrait) > studentsBases = new List<(Student, PortraitStudent)>();
-                List<PortraitStudent> unmatch=new List<PortraitStudent>();
+                List<PortraitStudent> unmatchStuInfo =new List<PortraitStudent>();
+                List<PortraitStudent> unmatchSemester = new List<PortraitStudent>();
+                List<PortraitStudent> upsertDatas = new List<PortraitStudent>();
                 string stusql = $"select c.id,c.classId,c.name,c.year  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}") }))
@@ -1397,17 +1400,18 @@ namespace TEAMModelOS.Controllers
                         studentsBases.Add((item,student));
                     }
                     else {
-                        unmatch.Add(student);
+                        unmatchStuInfo.Add(student);
                     }
                 }
                 var unexist =  students.FindAll(z => !studentsBases.Select(z => z.studentBase.id).Contains(z.studentId));
                 if (unexist.Any()) {
-                    unmatch.AddRange(unexist);
+                    unmatchStuInfo.AddRange(unexist);
                 }
                 Period period = schoolBase.period.Find(x => x.id.Equals($"{periodId}"));
+
                 if (period == null)
                 {
-                    return responseData = new() { code = RespondCode.NotFound, msg = "periodId不存在" };
+                    return responseData = new() { code = RespondCode.NotFound, msg = "periodId不存在" };
                 }
                 else {
                     bool periodChange = false;
@@ -1432,39 +1436,45 @@ namespace TEAMModelOS.Controllers
                         periodChange = true;
                     }
                     //是否需要创建科目 
-                    var bind = period.subjects.Find(x =>!string.IsNullOrWhiteSpace(x.bindId) && x.bindId.Equals($"{subjectId}"));
-                    if (bind == null)
-                    {
-                        string subjectName = "";
-                        switch (true) {
-                            case bool when $"{subjectId}".Equals("subject_sport"):
-                                subjectName = "体育";
-                                break;
-                            case bool when $"{subjectId}".Equals("subject_virtue"):
-                                subjectName = "德育";
-                                break;
-                            case bool when $"{subjectId}".Equals("subject_labour"):
-                                subjectName = "劳动";
-                                break;
-                            case bool when $"{subjectId}".Equals("subject_music"):
-                                subjectName = "音乐";
-                                break;
-                            case bool when $"{subjectId}".Equals("subject_painting"):
-                                subjectName = "美术";
-                                break;
-                        }
-                        var subName = period.subjects.Find(z => z.name.Contains(subjectName));
-                        if (subName != null)
+                    if (!$"{subjectId}".Equals("subject_art")) {
+                        var bind = period.subjects.Find(x => !string.IsNullOrWhiteSpace(x.bindId) && x.bindId.Equals($"{subjectId}"));
+                        if (bind == null)
                         {
-                            subName.bindId = $"{subjectId}";
-                        }
-                        else {
-                            period.subjects.Add(new Subject { id = Guid.NewGuid().ToString(), name = subjectName, bindId = $"{subjectId}", type = 1 });
+                            string subjectName = "";
+                            switch (true)
+                            {
+                                case bool when $"{subjectId}".Equals("subject_sport"):
+                                    subjectName = "体育";
+                                    break;
+                                case bool when $"{subjectId}".Equals("subject_virtue"):
+                                    subjectName = "德育";
+                                    break;
+                                case bool when $"{subjectId}".Equals("subject_labour"):
+                                    subjectName = "劳动";
+                                    break;
+                                //case bool when $"{subjectId}".Equals("subject_music"):
+                                //    subjectName = "音乐";
+                                //    break;
+                                //case bool when $"{subjectId}".Equals("subject_painting"):
+                                //    subjectName = "美术";
+                                //    break;
+                            }
+                            if (!string.IsNullOrWhiteSpace(subjectName)) {
+                                var subName = period.subjects.Find(z => z.name.Contains(subjectName));
+                                if (subName != null)
+                                {
+                                    subName.bindId = $"{subjectId}";
+                                }
+                                else
+                                {
+                                    period.subjects.Add(new Subject { id = Guid.NewGuid().ToString(), name = subjectName, bindId = $"{subjectId}", type = 1 });
+                                }
+                                periodChange = true;
+                            }
                         }
-                        periodChange = true;
-
                     }
-                    if (periodChange) {
+                    if (periodChange)
+                    {
                         await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync<School>(schoolBase, school, new PartitionKey("Base"));
                     }
                     List<Semester> sortedSemesters = SchoolService.SortSemester(period.semesters);
@@ -1526,7 +1536,27 @@ namespace TEAMModelOS.Controllers
                                     }
                                 }
                             });
+                            var noSemesterDatas = semesterDatas.Where(z => z.semesterId.Contains("学期无效")).ToList();
+                            if (noSemesterDatas.Any())
+                            {
+                                unmatchSemester.Add(new PortraitStudent
+                                {
+                                    studentId = studentInfo.portrait.studentId,
+                                    name = studentInfo.portrait.name,
+                                    classId = studentInfo.portrait.classId,
+                                    semesterData = noSemesterDatas,
+                                });
+                            }
                             var okSemesterDatas = semesterDatas.Where(z => !z.semesterId.Contains("学期无效"));
+                            if (okSemesterDatas.Any()) {
+                                upsertDatas.Add(new PortraitStudent
+                                {
+                                    studentId = studentInfo.portrait.studentId,
+                                    name = studentInfo.portrait.name,
+                                    classId = studentInfo.portrait.classId,
+                                    semesterData = okSemesterDatas.ToList(),
+                                });
+                            }
                             var ids = okSemesterDatas.Select(k => $"{k.year}-{k.semesterId}");
                             if (ids.Any())
                             {
@@ -1584,13 +1614,13 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                 }
-                return responseData = new() { data = new { unmatch }, code = RespondCode.Ok, msg = "成功" };
+                return responseData = new() { data = new { unmatchStuInfo, unmatchSemester , upsertDatas }, code = RespondCode.Ok, msg = "成功" };
             } catch (CosmosException cex) when(cex.Status==404) {
-                return new ResponseData<dynamic>() { code = RespondCode.NotFound, msg = "学生ID或学校编码不存在" };
+                return new ResponseData<dynamic>() { code = RespondCode.NotFound, msg = "学校编码不存在" };
             }
             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.成都开发測試群組);
-                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) {
@@ -1610,10 +1640,13 @@ namespace TEAMModelOS.Controllers
                         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"):
+                        //case bool when $"{subjectId}".Equals("subject_music"):
+                        //    educationScores = oedu.art;
+                        //    break;
+                        //case bool when $"{subjectId}".Equals("subject_painting"):
+                        //    educationScores = oedu.art;
+                        //    break;
+                        case bool when $"{subjectId}".Equals("subject_art"):
                             educationScores = oedu.art;
                             break;
                         default:educationScores = new List<EducationScore>();