Explorar o código

[API-Student]StudentManage , 調整批量更新和刪除學生的方法。(#207)

Mickey %!s(int64=4) %!d(string=hai) anos
pai
achega
22037986e4
Modificáronse 1 ficheiros con 148 adicións e 99 borrados
  1. 148 99
      TEAMModelOS/Controllers/School/StudentController.cs

+ 148 - 99
TEAMModelOS/Controllers/School/StudentController.cs

@@ -109,7 +109,7 @@ namespace TEAMModelOS.Controllers
                     case "update":
                         //更新學生資料,批量密碼重置,基本資訊更新(姓名、教室ID及座號)
                         var (dicStudent, nonexistentIds, errorIds) = await updateStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
-                        var studentClass = await updateClassStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
+                        var studentClass = await updateClassStudents(schoolId.GetString(), dicStudent);
                         if (errorIds.Count == 0)
                         {
                             return this.Ok(new
@@ -817,6 +817,7 @@ namespace TEAMModelOS.Controllers
             try
             {
                 Dictionary<string, List<string>> classStudent = new Dictionary<string, List<string>>();
+                List<string> studs = new List<string>();
                 //整理教室學生資訊
                 while (students.MoveNext())
                 {
@@ -825,6 +826,7 @@ namespace TEAMModelOS.Controllers
                     if (student.TryGetProperty("id", out var tmpId) && !string.IsNullOrWhiteSpace(tmpId.GetString()))
                     {
                         id = tmpId.GetString();
+                        studs.Add(id);
                     }
                     else continue;
 
@@ -834,63 +836,78 @@ namespace TEAMModelOS.Controllers
                         if (!string.IsNullOrWhiteSpace(classId) && classStudent.ContainsKey(classId)) classStudent[classId].Add(id);
                         else classStudent.Add(classId, new List<string>() { id });
                     }
-                    
-                    //如果沒給教室?但卻有加入過教室
-                    
                 }
 
-                foreach (var c in classStudent)
+                if (studs.Count != 0)
                 {
-                    var response = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOSTemp", "School").ReadItemStreamAsync(c.Key, new PartitionKey($"Class-{schoolId}"));
-                    if (response.Status == 200)
+                    //使用子查詢來查詢students欄位裡面是否有相符的學生
+                    var queryText = $"SELECT VALUE c FROM c JOIN (SELECT VALUE t FROM t IN c.students WHERE t.id IN ({string.Join(",", studs.Select(o => $"'{o}'"))}))";
+                    await foreach (Response item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOSTemp", "School")
+                                    .GetItemQueryStreamIterator(
+                                        queryText: queryText,
+                                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schoolId}") }))
                     {
-                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
-                        using var memoryStream = new MemoryStream();
-                        using var writer = new Utf8JsonWriter(memoryStream);
-                        writer.WriteStartObject();
-                        foreach (var element in json.RootElement.EnumerateObject())
+                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                         {
-                            if (element.Name.Equals("students", StringComparison.Ordinal))
+                            JsonElement.ArrayEnumerator docs = json.RootElement.GetProperty("Documents").EnumerateArray();
+                            while (docs.MoveNext())
                             {
-                                writer.WritePropertyName("students");
-                                writer.WriteStartArray();
-                                var s = element.Value.EnumerateArray();
-                                while (s.MoveNext())
+                                JsonElement doc = docs.Current;
+
+                                doc.TryGetProperty("id", out var tmpId);
+                                var id = tmpId.GetString();
+
+                                using var memoryStream = new MemoryStream();
+                                using var writer = new Utf8JsonWriter(memoryStream);
+                                writer.WriteStartObject();
+                                foreach (var element in doc.EnumerateObject())
                                 {
-                                    JsonElement stud = s.Current;
-                                    string id = stud.GetProperty("id").GetString();
-                                    if (!c.Value.Contains(id))
+                                    if (element.Name.Equals("students", StringComparison.Ordinal))
                                     {
-                                        string name = stud.GetProperty("name").GetString();
-                                        string no = stud.GetProperty("no").GetString();
-
-                                        writer.WriteStartObject();
-                                        writer.WriteString("id", id);
-                                        if (string.IsNullOrWhiteSpace(name)) writer.WriteNull("name");
-                                        else writer.WriteString("name", name);
-                                        if (string.IsNullOrWhiteSpace(no)) writer.WriteNull("no");
-                                        else writer.WriteString("no", no);
-                                        writer.WriteEndObject();
+                                        writer.WritePropertyName("students");
+                                        writer.WriteStartArray();
+                                        var s = element.Value.EnumerateArray();
+                                        while (s.MoveNext())
+                                        {
+                                            JsonElement stud = s.Current;
+                                            string sutdId = stud.GetProperty("id").GetString();
+                                            if (!studs.Contains(sutdId))
+                                            {
+                                                string name = stud.GetProperty("name").GetString();
+                                                string no = stud.GetProperty("no").GetString();
+
+                                                writer.WriteStartObject();
+                                                writer.WriteString("id", sutdId);
+                                                if (string.IsNullOrWhiteSpace(name)) writer.WriteNull("name");
+                                                else writer.WriteString("name", name);
+                                                if (string.IsNullOrWhiteSpace(no)) writer.WriteNull("no");
+                                                else writer.WriteString("no", no);
+                                                writer.WriteEndObject();
+                                            }
+                                        }
+                                        writer.WriteEndArray();
+                                    }
+                                    else
+                                    {
+                                        element.WriteTo(writer);
                                     }
                                 }
-                                writer.WriteEndArray();
-                            }
-                            else
-                            {
-                                element.WriteTo(writer);
+                                writer.WriteEndObject();
+                                writer.Flush();
+
+                                var ret = await _azureCosmos
+                                    .GetCosmosClient()
+                                    .GetContainer("TEAMModelOSTemp", "School")
+                                    .ReplaceItemStreamAsync(memoryStream, id, new PartitionKey($"Class-{schoolId}"));
+                                if (ret.Status != (int)HttpStatusCode.OK)
+                                {
+                                    await _dingDing.SendBotMsg(
+                                        $"OS,{_option.Location},Student/removeStudentFromClass()\nClass-{schoolId},{string.Join(",", studs.Select(o => $"'{o}'"))}", 
+                                        GroupNames.醍摩豆服務運維群組);
+                                }
                             }
                         }
-                        writer.WriteEndObject();
-                        writer.Flush();
-
-                        var ret = await _azureCosmos
-                            .GetCosmosClient()
-                            .GetContainer("TEAMModelOSTemp", "School")
-                            .ReadItemStreamAsync(c.Key, new PartitionKey($"Class-{schoolId}"));
-                    }
-                    else
-                    {
-                        //查無該教室
                     }
                 }
             }
@@ -1116,15 +1133,15 @@ namespace TEAMModelOS.Controllers
         /// <param name="schoolId"></param>
         /// <param name="students"></param>
         /// <returns></returns>
-        private async Task<(Dictionary<string, (string name, string year, string pic,string gender, string mail, string mobile)> students, List<string> nonexistentIds, List<string> errorIds)> updateStudents(string schoolId, JsonElement.ArrayEnumerator students)
+        private async Task<(Dictionary<string, (string name, string year, string pic, string gender, string mail, string mobile, string classId, string no)> students, List<string> nonexistentIds, List<string> errorIds)> updateStudents(string schoolId, JsonElement.ArrayEnumerator students)
         {
             try
             {
                 //Key:id Value:學生基本資訊
-                Dictionary<string, (string salt, string pw, string name, string year, string pic,string gender,string mail,string mobile)> studentsInfos
-                    = new Dictionary<string, (string salt, string pw, string name, string year, string pic, string gender, string mail, string mobile)>();
-                List<string> nonexistentIds = new List<string>();
-                List<string> errorIds = new List<string>();
+                var studentsInfos
+                    = new Dictionary<string, (string salt, string pw, string name, string year, string pic, string gender, string mail, string mobile, string classId, string no)>();
+                var nonexistentIds = new List<string>();
+                var errorIds = new List<string>();
 
                 //整理輸入資料
                 while (students.MoveNext())
@@ -1135,9 +1152,9 @@ namespace TEAMModelOS.Controllers
                         //確認是否有id欄位,並且確認是否有給pw欄位,若無給或是null empty等,則使用id當密碼。
                         if (!string.IsNullOrWhiteSpace(id.GetString()))
                         {
-                            string salt = string.Empty, pw = string.Empty, name = string.Empty, year = string.Empty, gender = string.Empty, mail = string.Empty, mobile = string.Empty;
+                            string salt = string.Empty, pw = string.Empty, name = string.Empty, year = string.Empty, gender = string.Empty, mail = string.Empty, mobile = string.Empty, classId = string.Empty, no = string.Empty;
                             //有給pw欄位才進行處理
-                             if (student.TryGetProperty("pw", out var tmpPw))
+                            if (student.TryGetProperty("pw", out var tmpPw))
                             {
                                 salt = Utils.CreatSaltString(8);
                                 pw = !string.IsNullOrWhiteSpace(tmpPw.GetString())
@@ -1164,10 +1181,18 @@ namespace TEAMModelOS.Controllers
                             {
                                 year = tmpYear.GetString();
                             }
+                            if (student.TryGetProperty("classId", out var tmpclassId))
+                            {
+                                classId = tmpclassId.GetString();
+                            }
+                            if (student.TryGetProperty("no", out var tmpNo))
+                            {
+                                no = tmpNo.GetString();
+                            }
                             if (!studentsInfos.ContainsKey(id.GetString()))
                             {
                                 //pic,mail,mobile暫不支持更新
-                                studentsInfos.Add(id.GetString(), (salt, pw, name, year, null, gender, null, null));
+                                studentsInfos.Add(id.GetString(), (salt, pw, name, year, null, gender, null, null, classId, no));
                                 nonexistentIds.Add(id.GetString());
                             }
                         }
@@ -1197,8 +1222,8 @@ namespace TEAMModelOS.Controllers
                                 JsonElement account = accounts.Current;
                                 string id = account.GetProperty("id").GetString();
 
-                                (string name, string year, string pic, string gender, string mail, string mobile) oldData;
-                                //oldData = studentsInfos[id];
+                                (string salt, string pw, string name, string year, string pic, string gender, string mail, string mobile, string classId, string no) oldData;
+                                oldData = (studentsInfos[id].salt, studentsInfos[id].pw, studentsInfos[id].name, studentsInfos[id].year, studentsInfos[id].pic, studentsInfos[id].gender, studentsInfos[id].mail, studentsInfos[id].mobile, studentsInfos[id].classId, studentsInfos[id].no);
                                 bool upPwDone = false;
                                 using var memoryStream = new MemoryStream();
                                 using var writer = new Utf8JsonWriter(memoryStream);
@@ -1207,13 +1232,14 @@ namespace TEAMModelOS.Controllers
                                 {
                                     switch (true)
                                     {
-                                        case bool _ when element.Name.Equals("name", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].name):
-                                            writer.WriteString("name", studentsInfos[id].name);
-                                            break;
+                                        //case bool _ when element.Name.Equals("name", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].name):
+                                        //    writer.WriteString("name", studentsInfos[id].name);
+                                        //    break;
                                         case bool _ when element.Name.Equals("name", StringComparison.Ordinal):
                                             if (string.IsNullOrWhiteSpace(studentsInfos[id].name))
                                             {
                                                 element.WriteTo(writer);
+                                                oldData.name = element.Value.GetString();
                                             }
                                             else
                                             {
@@ -1229,11 +1255,33 @@ namespace TEAMModelOS.Controllers
                                                 upPwDone = true;
                                             }
                                             break;
-                                        case bool _ when element.Name.Equals("gender", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].gender):
-                                            writer.WriteString("gender", studentsInfos[id].gender);
+                                        //case bool _ when element.Name.Equals("gender", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].gender):
+                                        //    writer.WriteString("gender", studentsInfos[id].gender);
+                                        //    break;
+                                        case bool _ when element.Name.Equals("gender", StringComparison.Ordinal):
+                                            if (string.IsNullOrWhiteSpace(studentsInfos[id].gender))
+                                            {
+                                                element.WriteTo(writer);
+                                                oldData.gender = element.Value.GetString();
+                                            }
+                                            else
+                                            {
+                                                writer.WriteString("gender", studentsInfos[id].gender);
+                                            }
                                             break;
-                                        case bool _ when element.Name.Equals("year", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].year):
-                                            writer.WriteString("year", studentsInfos[id].year);
+                                        //case bool _ when element.Name.Equals("year", StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(studentsInfos[id].year):
+                                        //    writer.WriteString("year", studentsInfos[id].year);
+                                        //    break;
+                                        case bool _ when element.Name.Equals("year", StringComparison.Ordinal):
+                                            if (string.IsNullOrWhiteSpace(studentsInfos[id].year))
+                                            {
+                                                element.WriteTo(writer);
+                                                oldData.year = element.Value.GetString();
+                                            }
+                                            else
+                                            {
+                                                writer.WriteString("year", studentsInfos[id].year);
+                                            }
                                             break;
                                         case bool _ when element.Name.StartsWith("_", StringComparison.Ordinal):
                                             break;
@@ -1250,6 +1298,7 @@ namespace TEAMModelOS.Controllers
                                 }
                                 writer.WriteEndObject();
                                 writer.Flush();
+                                studentsInfos[id] = oldData;
 
                                 try
                                 {
@@ -1274,10 +1323,10 @@ namespace TEAMModelOS.Controllers
                         nonexistentIds.ForEach(o => studentsInfos.Remove(o));
                     }
                     //整理輸出數據
-                    var retStudentsInfo = new Dictionary<string, (string name, string year, string pic, string gender, string mail, string mobile)>();
+                    var retStudentsInfo = new Dictionary<string, (string name, string year, string pic, string gender, string mail, string mobile, string classId, string no)>();
                     foreach (var item in studentsInfos)
                     {
-                        retStudentsInfo.Add(item.Key, (item.Value.name, item.Value.year, item.Value.pic, item.Value.gender, item.Value.mail, item.Value.mobile));
+                        retStudentsInfo.Add(item.Key, (item.Value.name, item.Value.year, item.Value.pic, item.Value.gender, item.Value.mail, item.Value.mobile, item.Value.classId, item.Value.no));
                     }
                     return (retStudentsInfo, nonexistentIds, errorIds);
                 }
@@ -1299,7 +1348,7 @@ namespace TEAMModelOS.Controllers
         /// <param name="schoolId"></param>
         /// <param name="students"></param>
         /// <returns></returns>
-        private async Task<Dictionary<string, (string classId, string periodId, string gradeId, string name, string no)>> updateClassStudents(string schoolId, JsonElement.ArrayEnumerator students)
+        private async Task<Dictionary<string, (string classId, string periodId, string gradeId, string name, string no)>> updateClassStudents(string schoolId, Dictionary<string, (string name, string year, string pic, string gender, string mail, string mobile, string classId, string no)> students)
         {
             try
             {
@@ -1307,28 +1356,28 @@ namespace TEAMModelOS.Controllers
                 var retStudentsClassInfo = new Dictionary<string, (string classId, string periodId, string gradeId, string name, string no)>();
 
                 //整理輸入的資料
-                var studentsClassInfo = new Dictionary<string, (string classId, string name, string no)>();
-                while (students.MoveNext())
-                {
-                    JsonElement student = students.Current;
-                    if (student.TryGetProperty("id", out var tmpId))
-                    {
-                        if (!string.IsNullOrWhiteSpace(tmpId.GetString()))
-                        {
-                            string classId = string.Empty, className = string.Empty, no = string.Empty, name = string.Empty;
-
-                            if (student.TryGetProperty("name", out var tmpName)) name = tmpName.GetString();
-                            if (student.TryGetProperty("classId", out var tmpClassId)) classId = tmpClassId.GetString();
-                            if (student.TryGetProperty("no", out var tmpNo)) no = tmpNo.GetString();
-
-                            studentsClassInfo.Add(tmpId.GetString(), (classId, name, no));
-                        }
-                    }
-                }
-                if (studentsClassInfo.Count == 0) return retStudentsClassInfo;
+                //var studentsClassInfo = new Dictionary<string, (string classId, string name, string no)>();
+                //while (students.MoveNext())
+                //{
+                //    JsonElement student = students.Current;
+                //    if (student.TryGetProperty("id", out var tmpId))
+                //    {
+                //        if (!string.IsNullOrWhiteSpace(tmpId.GetString()))
+                //        {
+                //            string classId = string.Empty, className = string.Empty, no = string.Empty, name = string.Empty;
+
+                //            if (student.TryGetProperty("name", out var tmpName)) name = tmpName.GetString();
+                //            if (student.TryGetProperty("classId", out var tmpClassId)) classId = tmpClassId.GetString();
+                //            if (student.TryGetProperty("no", out var tmpNo)) no = tmpNo.GetString();
+
+                //            studentsClassInfo.Add(tmpId.GetString(), (classId, name, no));
+                //        }
+                //    }
+                //}
+                if (students.Count == 0) return retStudentsClassInfo;
 
                 //透過id查找已加入的教室
-                var classInfo = await getClassInfoUseStudent(schoolId, studentsClassInfo.Select(o => o.Key).ToList());
+                var classInfo = await getClassInfoUseStudent(schoolId, students.Select(o => o.Key).ToList());
 
                 //如果有查到,代表該學生已經加入過某間教室(Class)
                 if (classInfo.Count != 0)
@@ -1369,17 +1418,17 @@ namespace TEAMModelOS.Controllers
                                 if (Document.TryGetProperty("no", out var tmpNo)) no = tmpNo.GetString();
 
                                 //檢查輸入資料內學生要加入的教室是否一致
-                                if (studentsClassInfo.ContainsKey(studId))
+                                if (students.ContainsKey(studId))
                                 {
                                     //如果是相同的教室id
-                                    if (studentsClassInfo[studId].classId.Equals(classId, StringComparison.Ordinal))
+                                    if (students[studId].classId.Equals(classId, StringComparison.Ordinal))
                                     {
                                         retStudentsClassInfo.Add(studId, (classId, periodId, gradeId, name, no));
 
                                         //座號及姓名檢查,如果不相同則進行更新
                                         if (
-                                            studentsClassInfo[studId].no.Equals(no, StringComparison.Ordinal)
-                                            && studentsClassInfo[studId].name.Equals(name, StringComparison.Ordinal)
+                                            students[studId].no.Equals(no, StringComparison.Ordinal)
+                                            && students[studId].name.Equals(name, StringComparison.Ordinal)
                                             )
                                         {
                                             writer.WriteStartObject();
@@ -1394,16 +1443,16 @@ namespace TEAMModelOS.Controllers
                                         {
                                             writer.WriteStartObject();
                                             writer.WriteString("id", studId);
-                                            if (string.IsNullOrWhiteSpace(studentsClassInfo[studId].name)) writer.WriteNull("name");
-                                            else writer.WriteString("name", studentsClassInfo[studId].name);
-                                            if (string.IsNullOrWhiteSpace(studentsClassInfo[studId].no)) writer.WriteNull("no");
-                                            else writer.WriteString("no", studentsClassInfo[studId].no);
+                                            if (string.IsNullOrWhiteSpace(students[studId].name)) writer.WriteNull("name");
+                                            else writer.WriteString("name", students[studId].name);
+                                            if (string.IsNullOrWhiteSpace(students[studId].no)) writer.WriteNull("no");
+                                            else writer.WriteString("no", students[studId].no);
                                             writer.WriteEndObject();
                                             //更新輸出結果的資料
-                                            retStudentsClassInfo[studId] = (classId, periodId, gradeId, studentsClassInfo[studId].name, studentsClassInfo[studId].no);
+                                            retStudentsClassInfo[studId] = (classId, periodId, gradeId, students[studId].name, students[studId].no);
                                         }
                                         //將已處理好的學生從字典裡移除
-                                        studentsClassInfo.Remove(studId);
+                                        students.Remove(studId);
                                     }
                                     //不是相同教室id,則要移除該學生的資訊,不寫入
                                     else continue;
@@ -1443,10 +1492,10 @@ namespace TEAMModelOS.Controllers
                     }
                 }
                 //始終會加入新教室,除非只是單純的換座號或是姓名
-                if (classInfo.Count == 0 || studentsClassInfo.Count != 0) //透過學生id查找教室,但沒找到任何已加入的教室
+                if (classInfo.Count == 0 || students.Count != 0) //透過學生id查找教室,但沒找到任何已加入的教室
                 {
                     //使用classId來查詢教室資訊
-                    var classInfos = await getClassInfoUseId(schoolId, studentsClassInfo.Select(o => o.Value.classId).ToList());
+                    var classInfos = await getClassInfoUseId(schoolId, students.Select(o => o.Value.classId).ToList());
                     if (classInfos.Count != 0)
                     {
                         foreach (var item in classInfos)
@@ -1493,7 +1542,7 @@ namespace TEAMModelOS.Controllers
                             }
 
                             //將欲加入的學生寫入該教室名單內
-                            var studList = studentsClassInfo
+                            var studList = students
                                 .Where(o => o.Value.classId.Equals(classId, StringComparison.Ordinal))
                                 .Select(o => new { id = o.Key, o.Value.name, o.Value.no }).ToList();
                             foreach (var stud in studList)