소스 검색

[API-Student]更新StudentManage Read功能。

Mickey 4 년 전
부모
커밋
f706b608a5
1개의 변경된 파일194개의 추가작업 그리고 29개의 파일을 삭제
  1. 194 29
      TEAMModelOS/Controllers/School/StudentController.cs

+ 194 - 29
TEAMModelOS/Controllers/School/StudentController.cs

@@ -96,24 +96,30 @@ namespace TEAMModelOS.Controllers
                         return this.Ok(new { students = ret, existId, errorYear });
                     case "read":
                         //針對給的參數來查詢學生,包含使用offset+limit或是接續token等方法查詢。
-                        int offset = 0, limit = 0;
-                        string token = string.Empty;
-                        if (request.TryGetProperty("token", out JsonElement tmpToken))
-                        {
-                            token = tmpToken.GetString();
-                        }
-                        else if (request.TryGetProperty("offset", out JsonElement tmpOffset)
-                                && request.TryGetProperty("limit", out JsonElement tmpLimit))
-                        {
-                            offset = tmpOffset.GetInt32();
-                            limit = tmpLimit.GetInt32();
-                        }
-                        var (students, continuationToken) = await getStudents(schoolId.GetString(), offset, limit, token);
-                        return this.Ok(new { students, token = continuationToken });
+                        //int offset = -1, limit = -1;
+                        //string token = string.Empty, byYear = string.Empty, byClassId = string.Empty;
+
+                        //if (request.TryGetProperty("year", out JsonElement tmpYear)) byYear = tmpYear.GetString();
+                        //if (request.TryGetProperty("classRoomId", out JsonElement tmpClassRoomId)) byClassId = tmpClassRoomId.GetString();
+
+                        //if (request.TryGetProperty("token", out JsonElement tmpToken) && !string.IsNullOrWhiteSpace(tmpToken.GetString()))
+                        //{
+                        //    token = tmpToken.GetString();
+                        //}
+                        //else if (request.TryGetProperty("offset", out JsonElement tmpOffset)
+                        //        && request.TryGetProperty("limit", out JsonElement tmpLimit))
+                        //{
+                        //    offset = tmpOffset.GetInt32();
+                        //    limit = tmpLimit.GetInt32();
+                        //}
+                        var students = await getAllStudent(schoolId.GetString());
+                        return this.Ok(new { students });
                     case "update":
                         //更新學生資料,批量密碼重置,基本資訊更新(姓名、教室ID及座號)
-                        await updateStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
-                        await updateClassStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
+                        var (dicStudent, nonexistentIds) = await updateStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
+                        var studentClass = await updateClassStudents(schoolId.GetString(), request.GetProperty("students").EnumerateArray());
+
+                        //var ret = dicStudent.Select(o=>new {  });
                         return this.Ok();
                     case "delete":
                         //刪除學生資料及從教室學生名單內移除該學生
@@ -136,7 +142,7 @@ namespace TEAMModelOS.Controllers
         /// 創建學生帳號,目前SDK4.0預覽版還不支援批量創建(TransactionalBatch),待SDK正式發行時在優化此代碼。
         /// </summary>
         /// <param name="schoolId">學校簡碼</param>
-        /// <param name="students">{ "id":"","name":"","no":"","pw":"","year":"","classId":"","className":"" }</param>
+        /// <param name="students">[{ "id":"","name":"","no":"","pw":"","year":"","classId":"","className":"" }]</param>
         /// <returns></returns>
         private async Task<(
             Dictionary<string, string> classInfo,
@@ -330,6 +336,7 @@ namespace TEAMModelOS.Controllers
                 writer.WriteNull("name");
                 writer.WriteEndObject();
                 writer.WriteNull("gradeId");
+                writer.WriteNull("periodId");
                 writer.WriteNull("sn");
                 writer.WriteNull("style");
                 writer.WriteNull("timetable");
@@ -354,23 +361,54 @@ namespace TEAMModelOS.Controllers
         /// 使用學校代碼查詢該校所有學生,並且在查詢該學生所屬的教室及座號,支援offset和limit操作已及ContinuationToken,若有ContinuationToken,則會優先使用ContinuationToken。
         /// </summary>
         /// <param name="schoolId"></param>
+        /// <param name="byNameOrId">透過Name或Id來查,所以不會管學制、學級和教室</param>
+        /// <param name="byPeriod"></param>
+        /// <param name="byGrade"></param>
+        /// <param name="byClassId"></param>
         /// <param name="offset"></param>
         /// <param name="limit"></param>
         /// <param name="token"></param>
         /// <returns></returns>
-        private async Task<(List<object> students, string continuationToken)> getStudents(string schoolId, int offset = 0, int limit = 0, string token = default)
+        private async Task<(List<object> students, string continuationToken)> getStudents(string schoolId,string byNameOrId = null, string byPeriod = null, string byGrade = null, string byClassId = null, int offset = -1, int limit = -1, string token = default)
         {
             try
-            {
+            {   //TODO : 進階查詢選項調整 
                 //以學校學生角度去抓資料
-                List<(string id, string name, string pic)> listStudent = new List<(string id, string name, string pic)>();
+                List<(string id, string name, string pic, string year)> listStudent = new List<(string id, string name, string pic, string year)>();
                 string queryText = $"SELECT c.id, c.name, c.picture, c.year FROM c WHERE c.pk = 'Base'";
 
+                //如果有選擇ClassId的話,則先取得該教室內的學生。
+                List<string> searchId = new List<string>();
+                if (!string.IsNullOrWhiteSpace(byClassId))
+                {
+                    var classInfos = await getClassInfoUseId(schoolId, new List<string>() { byClassId });
+                    foreach (var classInfo in classInfos)
+                    {
+                        var students = classInfo.Value.GetProperty("students").EnumerateArray();
+                        while (students.MoveNext())
+                        {
+                            JsonElement stud = students.Current;
+                            string id = stud.GetProperty("id").GetString();
+                            searchId.Add(id);
+                        }
+                    }
+                    //將使用者過濾classId所取得的學生ID加入sql字串內
+                    if (searchId.Count != 0)
+                    {
+                        queryText = $"{queryText} AND c.id IN ({string.Join(",", searchId.Select(o => $"'{o}'"))})";
+                    }
+                }
+
+                //if (!string.IsNullOrWhiteSpace(byYear))
+                //{
+                //    queryText = $"{queryText} AND c.year = '{byYear}'";
+                //}
+
                 //檢查是否有接續token及是否要在sql語法內多增加offset及limit
                 if (string.IsNullOrWhiteSpace(token))
                 {
                     token = default;
-                    if (offset != 0 && limit != 0) queryText = $"{queryText} OFFSET {offset} LIMIT {limit}";
+                    if (offset != -1 && limit != -1) queryText = $"{queryText} OFFSET {offset} LIMIT {limit}";
                 }
 
                 //回傳用ContinuationToken
@@ -391,7 +429,7 @@ namespace TEAMModelOS.Controllers
                         while (accounts.MoveNext())
                         {
                             JsonElement account = accounts.Current;
-                            listStudent.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(), account.GetProperty("picture").GetString()));
+                            listStudent.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(), account.GetProperty("picture").GetString(), account.GetProperty("year").GetString()));
                         }
                     }
                     //單筆查詢上限為100條,所以查完一次即返回,並且給接續token。
@@ -431,6 +469,7 @@ namespace TEAMModelOS.Controllers
                                             o.id,
                                             o.name,
                                             o.pic,
+                                            o.year,
                                             no = stud.GetProperty("no").GetString(),
                                             gradeId = classroom.GetProperty("gradeId").GetString(),
                                             className = classroom.GetProperty("name").GetString()
@@ -448,6 +487,7 @@ namespace TEAMModelOS.Controllers
                                             o.id,
                                             o.name,
                                             o.pic,
+                                            o.year,
                                             no = (string)null,
                                             gradeId = (string)null,
                                             className = (string)null
@@ -466,6 +506,113 @@ namespace TEAMModelOS.Controllers
             return (null, null);
         }
 
+        /// <summary>
+        /// 取得該學校的所有學生。
+        /// </summary>
+        /// <param name="schoolId"></param>
+        /// <returns></returns>
+        private async Task<List<object>> getAllStudent(string schoolId)
+        {
+            try
+            {   //TODO : 進階查詢選項調整 
+                //以學校學生角度去抓資料
+                List<(string id, string name, string pic, string year)> listStudent = new List<(string id, string name, string pic, string year)>();
+                string queryText = $"SELECT c.id, c.name, c.picture, c.year FROM c WHERE c.pk = 'Base'";
+
+                //回傳用ContinuationToken
+                string continuationToken = string.Empty;
+
+                //進行學生資料的查詢 TEAMModelOS-Student
+                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Student")
+                   .GetItemQueryStreamIterator(
+                       queryText: queryText,
+                       requestOptions: new QueryRequestOptions()
+                       { PartitionKey = new PartitionKey($"Base-{schoolId}"), MaxItemCount = -1 }))
+                {
+                    continuationToken = item.GetContinuationToken();
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                        while (accounts.MoveNext())
+                        {
+                            JsonElement account = accounts.Current;
+                            listStudent.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString(), account.GetProperty("picture").GetString(), account.GetProperty("year").GetString()));
+                        }
+                    }
+                }
+
+                //查學生所屬的教室及座號
+                List<object> ret = new List<object>();
+                //查教室資訊,使用上面的學生id並透過子查詢查詢。
+                queryText = $"SELECT c.id, c.students, c.gradeId , c.periodId FROM c WHERE c.code = 'Class-{schoolId}'";
+                await foreach (Response item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School")
+                   .GetItemQueryStreamIterator(
+                   queryText: queryText,
+                   //continuationToken: token,
+                   requestOptions: new QueryRequestOptions()
+                   { PartitionKey = new PartitionKey($"Class-{schoolId}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        var classrooms = json.RootElement.GetProperty("Documents").EnumerateArray();
+                        while (classrooms.MoveNext())
+                        {
+                            JsonElement classroom = classrooms.Current;
+
+                            var studs = classroom.GetProperty("students").EnumerateArray();
+                            while (studs.MoveNext())
+                            {
+                                JsonElement stud = studs.Current;
+                                string id = stud.GetProperty("id").GetString();
+                                //整理出前端所需的資訊
+                                var tmp = listStudent
+                                    .Where(o => o.id.Equals(id, StringComparison.Ordinal))
+                                    .Select(o =>
+                                        new
+                                        {
+                                            o.id,
+                                            o.name,
+                                            o.pic,
+                                            o.year,
+                                            no = stud.GetProperty("no").GetString(),
+                                            gradeId = classroom.GetProperty("gradeId").GetString(),
+                                            classId = classroom.GetProperty("id").GetString(),
+                                            periodId = classroom.GetProperty("periodId").GetString()
+                                        });
+                                ret.AddRange(tmp);
+                                //刪除已整理完的ID
+                                listStudent.RemoveAll(o => o.id.Equals(id, StringComparison.Ordinal));
+                            }
+                        }
+                    }
+                }
+                var notJoinClassStuds = listStudent.Select(o =>
+                                        new
+                                        {
+                                            o.id,
+                                            o.name,
+                                            o.pic,
+                                            o.year,
+                                            no = (string)null,
+                                            gradeId = (string)null,
+                                            className = (string)null
+                                        });
+                ret.AddRange(notJoinClassStuds);
+                return ret;
+            }
+            catch (CosmosException ex)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},Student/getStudents()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},Student/getStudents()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
+            }
+            return null;
+        }
+
         /// <summary>
         /// 使用學生ID來查詢所屬的教室
         /// </summary>
@@ -1000,12 +1147,17 @@ namespace TEAMModelOS.Controllers
         /// <param name="schoolId"></param>
         /// <param name="students"></param>
         /// <returns></returns>
-        private async Task updateClassStudents(string schoolId, JsonElement.ArrayEnumerator students)
+        private async Task<Dictionary<string, (string classId, string className, string name, string no)>> updateClassStudents(string schoolId, JsonElement.ArrayEnumerator students)
         {
             try
             {
+                //輸出用資料格式
+                Dictionary<string, (string classId, string className, string name, string no)> retStudentsClassInfo 
+                    = new Dictionary<string, (string classId, string className, string name, string no)>();
+
                 //整理輸入的資料
-                Dictionary<string, (string classId, string name, string no)> studentsClassInfo = new Dictionary<string, (string classId, string name, string no)>();
+                Dictionary<string, (string classId, string className, string name, string no)> studentsClassInfo
+                    = new Dictionary<string, (string classId, string className, string name, string no)>();
                 while (students.MoveNext())
                 {
                     JsonElement student = students.Current;
@@ -1013,18 +1165,18 @@ namespace TEAMModelOS.Controllers
                     {
                         if (!string.IsNullOrWhiteSpace(tmpId.GetString()))
                         {
-                            string classId = string.Empty, no = string.Empty, name = string.Empty;
+                            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("className", out var tmpClassName)) classId = tmpClassName.GetString();
                             if (student.TryGetProperty("no", out var tmpNo)) no = tmpNo.GetString();
 
-                            studentsClassInfo.Add(tmpId.GetString(), (classId, name, no));
+                            studentsClassInfo.Add(tmpId.GetString(), (classId, className, name, no));
                         }
                     }
                 }
-
-                if (studentsClassInfo.Count == 0) return;
+                if (studentsClassInfo.Count == 0) return retStudentsClassInfo;
 
                 //透過id查找已加入的教室
                 var classInfo = await getClassInfoUseStudent(schoolId, studentsClassInfo.Select(o => o.Key).ToList());
@@ -1038,6 +1190,8 @@ namespace TEAMModelOS.Controllers
                         if (item.TryGetProperty("id", out var tmpClassId))
                         {
                             string classId = tmpClassId.GetString();
+                            string className = string.Empty;
+                            if (item.TryGetProperty("name", out var tmpClassName)) className = tmpClassName.GetString();
 
                             using var memoryStream = new MemoryStream();
                             using var writer = new Utf8JsonWriter(memoryStream);
@@ -1069,6 +1223,8 @@ namespace TEAMModelOS.Controllers
                                     //如果是相同的教室id
                                     if (studentsClassInfo[studId].classId.Equals(classId, StringComparison.Ordinal))
                                     {
+                                        retStudentsClassInfo.Add(studId, (classId, className, name, no));
+
                                         //座號及姓名檢查,如果不相同則進行更新
                                         if (
                                             studentsClassInfo[studId].no.Equals(no, StringComparison.Ordinal)
@@ -1092,6 +1248,8 @@ namespace TEAMModelOS.Controllers
                                             if (string.IsNullOrWhiteSpace(studentsClassInfo[studId].no)) writer.WriteNull("no");
                                             else writer.WriteString("no", studentsClassInfo[studId].no);
                                             writer.WriteEndObject();
+                                            //更新輸出結果的資料
+                                            retStudentsClassInfo[studId] = (classId, className, studentsClassInfo[studId].name, studentsClassInfo[studId].no);
                                         }
                                         //將已處理好的學生從字典裡移除
                                         studentsClassInfo.Remove(studId);
@@ -1144,6 +1302,8 @@ namespace TEAMModelOS.Controllers
                         foreach (var item in classInfos)
                         {
                             string classId = item.Key;
+                            string className = string.Empty;
+                            if (item.Value.TryGetProperty("name", out var tmpClassName)) className = tmpClassName.GetString();
 
                             #region 組JSON
                             using var memoryStream = new MemoryStream();
@@ -1193,13 +1353,15 @@ namespace TEAMModelOS.Controllers
                                 if (string.IsNullOrWhiteSpace(stud.no)) writer.WriteNull("no");
                                 else writer.WriteString("no", stud.no);
                                 writer.WriteEndObject();
+
+                                retStudentsClassInfo.Add(stud.id, (classId, className, stud.name, stud.no));
                             }
 
                             writer.WriteEndArray();
                             writer.WriteEndObject();
                             writer.Flush();
                             #endregion
-                            var resultJson = Encoding.UTF8.GetString(memoryStream.ToArray());
+                            //var resultJson = Encoding.UTF8.GetString(memoryStream.ToArray());
 
                             try
                             {
@@ -1223,6 +1385,8 @@ namespace TEAMModelOS.Controllers
                         //透過教室ID進行查詢,但查不到這間教室
                     }
                 }
+
+                return retStudentsClassInfo;
             }
             catch (CosmosException ex)
             {
@@ -1232,6 +1396,7 @@ namespace TEAMModelOS.Controllers
             {
                 await _dingDing.SendBotMsg($"OS,{_option.Location},Student/updateClassStudents()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
             }
+            return null;
         }
 
         /// <summary>