CrazyIter_Bin 4 lat temu
rodzic
commit
a41c5f553a
75 zmienionych plików z 2707 dodań i 1132 usunięć
  1. 3 5
      TEAMModelFunction/ActivityHttpTrigger.cs
  2. 3 3
      TEAMModelFunction/MonitorCosmosDB.cs
  3. 9 32
      TEAMModelFunction/TriggerExam.cs
  4. 36 16
      TEAMModelFunction/TriggerSurvey.cs
  5. 18 8
      TEAMModelFunction/TriggerVote.cs
  6. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Common/ActivityData.cs
  7. 33 29
      TEAMModelOS.SDK/Models/Cosmos/Common/Survey.cs
  8. 6 2
      TEAMModelOS.SDK/Models/Cosmos/Common/Vote.cs
  9. 4 4
      TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs
  10. 4 2
      TEAMModelOS/ClientApp/public/index.html
  11. 5 7
      TEAMModelOS/ClientApp/src/assets/student-web/component_styles/vote.css
  12. 1 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue
  13. 1 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseMultiple.vue
  14. 15 5
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  15. 4 0
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.less
  16. 29 26
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue
  17. 1 7
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.vue
  18. 0 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.vue
  19. 2 29
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  20. 4 5
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/StudentScore.vue
  21. 8 16
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue
  22. 11 10
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  23. 41 21
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue
  24. 67 43
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue
  25. 6 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/VoteResultChart.vue
  26. 26 37
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  27. 21 7
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  28. 5 0
      TEAMModelOS/ClientApp/src/css/site.css
  29. 7 2
      TEAMModelOS/ClientApp/src/utils/editorTools.js
  30. 1 3
      TEAMModelOS/ClientApp/src/utils/evTools.js
  31. 5 4
      TEAMModelOS/ClientApp/src/utils/kityformula.js
  32. 92 52
      TEAMModelOS/ClientApp/src/utils/public.js
  33. 13 0
      TEAMModelOS/ClientApp/src/view/Home.vue
  34. 1 0
      TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue
  35. 1 4
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue
  36. 1 4
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue
  37. 33 21
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue
  38. 86 87
      TEAMModelOS/ClientApp/src/view/evaluation/components/BasePoints.vue
  39. 4 7
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.vue
  40. 2 8
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue
  41. 1 4
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompose.vue
  42. 2 8
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseConnector.vue
  43. 2 8
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCorrect.vue
  44. 1 4
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseJudge.vue
  45. 3 10
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue
  46. 3 11
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  47. 2 8
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSubjective.vue
  48. 38 16
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue
  49. 8 8
      TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue
  50. 5 5
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue
  51. 3 3
      TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue
  52. 11 5
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue
  53. 97 0
      TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.less
  54. 703 0
      TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.vue
  55. 48 28
      TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue
  56. 2 2
      TEAMModelOS/ClientApp/src/view/learnactivity/SimpleAnalysis.vue
  57. 26 0
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less
  58. 187 20
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue
  59. 5 1
      TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.less
  60. 433 91
      TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue
  61. 22 2
      TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.less
  62. 31 21
      TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue
  63. 8 7
      TEAMModelOS/ClientApp/src/view/newcourse/TimeSetting.vue
  64. 81 42
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  65. 42 20
      TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue
  66. 3 3
      TEAMModelOS/Controllers/Analysis/AchievementController.cs
  67. 1 1
      TEAMModelOS/Controllers/Analysis/AnalysisController.cs
  68. 45 35
      TEAMModelOS/Controllers/Common/ExamController.cs
  69. 10 10
      TEAMModelOS/Controllers/Common/SurveyController.cs
  70. 5 7
      TEAMModelOS/Controllers/Common/VoteController.cs
  71. 22 4
      TEAMModelOS/Controllers/Core/ImportController.cs
  72. 136 131
      TEAMModelOS/Controllers/School/ClassRoomController.cs
  73. 1 1
      TEAMModelOS/Controllers/Teacher/TeacherCommonController.cs
  74. 6 6
      TEAMModelOS/Services/Common/ActivityStudentService.cs
  75. 104 97
      TEAMModelOS/Services/Common/ActivityTeacherService.cs

+ 3 - 5
TEAMModelFunction/ActivityHttpTrigger.cs

@@ -70,17 +70,16 @@ namespace TEAMModelFunction
                         dataa = new ActivityData
                         {
                             id = info.id,
-                            code = $"Activity-{info.owner}",
+                            code = $"Activity-{info.school}",
                             type = "exam",
                             name = info.name,
                             startTime = info.startTime,
                             endTime = info.endTime,
                             scode = info.code,
                             scope = info.scope,
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids = new List<string> { "" },
                             progress = "going",
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(dataa, new Azure.Cosmos.PartitionKey(dataa.code));
@@ -98,9 +97,8 @@ namespace TEAMModelFunction
                             scode = info.code,
                             scope = info.scope,
                             progress = "going",
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids = new List<string> { "" },
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(dataa, new Azure.Cosmos.PartitionKey(dataa.code));

+ 3 - 3
TEAMModelFunction/MonitorCosmosDB.cs

@@ -53,7 +53,7 @@ namespace TEAMModelFunction
                         long etime = input.GetPropertyValue<long>("endTime");
                         string school = input.GetPropertyValue<string>("school");
                         string code = input.GetPropertyValue<string>("code");
-                        string owner = input.GetPropertyValue<string>("owner");
+                        string creatorId = input.GetPropertyValue<string>("creatorId");
                         string progress = input.GetPropertyValue<string>("progress");
                         string scope = input.GetPropertyValue<string>("scope");
                         string name = input.GetPropertyValue<string>("name");
@@ -63,7 +63,7 @@ namespace TEAMModelFunction
                             etime = etime,
                             school = school,
                             code = code,
-                            owner = owner,
+                            creatorId = creatorId,
                             progress = progress,
                             scope = scope,
                             ttl = ttl,
@@ -97,7 +97,7 @@ namespace TEAMModelFunction
         public long etime { get; set; }
         public string school { get; set; }
         public string code { get; set; }
-        public string owner { get; set; }
+        public string creatorId { get; set; }
         public string progress { get; set; }
         public string scope { get; set; }
         public int ttl { get; set; }

+ 9 - 32
TEAMModelFunction/TriggerExam.cs

@@ -94,17 +94,16 @@ namespace TEAMModelFunction
                         data = new ActivityData
                         {
                             id = info.id,
-                            code = $"Activity-{info.owner}",
+                            code = $"Activity-{info.school}",
                             type = "exam",
                             name = info.name,
                             startTime = info.startTime,
                             endTime = info.endTime,
                             scode = info.code,
                             scope = info.scope,
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids =  new List<string> { "" },
                             progress = "going",
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
@@ -122,16 +121,15 @@ namespace TEAMModelFunction
                             scode = info.code,
                             scope = info.scope,
                             progress = "going",
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids = new List<string> { "" },
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
                     }
                     if (examClassResults.Count == 0)
                     {
-                        foreach (string cla in info.targetClassIds)
+                        foreach (string cla in info.classes)
                         {
                             int m = 0;
                             foreach (ExamSubject subject in info.subjects)
@@ -197,17 +195,8 @@ namespace TEAMModelFunction
 
                                         foreach (Students students in stuList.students)
                                                 {
-                                                    if (students.code.Contains(code))
-                                                    {
-                                                        if (!ids.Contains(students.id))
-                                                        {
-                                                            ids.Add(students.id);
-                                                        }
-                                                    }
-                                                    else
-                                                    {
+
                                                         ids.Add(students.id);
-                                                    }
                                                 }
                                                 if (stuList.tmids.Count > 0)
                                                 {
@@ -229,17 +218,7 @@ namespace TEAMModelFunction
                                         //处理发布对象为自选名单(校本)
                                         foreach (Students students in stuList.students)
                                         {
-                                            if (students.code.Contains(code))
-                                            {
-                                                if (!ids.Contains(students.id))
-                                                {
-                                                    ids.Add(students.id);
-                                                }
-                                            }
-                                            else
-                                            {
                                                 ids.Add(students.id);
-                                            }
                                         }                                      
                                     }                                    
                                 }
@@ -288,7 +267,7 @@ namespace TEAMModelFunction
                         int gno = 0;
                         foreach (ExamSubject subject in info.subjects)
                         {
-                            if (subject.classCount == info.targetClassIds.Count)
+                            if (subject.classCount == info.classes.Count)
                             {
                                 await createClassResultAsync(info, examClassResults, subject, gno,_azureCosmos);
                             }
@@ -309,7 +288,7 @@ namespace TEAMModelFunction
                         data = new ActivityData
                         {
                             id = info.id,
-                            code = $"Activity-{info.owner}",
+                            code = $"Activity-{info.school}",
                             type = "exam",
                             name = info.name,
                             startTime = info.startTime,
@@ -317,9 +296,8 @@ namespace TEAMModelFunction
                             scode = info.code,
                             scope = info.scope,
                             progress = "finish",
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids = new List<string> { "" },
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<ActivityData>(data, info.id, new Azure.Cosmos.PartitionKey(data.code));
@@ -337,9 +315,8 @@ namespace TEAMModelFunction
                             scode = info.code,
                             scope = info.scope,
                             progress = "finish",
-                            classes = info.targetClassIds.IsNotEmpty() ? info.targetClassIds : new List<string> { "" },
+                            classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
                             tmdids = new List<string> { "" },
-                            owner = info.owner,
                             subjects = sub
                         };
                         await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<ActivityData>(data, info.id, new Azure.Cosmos.PartitionKey(data.code));

+ 36 - 16
TEAMModelFunction/TriggerSurvey.cs

@@ -29,7 +29,14 @@ namespace TEAMModelFunction
                 return;
             }
             var adid = tdata.id;
-            var adcode = $"Activity-{tdata.owner}";
+            var adcode = "";
+            if (tdata.scope == "school")
+            {
+                  adcode = $"Activity-{tdata.school}";
+            }
+            else if (tdata.scope == "private"){
+                adcode = $"Activity-{tdata.creatorId}";
+            }
             ActivityData data = null;
             try
             {
@@ -77,7 +84,7 @@ namespace TEAMModelFunction
                             data = new ActivityData
                             {
                                 id = survey.id,
-                                code = $"Activity-{survey.owner}",
+                                code = $"Activity-{survey.school}",
                                 type = "survey",
                                 name = survey.name,
                                 startTime = survey.startTime,
@@ -87,7 +94,6 @@ namespace TEAMModelFunction
                                 classes = survey.classes.IsNotEmpty() ? survey.classes : new List<string> { "" },
                                 tmdids = survey.tmdids.IsNotEmpty() ? survey.tmdids : new List<string> { "" },
                                 progress = "going",
-                                owner = survey.owner,
                                 subjects = new List<string> { "" }
                             };
                             await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
@@ -106,7 +112,6 @@ namespace TEAMModelFunction
                                 scope = survey.scope,
                                 progress = "going",
                                 classes = survey.classes.IsNotEmpty() ? survey.classes : new List<string> { "" },
-                                owner = survey.owner,
                                 tmdids = new List<string> { "" },
                                 subjects = new List<string> { "" }
                             };
@@ -133,40 +138,50 @@ namespace TEAMModelFunction
                             };
                             await _azureStorage.Save<ChangeRecord>(changeRecord);
                         }
+                        await _dingDing.SendBotMsg($"问卷调查{tdata.id}将于:{tdata.etime}完成并结算!", GroupNames.成都开发測試群組);
                         break;
                     case "finish":
+                        await _dingDing.SendBotMsg($"问卷调查{tdata.id}开始结算{tdata.etime}!", GroupNames.成都开发測試群組);
                         var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Survey:Record:{survey.id}");
+                        var submits = await _azureRedis.GetRedisClient(8).SetMembersAsync($"Survey:Submit:{survey.id}");
                         List<dynamic> recs = new List<dynamic>();
                         foreach (var rcd in records)
                         {
                             var value = rcd.Value.ToString().ToObject<JsonElement>();
                             recs.Add(new { index = rcd.Name.ToString(), ans = value });
                         }
-                        var cods = new { records = recs };
+
+                        List<dynamic> userids = new List<dynamic>();
+                        foreach (var submit in submits)
+                        {
+                            var value = submit.ToString();
+                            userids.Add(value);
+                        }
+                        var cods = new { records = recs, userids };
                         //问卷整体情况
-                        await _azureStorage.UploadFileByContainer(survey.owner, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
+                        await _azureStorage.UploadFileByContainer(survey.blobcntr, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
                         //结算每道题的答题情况
-                        var ContainerClient =  _azureStorage.GetBlobContainerClient(survey.owner);
-                           
+                        var ContainerClient =  _azureStorage.GetBlobContainerClient(survey.blobcntr);
+                        List<Task<string>> tasks = new List<Task<string>>();
                         //获取
                         try {
                             List<string> items = await ContainerClient.List($"survey/{survey.id}/urecord");
                             List<SurveyRecord> surveyRecords = new List<SurveyRecord>();
                             foreach (string item in items)
                             {
-                                var Download = await _azureStorage.GetBlobContainerClient(survey.owner).GetBlobClient(item).DownloadAsync();
+                                var Download = await _azureStorage.GetBlobContainerClient(survey.blobcntr).GetBlobClient(item).DownloadAsync();
                                 var json = await JsonDocument.ParseAsync(Download.Value.Content);
                                 var Record = json.RootElement.ToObject<SurveyRecord>();
                                 surveyRecords.Add(Record);
                             }
                             await _dingDing.SendBotMsg($"问卷调查问题结算数据{surveyRecords.ToJsonString()}", GroupNames.成都开发測試群組);
-                            for (int index = 0; index < survey.ans.Count; index++)
+                            for (int index = 0; index < survey.answers.Count; index++)
                             {
                                 string url = $"{survey.id}/qrecord/{index}.json";
                                 QuestionRecord question = new QuestionRecord() { index = index };
                                 foreach (SurveyRecord record in surveyRecords)
                                 {
-                                    if (record.ans.Count == survey.ans.Count)
+                                    if (record.ans.Count == survey.answers.Count)
                                     {
                                         foreach (var an in record.ans[index])
                                         {
@@ -184,7 +199,7 @@ namespace TEAMModelFunction
                                             }
                                             else
                                             {
-                                                if (survey.ans[index].Contains(an))
+                                                if (survey.answers[index].Contains(an))
                                                 {
                                                     //如果是客观题code
                                                     question.opt.Add(an, new HashSet<string> { record.userid });
@@ -198,8 +213,9 @@ namespace TEAMModelFunction
                                         }
                                     }
                                 }
-                                await _azureStorage.UploadFileByContainer(survey.owner, question.ToJsonString(), "survey", url);
+                                tasks.Add(  _azureStorage.UploadFileByContainer(survey.blobcntr, question.ToJsonString(), "survey", url));
                             }
+                            await Task.WhenAll(tasks);
                         } catch (Exception ex) {
                             await _dingDing.SendBotMsg($"问卷调查问题结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
                         }
@@ -208,7 +224,12 @@ namespace TEAMModelFunction
                             survey.recordUrl = $"/survey/{survey.id}/record.json";
                             await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Survey>(survey, survey.id, new Azure.Cosmos.PartitionKey(survey.code));
                         }
-                        // await Task.WhenAll(tasks);
+                        else {
+                            _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Record:{survey.id}");
+                            _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Submit:{survey.id}");
+                            break;
+                        }
+                        
                         //更新结束状态
                         data.progress = "finish";
                         if (survey.scope == "school")
@@ -219,8 +240,7 @@ namespace TEAMModelFunction
                         {
                             await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<ActivityData>(data, data.id, new Azure.Cosmos.PartitionKey(data.code));
                         }
-                        _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Record:{survey.id}");
-                        _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Submit:{survey.id}");
+                        
                         break;
                 }
             }

+ 18 - 8
TEAMModelFunction/TriggerVote.cs

@@ -27,7 +27,15 @@ namespace TEAMModelFunction
                 return;
             }
             var adid = tdata.id;
-            var adcode = $"Activity-{tdata.owner}";
+            var adcode = "";
+            if (tdata.scope == "school")
+            {
+                adcode = $"Activity-{tdata.school}";
+            }
+            else if (tdata.scope == "private")
+            {
+                adcode = $"Activity-{tdata.creatorId}";
+            }
             ActivityData data = null;
             try
             {
@@ -79,7 +87,7 @@ namespace TEAMModelFunction
                             data = new ActivityData
                             {
                                 id = vote.id,
-                                code = $"Activity-{vote.owner}",
+                                code = $"Activity-{vote.school}",
                                 type = "vote",
                                 name = vote.name,
                                 startTime = vote.startTime,
@@ -89,7 +97,6 @@ namespace TEAMModelFunction
                                 classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
                                 tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
                                 progress = "going",
-                                owner = vote.owner,
                                 subjects = new List<string> { "" }
                             };
                             await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
@@ -108,7 +115,6 @@ namespace TEAMModelFunction
                                 scope = vote.scope,
                                 progress = "going",
                                 classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
-                                owner = vote.owner,
                                 tmdids = new List<string> { "" },
                                 subjects = new List<string> { "" }
                             };
@@ -135,8 +141,10 @@ namespace TEAMModelFunction
                             };
                             await _azureStorage.Save<ChangeRecord>(changeRecord);
                         }
+                        await _dingDing.SendBotMsg($"投票活动{tdata.id}将于:{tdata.etime}完成并结算!", GroupNames.成都开发測試群組);
                         break;
                     case "finish":
+                        await _dingDing.SendBotMsg($"投票活动{tdata.id}开始结算{tdata.etime}!", GroupNames.成都开发測試群組);
                         //获取投票活动的所有投票记录
                         var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Vote:Record:{vote.id}");
                         //获取投票活动的选项及投票数
@@ -160,11 +168,11 @@ namespace TEAMModelFunction
                         var gp = recordsBlob.GroupBy(x => x.userid).Select(x => new { key = x.Key, list = x.ToList() });
                         foreach (var g in gp)
                         {
-                            tasks.Add(_azureStorage.UploadFileByContainer(vote.owner, g.list.ToJsonString(), "vote", $"{vote.id}/urecord/{g.key}.json"));
+                            tasks.Add(_azureStorage.UploadFileByContainer(vote.blobcntr, g.list.ToJsonString(), "vote", $"{vote.id}/urecord/{g.key}.json"));
                         }
                         //处理活动方的记录, 
                         string url = $"/vote/{vote.id}/record.json";
-                        tasks.Add(_azureStorage.UploadFileByContainer(vote.owner, new { options = countcds, records = recordsBlob }.ToJsonString(), "vote", $"{vote.id}/record.json"));
+                        tasks.Add(_azureStorage.UploadFileByContainer(vote.blobcntr, new { options = countcds, records = recordsBlob }.ToJsonString(), "vote", $"{vote.id}/record.json"));
                         //处理投票者的记录
 
                         if (string.IsNullOrEmpty(vote.recordUrl))
@@ -172,9 +180,11 @@ namespace TEAMModelFunction
                             vote.recordUrl = url;
                             await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Vote>(vote, vote.id, new Azure.Cosmos.PartitionKey(vote.code));
                         }
-                        else { 
+                        else {
                             //异动,且已经有结算记录则不必再继续。
-                            //break; 
+                            _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Record:{vote.id}");
+                            _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Count:{vote.id}");
+                            break; 
                         }
                         await Task.WhenAll(tasks);
                         data.progress = "finish";

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/ActivityData.cs

@@ -82,7 +82,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos
         public string scope { get; set; }
         public List<string> classes { get; set; } = new List<string> { "" };
         public List<string> tmdids { get; set; } = new List<string> { "" };
-        public string owner { get; set; }
+        //public string owner { get; set; }
         public List<string> subjects { get; set; } = new List<string> { "" };
     }
 }

+ 33 - 29
TEAMModelOS.SDK/Models/Cosmos/Common/Survey.cs

@@ -20,10 +20,14 @@ namespace TEAMModelOS.SDK.Models
             tmdids = new List<string>();
         }
         /// <summary>
+        /// blob容器名
+        /// </summary>
+        public string blobcntr { get; set; }
+        /// <summary>
         /// 学校编码或教室tmdid
         /// </summary>
         [Required(ErrorMessage = "owner 必须设置")]
-        public string owner { get; set; }
+        public string school { get; set; }
         /// <summary>
         /// 问卷名称
         /// </summary>
@@ -65,7 +69,7 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public long updateTime { get; set; }
         //将问题放入Blob  hbcn/survey/问卷调查id.json  存放内容 Question的数组
-        public List<string> questionUrl { get; set; }
+        public string  blob { get; set; }
         // public List<Question> questions { get; set; }
         /// <summary>
         /// 学生作答记录/ 状态为finish时进行结算
@@ -75,7 +79,7 @@ namespace TEAMModelOS.SDK.Models
         /// 如果本题不是客观题 则为[]空数组
         /// 客观题所有选项[["A","B","C","D"],["A","B"],[],["A","B"]]
         /// </summary>
-        public List<List<string>> ans { get; set; }
+        public List<List<string>> answers { get; set; }
         /// <summary>
         /// TTL删除改变状态使用
         /// </summary>
@@ -85,30 +89,30 @@ namespace TEAMModelOS.SDK.Models
     /// <summary>
     ///问卷题目
     /// </summary>
-    public class Question {
-        /// <summary>
-        /// 题目id
-        /// </summary>
-        public string qid { get; set; }
-        /// <summary>
-        /// 问卷题目
-        /// </summary>
-        public string question { get; set; }
-        /// <summary>
-        /// 问卷题目的描述
-        /// </summary>
-        public string description { get; set; }
-        /// <summary>
-        /// 问卷选项
-        /// </summary>
-        public List<CodeValue> options { get; set; }
-        /// <summary>
-        /// 判断judge  多选multiple 单选single
-        /// </summary>
-        public string type { get; set; }
-        /// <summary>
-        /// 是否必需作答
-        /// </summary>
-        public bool required { get; set; }
-    }
+    //public class Question {
+    //    /// <summary>
+    //    /// 题目id
+    //    /// </summary>
+    //    public string qid { get; set; }
+    //    /// <summary>
+    //    /// 问卷题目
+    //    /// </summary>
+    //    public string question { get; set; }
+    //    /// <summary>
+    //    /// 问卷题目的描述
+    //    /// </summary>
+    //    public string description { get; set; }
+    //    /// <summary>
+    //    /// 问卷选项
+    //    /// </summary>
+    //    public List<CodeValue> options { get; set; }
+    //    /// <summary>
+    //    /// 判断judge  多选multiple 单选single
+    //    /// </summary>
+    //    public string type { get; set; }
+    //    /// <summary>
+    //    /// 是否必需作答
+    //    /// </summary>
+    //    public bool required { get; set; }
+    //}
 }

+ 6 - 2
TEAMModelOS.SDK/Models/Cosmos/Common/Vote.cs

@@ -21,10 +21,14 @@ namespace TEAMModelOS.SDK.Models
 
         }
         /// <summary>
+        /// blob容器名
+        /// </summary>
+        public string blobcntr { get; set; }
+        /// <summary>
         /// 学校编码或教师tmdid
         /// </summary>
         [Required(ErrorMessage = "owner 必须设置")]
-        public string owner { get; set; }
+        public string school { get; set; }
         /// <summary>
         /// 投票名称
         /// </summary>
@@ -36,7 +40,7 @@ namespace TEAMModelOS.SDK.Models
         [Required(ErrorMessage = "creatorId 必须设置")]
         public string creatorId { get; set; }
         /// <summary>
-        /// 投票描述
+        /// 投票描述 
         /// </summary>
         public string description { get; set; }
         /// <summary>

+ 4 - 4
TEAMModelOS.SDK/Models/Cosmos/School/ExamInfo.cs

@@ -20,12 +20,12 @@ namespace TEAMModelOS.SDK.Models
             grades = new List<Grade>();
             subjects = new List<ExamSubject>();
             papers = new List<PaperSimple>();
-            targetClassIds = new List<string>();
+            classes = new List<string>();
         }
         /// <summary>
-        /// 学校编码或教室tmdid
+        /// blob容器名
         /// </summary>
-        public string owner { get; set; }
+        public string blobcntr { get; set; }
         public string name { get; set; }
         public string school { get; set; }
         public string creatorId { get; set; }
@@ -61,7 +61,7 @@ namespace TEAMModelOS.SDK.Models
         public int year { get; set; }
         public string range { get; set; }
         public string source { get; set; }
-        public List<string> targetClassIds { get; set; }
+        public List<string> classes { get; set; }
         public List<PaperSimple> papers { get; set; }
         ///考试类型 段考 stage  联考 union 平常考 normal 其他 other
         /// </summary>

+ 4 - 2
TEAMModelOS/ClientApp/public/index.html

@@ -10,6 +10,9 @@
 		<script>
 		MathJax = {
 		  loader: {load: ["input/tex", "output/svg"]},
+		  // mml:{
+			 //  forceReparse:true
+		  // },
 		  tex: {
 		    inlineMath: [['$', '$'], ['\\(', '\\)']],
 			displayMath: [["$$", "$$"], ["\\[", "\\]"]]
@@ -20,9 +23,8 @@
 		};
 		</script>
 		<script type="text/javascript" id="MathJax-script" async
-		  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
+		  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-svg.js">
 		</script>
-		
 		<script>
 			let cloudSetting = localStorage.getItem('cloudSetting')
 			if (cloudSetting) {

+ 5 - 7
TEAMModelOS/ClientApp/src/assets/student-web/component_styles/vote.css

@@ -1,16 +1,14 @@
 .vote .checkAnswer {
-  display: flex;
-  width:100%;
-  margin-top: 20px;
-  margin-left: 0px;
+    display: inline-flex;
+    min-width:100px;
+    margin-top: 15px;
+    margin-right:20px;
 }
 .vote .checkAnswer .testBtn {
   margin: 10px 0px;
   position: relative;
   z-index: 2;
-  width:50%;
   font-weight: bolder;
-  padding-left: 20px;
   cursor: pointer;
 }
 .vote .checkAnswer .testBtn input[type="checkbox"] {
@@ -44,7 +42,7 @@
     .vote  .vote-title {
         width: 100%;
         /*display: flex;*/
-    }
+}
     .vote .vote-title .title-rect-group{
         display:flex;
     }

+ 1 - 1
TEAMModelOS/ClientApp/src/components/questionnaire/BaseJudge.vue

@@ -193,7 +193,7 @@
 
 			// 模拟选项聚焦事件
 			optionClick(index) {
-				let allToolbars = document.getElementsByClassName('option-editor')
+				let allToolbars = document.getElementsByClassName('qn-option-editor')
 				let that = this
 				for (let i = 0; i < allToolbars.length; i++) {
 					allToolbars[i].children[0].style.visibility = 'hidden'

+ 1 - 1
TEAMModelOS/ClientApp/src/components/questionnaire/BaseMultiple.vue

@@ -192,7 +192,7 @@
 
 			// 模拟选项聚焦事件
 			optionClick(index) {
-				let allToolbars = document.getElementsByClassName('option-editor')
+				let allToolbars = document.getElementsByClassName('qn-option-editor')
 				let that = this
 				for (let i = 0; i < allToolbars.length; i++) {
 					allToolbars[i].children[0].style.visibility = 'hidden'

+ 15 - 5
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue

@@ -15,7 +15,7 @@
 				</div>
 				<Select multiple v-model="qnForm.classes" :class="!qnFormEdit ? 'qn-form-disabled':''" :placeholder="$t('survey.form.targetPlace')" v-else>
 					<!-- <Option v-for="(item,index) in classRooms" :value="item.id" :key="index">{{ item.name }}</Option> -->
-						<Option v-for="item in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="item.id">{{ item.name }}</Option>
+						<Option v-for="(item,index) in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="index">{{ item.name }}</Option>
 						<!-- <Option v-for="item in classRooms" :value="item.id" :key="item.id">{{ item.name }}</Option> -->
 				</Select>
 			</FormItem>
@@ -172,8 +172,9 @@
 							params.description = this.qnForm.description
 							// 新增参数
 							params.creatorId = this.$store.state.userInfo.TEAMModelId
-							params.owner = this.$route.name === 'personalSurvey' && this.classType === 'private' ? this.$store.state.userInfo
-								.TEAMModelId : this.$store.state.userInfo.schoolCode
+							params.school = params.scope === 'school' ?  this.$store.state.userInfo.schoolCode : null
+							params.blobcntr = params.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+							
 							
 							// 如果是编辑状态 则直接复制ID 如果是新增 则直接赋值新ID
 							if (this.isEdit && this.editInfo.id && this.editInfo.code) {
@@ -203,7 +204,13 @@
 						code: this.$store.state.userInfo.schoolCode
 					}).then(res => {
 						if (!res.error && res.courses) {
-							r(res.courses)
+							this.$store.dispatch('user/getSchoolProfile').then(schoolProfile => {
+							    let schoolClasses =  schoolProfile.school_classes
+								console.log(schoolClasses)
+								r([...res.courses,...schoolClasses])
+							}).catch(err => {
+								r([])
+							})
 						} else {
 							j(500)
 							this.$Message.error(this.$t('survey.getDataFailTip'))
@@ -255,8 +262,11 @@
 			 * 回显问卷详情
 			 * @param item
 			 */
-			doRender(item) {
+			async doRender(item) {
 				console.log(item)
+				if(!this.classRooms.length){
+					this.classRooms = await this.getClassrooms(this.userInfo.TEAMModelId)
+				}
 				this.qnForm = {
 					name: item.name,
 					classes: item.classes || [],

+ 4 - 0
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.less

@@ -68,6 +68,10 @@
 			cursor: move;
 			user-select: none;
 			
+			.qn-stem p{
+				display: inline-block;
+			}
+			
 			&:hover{
 				background: #ececec;
 				

+ 29 - 26
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue

@@ -16,7 +16,7 @@
 						<p class="qn-stem">
 							<span style="color: red;" v-show="item.required">* </span>
 							<span>{{ index + 1 }}. </span>
-							<span>{{ getSimpleText(item.question) }}</span>
+							<span v-html="item.question"></span>
 							<span>( {{ typeList[item.type] }} )</span>
 						</p>
 						<!-- 单选题-选项 -->
@@ -255,24 +255,31 @@
 					// 根据试卷的Blob地址 去读取JSON文件
 					let sasString = qnItem.scope === 'private' ?  await this.$tools.getPrivateSas() : await this.$tools.getSchoolSas()
 					let promiseArr = []
-					for (let item of qnItem.questionUrl) {
-						promiseArr.push(new Promise(async (r,j) => {
-							try{
-								let itemJson = JSON.parse(await this.$tools.getFile(blobHost + item + sasString.sas))
-								r(itemJson)
-							}catch(e){
-								j(e)
-							}
-						}))
+					let indexJson = await this.getBlobJsonFile(qnItem.scope,qnItem.blob)
+					if(indexJson.slides.length){
+						for (let item of indexJson.slides) {
+							promiseArr.push(new Promise(async (r,j) => {
+								try{
+									let itemJson = JSON.parse(await this.$tools.getFile(blobHost + item + sasString.sas))
+									r(itemJson)
+								}catch(e){
+									j(e)
+								}
+							}))
+						}
+						Promise.all(promiseArr).then(result => {
+							resolve(result)
+						}).catch(err => {
+							reject(err)
+						})
+					}else{
+						resolve([])
 					}
-					Promise.all(promiseArr).then(result => {
-						resolve(result)
-					}).catch(err => {
-						reject(err)
-					})
+					
 				})
 			},
 			
+			
 			// 获取blob里的试题数据
 			getBlobJsonFile(scope,url){
 				return new Promise(async (resolve,reject) => {
@@ -373,23 +380,19 @@
 			currentQn: {
 				async handler(newValue) {
 					/** 编辑回显 */
-					if (newValue) {
-						console.log('问卷接受到的数据 ==',newValue);
-						if(newValue.questionUrl && newValue.questionUrl.length){
-							if(newValue.progress !== 'pending'){
-								let records = await this.getQnRecord(newValue)
-								let items = await this.getBlobItems(newValue)
-								this.makeItemResult(records,items)
-							}else{
-								this.items = await this.getBlobItems(newValue)
-							}
+					if (newValue && newValue.id) {
+						if(newValue.progress !== 'pending'){
+							let records = await this.getQnRecord(newValue)
+							let items = await this.getBlobItems(newValue)
+							this.makeItemResult(records,items)
 						}else{
-							this.items = []
+							this.items = await this.getBlobItems(newValue)
 						}
 						this.isShowAllAnalysis = false
 						this.curIndexList = []
 					} else {
 						/** 新增 */
+						this.items = []
 					}
 				},
 				deep: true,

+ 1 - 7
TEAMModelOS/ClientApp/src/components/questionnaire/BaseSingle.vue

@@ -96,9 +96,6 @@
 					})
 				}
 			},
-			onRichTextClick(e) {
-				this.$parent.onRichTextClick(e)
-			},
 			// 添加选项
 			addOption() {
 				let that = this
@@ -191,7 +188,7 @@
 
 			// 模拟选项聚焦事件
 			optionClick(index) {
-				let allToolbars = document.getElementsByClassName('option-editor')
+				let allToolbars = document.getElementsByClassName('qn-option-editor')
 				let that = this
 				for (let i = 0; i < allToolbars.length; i++) {
 					allToolbars[i].children[0].style.visibility = 'hidden'
@@ -210,9 +207,6 @@
 			stemEditor.config.onchange = (html) => {
 				this.stemContent = html
 			}
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
 			this.$editorTools.initSimpleEditor(stemEditor)
 			stemEditor.create()
 			this.stemEditor = stemEditor

+ 0 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/BillBoardandLightBox.vue

@@ -101,8 +101,6 @@
         watch: {
             voteRes: {
                 handler() {
-                    console.log(this.activityData)
-                    console.log(this.$store.getters.getItemTitle)
                      this.setVoteTable()
                 },
                 // 深度观察监听

+ 2 - 29
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue

@@ -255,10 +255,6 @@
 </template>
 
 <script>
-    //import BlobTool from '@/utils/blobTool.js';
-    //import FileSaver from "file-saver";
-    //import JSZip from "jszip";
-    //import elementResizeDetectorMaker from "element-resize-detector"
     import pdf from 'vue-pdf'
     import LessonTestReportCharts from "./LessonTestReportCharts/LessonTestReportCharts";
     import Loading from "vue-loading-overlay";
@@ -426,10 +422,10 @@
             async getItem(data) { //获取学生作答数据
                 let datas = []
                 if (data !== undefined) {
-                    let key = this.$store.getters.getExamInfo.code.split('-')
+                    let codes = this.$store.getters.getItemTitle.code.split('-')
                     let code = {
                         scope: this.$store.getters.getExamInfo.scope,
-                        code: key[(key.length - 1)],
+                        code: codes[codes.length - 1],
                         blob: data
                     }
                     let blob = this.formUrl(code)
@@ -485,29 +481,6 @@
                if (this.paperData.length) {
                    this.ansData = await this.getItem(this.examInfo.stuAns[0])
                }
-               this.$nextTick(() => {
-                   // window.MathJax.Hub.Queue([
-                   //     "Typeset",
-                   //     MathJax.Hub,
-                   //     this.$refs.qcontent,
-                   // ]);
-               });
-            },
-            getCurrentLang() {
-                return localStorage.getItem('lang');
-            },
-            RandomNum() {
-                return Random.integer(70, 96)
-            },
-            forceRerender() {
-                // remove the my-component component from the DOM
-                this.renderComponent = false;
-
-                this.$nextTick(() => {
-                    // add my-component component in DOM
-                    this.renderComponent = true;
-                });
-
             },
             closeDetail() {
                 this.closeAnsDetail = !this.closeAnsDetail;

+ 4 - 5
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/StudentScore.vue

@@ -290,15 +290,14 @@
                     subItem: [],
                 }
                 if (data !== undefined) {
-                    let key = data.code.split('-')
+                    let key = this.$store.getters.getItemTitle.code.split('-')
                     let code = {
-                        scope: data.scope,
+                        scope: this.$store.getters.getItemTitle.scope,
                         code: key[(key.length - 1)],
                         blob: data.blob
                     }
                     let papers = await this.$evTools.getStuPaper(code)
                     let answer = await this.getItem(ans)
-
                     paper = await this.formPaper(papers)
                     this.testData = paper
                     let objIndex = 0
@@ -327,10 +326,10 @@
             async getItem(data) {
                 let datas = []
                 if (data !== undefined) {
-                    let key = this.stuData.papers[0].code.split('-')
+                    let key = this.$store.getters.getItemTitle.code.split('-')
                     let code = {
                         scope: this.stuData.papers[0].scope,
-                        code: key[(key.length - 1)],
+                        code:key[key.length - 1],
                         blob: data[0]
                     }
                     let blob = this.formUrl(code)

+ 8 - 16
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperTest.vue

@@ -125,7 +125,7 @@
                                 </label>
                             </div>
                             <!--选择题选项-->
-                            <div class="select-box" v-if=" getQue(queNo).type != 'judge' ">
+                            <div class="select-box" v-if="getQue(queNo).type != 'judge'">
                                 <label class="testBtn"
                                        v-for="(item, index) in getQue(queNo).option"
                                        :key="index">
@@ -223,7 +223,6 @@
                 isLoading: false,
                 fullPage: true,
                 opacity: 0.6,
-                //loading畫面
                 showMessageNum: 0,
                 WarmMessageisOpen: false,
                 checkers: [],
@@ -267,7 +266,6 @@
                 ],
                 examInfo: [],
                 judgeSelect: "",
-
                 imgPreview: {
                     img: "",
                     show: false
@@ -331,13 +329,6 @@
             getQue(index) {
                 if (this.examInfo.length) {
                     if (this.examInfo[index]) {
-                        this.$nextTick(() => {
-                            // window.MathJax.Hub.Queue([
-                            //     "Typeset",
-                            //     MathJax.Hub,
-                            //     this.$refs.questionBox,
-                            // ]);
-                        });
                         return this.examInfo[index];
                     } else {
                         return {
@@ -352,6 +343,7 @@
                     this.checkers[data].push(this.getQue(this.queNo).option[index].code)
                 }
             },
+            //显示知识点(暂未对接)
             hintHandon() {
                 let undoQuestion = 0
                 for (var i = 0; i <= this.examInfo.length - 1; i++) {
@@ -363,11 +355,6 @@
                 if (undoQuestion != 0) return false
                 else return true
             },
-            qtypeOption: function (queNo) {
-                if (this.getQue(queNo).type == "multiple") {
-                    return "checkbox"
-                } else return "radio"
-            },
             gototheQues(index) {
                 this.queNo = index - 1
             },
@@ -377,6 +364,7 @@
             nextQ() {
                 if (this.queNo < (this.examInfo.length - 1)) this.queNo++
             },
+            //打开提示信息
             openWarmMessage(showMessageNum) {
                 this.WarmMessageisOpen = true
                 if (showMessageNum == 1) {
@@ -393,9 +381,11 @@
                     }
                 } else return;
             },
+            //关闭提示信息
             closeWarmMessage() {
                 this.WarmMessageisOpen = false
             },
+            //提交作答记录
             closetest() {
                 this.WarmMessageisOpen = false
                 if (this.checkers.length) {
@@ -409,7 +399,8 @@
                         subjectId: this.$store.getters.getExamInfo.subject.id,
                         multipleRule: this.$store.getters.getExamInfo.multipleRule,
                         paperId: this.$store.getters.getPaperInfo.id,
-                        code: codes[1]
+                        code: codes[1],
+                        scode: this.$store.getters.getItemTitle.scode
                     }
                     this.$api.studentWeb.SaveStuExamPaper(req).then(res => {
                         if (res) {
@@ -427,6 +418,7 @@
                     })
                 } 
             },
+            //退出测试
             quitTest() {
                 this.isLoading = true
                 setTimeout(() => {

+ 11 - 10
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue

@@ -89,13 +89,13 @@
                 paperData: [],
                 openEva: false,
                 selectData: {},
-                isExamDown: false, 
+                isExamDown: false,
                 chooseData: {},
                 examData: [],
                 isLoad: false,
                 stuData: {},
                 isTestOver: false,
-                selectTab:"test"
+                selectTab: "test"
             };
         },
         methods: {
@@ -104,25 +104,24 @@
                 this.stuData = {}
                 this.chooseData = {}
                 this.isTestOver = false
-                //this.selectTab = "test"
-                console.log(this.selectTab)
+                this.isLoad = true
                 if (this.$store.getters.getItemTitle.name !== undefined) {
                     let paper = this.$store.getters.getItemTitle
                     let codes = this.$store.getters.getItemTitle.code.split('-')
                     let req = {
                         id: paper.id,
                         studentId: this.$store.state.userInfo.sub,
-                        code: codes[1]
+                        code: codes[1],
+                        scode: paper.scode
                     }
                     let isTest = 0
                     this.$api.studentWeb.FindStudentPaper(req).then(res => {
-                        console.log(res)
                         this.stuData = res
                         let resData = res
                         for (let item of resData.papers) {
                             if (item.scope) {
                                 this.paperData.push(item)
-                            } 
+                            }
                         }
                         for (let i = 0; i < this.paperData.length; i++) {
                             this.paperData[i].subject = resData.subjects[i]
@@ -152,6 +151,7 @@
                         this.opentestWithSubject(this.paperData[0])
                     })
                 }
+                this.isLoad = false
             },
             dateFormat(timestamp) {
                 var date = new Date(timestamp)
@@ -172,18 +172,19 @@
                 }
             },
             async getPaper(data) {
-                console.log(data)
+                console.log('paper', data)
                 this.isExamDown = false
                 this.isLoad = true
                 this.selectData = {}
                 this.chooseData = {}
                 if (data.blob !== undefined && data.blob !== "") {
-                    let key = data.code.split('-')
+                    let key = this.$store.getters.getItemTitle.code.split('-')
                     let code = {
                         scope: data.scope,
-                        code: key[(key.length - 1)],
+                        code: key[key.length - 1],
                         blob: data.blob
                     }
+                    console.log('评测信息',this.$store.getters.getItemTitle)
                     let exam = {}
                     for (let item of this.examData) {
                         if (data.paperId == item.id) {

+ 41 - 21
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue

@@ -132,7 +132,6 @@
 
 		},
 		methods: {
-
 			onOptionClick(item, index, code) {
 				if (this.submitArr[index].includes(code)) {
 					this.submitArr[index].splice(this.submitArr[index].indexOf(code), 1)
@@ -233,8 +232,6 @@
 					if(!isAnswerd){
 						this.$api.studentWeb.getSurveyInfo(params).then(async res => {
 							if (res) {
-								console.log('获取问卷数据')
-								console.log(res)
 								this.surveyInfo = res.survey
 								this.surveyInfo.items = await this.getBlobItems(res.survey)
 								this.submitArr = []
@@ -255,30 +252,53 @@
 			getBlobItems(qnItem) {
 				return new Promise(async (resolve, reject) => {
 					// let blobHost = qnItem.scope === 'private' ?  JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri : JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).blob_uri
-					let blobHost = 'https://teammodelstorage.blob.core.chinacloudapi.cn/' + qnItem.owner
+					let blobUrl = JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).blob_uri
+					let blobHost = blobUrl.slice(0,blobUrl.lastIndexOf('/')) + '/' +  qnItem.blobcntr
 					// 根据试卷的Blob地址 去读取JSON文件
 					let sasString = qnItem.scope === 'private' ? await this.$tools.getPrivateSas(qnItem
-						.owner) : await this.$tools.getSchoolSas(qnItem.owner)
+						.blobcntr) : await this.$tools.getSchoolSas(qnItem.blobcntr)
 					let promiseArr = []
-					for (let item of qnItem.questionUrl) {
-						promiseArr.push(new Promise(async (r, j) => {
-							try {
-								let itemJson = JSON.parse(await this.$tools.getFile(blobHost +
-									item + sasString.sas))
-								r(itemJson)
-							} catch (e) {
-								j(e)
-							}
-						}))
+					let indexJson = await this.getBlobJsonFile(qnItem.scope,qnItem.blob,qnItem.blobcntr)
+					if(indexJson.slides.length){
+						for (let item of indexJson.slides) {
+							promiseArr.push(new Promise(async (r, j) => {
+								try {
+									let itemJson = JSON.parse(await this.$tools.getFile(blobHost +
+										item + sasString.sas))
+									r(itemJson)
+								} catch (e) {
+									j(e)
+								}
+							}))
+						}
+						Promise.all(promiseArr).then(result => {
+							resolve(result)
+						}).catch(err => {
+							reject(err)
+						})
+					}else{
+						resolve([])
+					}
+					
+				})
+			},
+			
+			// 获取blob里的试题数据
+			getBlobJsonFile(scope,url,container){
+				return new Promise(async (resolve,reject) => {
+					let blobUrl = JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).blob_uri
+					let blobHost = blobUrl.slice(0,blobUrl.lastIndexOf('/')) + '/' +  container
+					// 根据试卷的Blob地址 去读取JSON文件
+					let sasString = scope === 'private' ?  await this.$tools.getPrivateSas(container) : await this.$tools.getSchoolSas(container)
+					try{
+						let itemJson = JSON.parse(await this.$tools.getFile(blobHost + url + sasString.sas))
+						resolve(itemJson)
+					}catch(e){
+						this.$Message.error('文件获取失败!')
+						reject(e)
 					}
-					Promise.all(promiseArr).then(result => {
-						resolve(result)
-					}).catch(err => {
-						reject(err)
-					})
 				})
 			},
-
 
 			typeOption: function(type) {
 				//console.log(type);

+ 67 - 43
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/Vote.vue

@@ -31,7 +31,7 @@
                     <div class="title-rect-group">
                         <div class="title-rect" />
                         <h2 class="title-rect-name">{{ $t("studentWeb.vote.bollotbox") }}</h2>
-                        <p v-if="voteInfo.repeat" style="margin-left:15px;margin-top:2px">{{ $t("studentWeb.vote.surplusTickets")}} <span @click="getVote" style="font-size:16px">{{voteCount}}</span><span> {{ $t("studentWeb.vote.tickets")}} </span></p>
+                        <p v-if="voteInfo.repeat" style="margin-left:15px;margin-top:2px">{{ $t("studentWeb.vote.surplusTickets")}} <span style="font-size:16px">{{voteCount}}</span><span> {{ $t("studentWeb.vote.tickets")}} </span></p>
                     </div>
                     <Button v-show="isResult" style="float:right;margin-top:-30px" size="small" type="success" @click="showRes">
                         <span style="margin-left:5px">{{$t("studentWeb.vote.voteRes")}}</span>
@@ -39,26 +39,25 @@
                 </div>
                 <!--和評測模組一樣-->
                 <div class="question-box"><span v-html="voteInfo.description"></span></div>
-                <div class="checkAnswer">
-                    <label class="testBtn"
-                           v-for="(item, index) in voteInfo.options"
-                           :key="index">
-                        <input type="checkbox" :value="item" v-model="voteChecked" @click="getVote(item)" />
-                        <div class="testbg">
-                            <div class="vote-info">
-                                <span style="display:flex;margin-right:5px">{{item.code}}.<span v-html="item.value"></span></span>
+                <div>
+                    <div class="checkAnswer" v-for="(item, index) in voteInfo.options" :key="index">
+                        <label class="testBtn">
+                            <input type="checkbox" :value="item" v-model="voteChecked" @click="getVote(item)" />
+                            <div class="testbg">
+                                <div class="vote-info">
+                                    <span style="display:flex;margin-right:5px">{{item.code}}.<span v-html="item.value"></span></span>
+                                </div>
+                                <InputNumber v-model="item.count"
+                                             :formatter="value => `${value}` +$t('studentWeb.vote.tickets')"
+                                             :parser="value => value.replace($t('studentWeb.vote.tickets'), '')"
+                                             :min="0"
+                                             v-if="voteInfo.repeat"
+                                             @on-change="setVoteNum(item)"
+                                             :disabled="!voteStatus">
+                                </InputNumber>
                             </div>
-                            <InputNumber v-model="item.count"
-                                         :formatter="value => `${value}` +$t('studentWeb.vote.tickets')"
-                                         :parser="value => value.replace($t('studentWeb.vote.tickets'), '')"
-                                         :min="0"
-                                         v-if="voteInfo.repeat"
-                                         @on-change="setVoteNum(item)"
-                                         :disabled="!voteStatus"
-                                         >
-                            </InputNumber>
-                        </div>
-                    </label>
+                        </label>
+                    </div>
                 </div>
                 <Button :disabled="!isVote" size="large" type="success" @click="submitMessage()">
                     <svg-icon icon-class="vote" class="uploadBtn-icon" />
@@ -66,6 +65,8 @@
                 </Button>
                 <span class="clickbutnoChoosehint"
                       v-if="clickbutnoChoose == true && voteChecked == ''">{{ $t("studentWeb.vote.note") }}</span>
+                <span v-if="isOverCount" style="margin-top:5px;margin-left:15px;color:red">{{$t("studentWeb.vote.warning2")}}</span>
+
             </div>
         </div>
         <div class="voteResults" v-if="showResult">
@@ -125,6 +126,7 @@
                 chooseVoteRes: {},
                 isLoad: false,
                 isResult: false,
+                isOverCount: false,
                 voteData: [],
                 voteList: []
             };
@@ -166,6 +168,7 @@
                             for (let item of res.vote.options) {
                                 item.count = 0
                             }
+                            this.voteInfo = res.vote
                             if (res.vote.progress == "finish") {
                                 this.getVoteRecord()
                                 this.getVoteRes()
@@ -173,45 +176,68 @@
                             } else {
                                 this.getVoteRecord()
                             }
-                            this.voteInfo = res.vote
                         }
                     })
                 }
             },
-            getVoteRes() {
-                if (this.$store.getters.getItemTitle.id) {
-                    this.voteRes = {}
-                    let params = {
-                        "id": this.$store.getters.getItemTitle.id,
-                        "code": this.$store.getters.getItemTitle.scode,
-                        "userid": this.$store.state.userInfo.sub
-                    }
-                    this.$api.studentWeb.getVoteRecord(params).then(res => {
-                        if (res) {
-                            this.setData(res)
-                            this.isLoad = false
-                        }
-                    })
+           async getVoteRes() {
+                console.log('投票数据', this.voteInfo)
+                if (this.voteInfo.recordUrl !== "") {
+                    console.log(this.voteInfo.recordUrl)
+                    let data = await this.getBlobItems(this.voteInfo)
+                    this.setData(data[0])
+                    console.log(data)
                 }
             },
+            // 获取blob里的试题数据
+            getBlobItems(qnItem) {
+                let key = this.voteInfo.code.split('-')
+                let code = key[key.length - 1]
+                return new Promise(async (resolve, reject) => {
+                    let blobHost = 'https://teammodelstorage.blob.core.chinacloudapi.cn/' + code
+                    // 根据试卷的Blob地址 去读取JSON文件
+                    let sasString = qnItem.scope === 'private' ? await this.$tools.getPrivateSas(code) : await this.$tools.getSchoolSas(code)
+                    let promiseArr = []
+                        promiseArr.push(new Promise(async (r, j) => {
+                            try {
+                                let itemJson = JSON.parse(await this.$tools.getFile(blobHost + qnItem.recordUrl + sasString.sas))
+                                r(itemJson)
+                            } catch (e) {
+                                j(e)
+                            }
+                        }))
+                    Promise.all(promiseArr).then(result => {
+                        resolve(result)
+                    }).catch(err => {
+                        reject(err)
+                    })
+                })
+            },
             //准备图表数据
             setData(data) {
+                this.voteData = []
+                this.voteList = []
                 if (data.options.length) {
-                    this.voteData = []
-                    this.voteList = []
-                    for (let item of data.options) {
+                    let code = []
+                    code = data.options.sort((a, b) => {
+                        return (a.code < b.code) ? -1 : (a.code > b.code) ? 1 : 0;
+                    })
+                    for (let item of code) {
                         this.voteData.push({
                             value: item.count,
                             itemStyle: { color: "#00AD6C" },
                         })
                         this.voteList.push(item.code)
                     }
-                    this.voteList = this.voteList.sort()
                 }
             },
+            //排序
+            compare(val1, val2){
+                return val1.code.toLowerCase() < val2.code.toLowerCase()
+             },
             showRes() {
-                this.showResult = !this.showResult
-            },
+            this.showResult = !this.showResult
+             },
             //获取投票结果
             getVote(data) {
                 if (!this.voteInfo.repeat) {
@@ -297,7 +323,6 @@
                 } else {
                     status = false
                 }
-                console.log(this.isVote)
                 this.voteStatus = status
                 this.isVote = status
                 return status
@@ -360,7 +385,6 @@
                     if (num > this.voteInfo.voteNum) {
                         this.isOverCount = true
                         this.isVote = false
-                        this.$Message.warning(this.$t('studentWeb.vote.warning2'))
                         return 0
                     }
                     return this.voteInfo.voteNum - num

+ 6 - 2
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/VoteResultChart.vue

@@ -1,7 +1,8 @@
 <template>
     <div class="vote-result-chart">
         <Card class="vote-chart-card">
-            <div id="main" style="height:400px;width:600px"></div>
+            <div id="main" style="height:350px;width:600px"></div>
+            <span v-if="voteData.length == 0">暂未投票结果数据</span>
         </Card>
     </div>
 </template>
@@ -28,7 +29,10 @@
             };
         },
         mounted() {
-            this.setMyMap()
+            console.log(this.voteData)
+            if (this.voteData.length) {
+                this.setMyMap()
+            }
         },
         methods: {
            setMyMap() {

+ 26 - 37
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -9,7 +9,7 @@
                         <svg-icon icon-class="search"
                                   class="searchIcon"
                                   :class="{ openSearch: openSearch }" />
-                    </div>
+                    </div>          
                     <div class="search-wrapper" :class="{ openSearch: openSearch }">
                         <Input type="text" v-model="search" :placeholder="$t('studentWeb.public.search')" clearable />
                     </div>
@@ -19,28 +19,19 @@
                 <div>
                     <Dropdown>
                         <a href="javascript:void(0)" class="list-title">
-                            <span >{{ selectedEventStatusNow }}</span>
+                            <span>{{ selectedEventStatusNow }}</span>
                             <Icon type="ios-arrow-down"></Icon>
                         </a>
                         <DropdownMenu slot="list">
                             <div @click="sentEventStatus('all')">
                                 <DropdownItem>{{ $t("studentWeb.event.allStatus") }}</DropdownItem>
                             </div>
-                            <div @click="sentEventStatus('unFinsish')">
+                            <div @click="sentEventStatus('going')">
                                 <DropdownItem>{{ $t("studentWeb.event.unFinished") }}</DropdownItem>
                             </div>
                             <div @click="sentEventStatus('finish')">
                                 <DropdownItem>{{ $t("studentWeb.event.Fineshed") }}</DropdownItem>
                             </div>
-                            <div @click="sentEventStatus('overTime')">
-                                <DropdownItem>{{ $t("studentWeb.event.Timeout") }}</DropdownItem>
-                            </div>
-                            <div @click="sentEventStatus('reExam')">
-                                <DropdownItem divided>{{ $t("studentWeb.event.makeupExam") }}</DropdownItem>
-                            </div>
-                            <div @click="sentEventStatus('reMake')">
-                                <DropdownItem>{{ $t("studentWeb.event.makeupHw") }}</DropdownItem>
-                            </div>
                         </DropdownMenu>
                     </Dropdown>
                 </div>
@@ -49,8 +40,7 @@
                 <ul class="icon-selector" v-if="hideIconbtn == false">
                     <li class="icon-btn"
                         @click="selectAllType()"
-                        :class="{'icon-btn-selected': eventTypeCheckers == ''}"
-                        >
+                        :class="{'icon-btn-selected': eventTypeCheckers == ''}">
                         <svg-icon icon-class="alltext" class="innerIcon Icon-0" />
                     </li>
                     <label v-for="(iconBtn, index) in typeNametoIcon" :key="index">
@@ -179,6 +169,20 @@
                         iconClass: "quesnaire",
                     },
                 ],
+                activityType: [
+                    {
+                        type: "all",
+                        status:"所有活动状态"
+                    },
+                    {
+                        type: "going",
+                        status:"进行中"
+                    },
+                    {
+                        type: "finish",
+                        status:"已完成"
+                    },
+                ],
                 mockdata: "",
                 eventPageType: ["preview", "exam", "homeWork", "vote", "survey"], //本頁出現的類型
                 openSearch: false, //打開搜尋器
@@ -228,24 +232,6 @@
                 this.eventList.length = 0
                 this.isListNoItem = true;
                 this.getActivityInfo()
-
-                //if (this.$store.state.user.studentProfile.classinfo.id !== "") {
-                //    let params = {
-                //        'id': this.$store.state.user.studentProfile.classinfo.id,
-                //        'studentId': this.$store.state.userInfo.sub
-                //    }
-                //    this.$api.studentWeb.FindExamPaper(params).then(res => {
-                //        let data = []
-                //        for (let item of res.props) {
-                //            let code = item.code.split('-')
-                //            if (code[0] == 'Exam') {
-                //                item.eventType = 'exam'
-                //                data.push(item)
-                //            }
-                //        }
-                //        this.eventList = [...data]
-                //    })
-                //}
             },
             //***临时获取投票数据
             getActivityInfo() {
@@ -288,12 +274,10 @@
                 var y = 0;
                 if (!e) var e = window.event;
                 if (e.pageX || e.pageY) {
-                    x =
-                        e.pageX -
+                    x = e.pageX -
                         document.documentElement.scrollLeft -
                         document.body.scrollLeft;
-                    y =
-                        e.pageY -
+                    y = e.pageY -
                         document.documentElement.scrollTop -
                         document.body.scrollTop;
                 } else if (e.clientX || e.clientY) {
@@ -382,7 +366,6 @@
                     );
                 } else if (status == "reExam") {
                     this.hideIconbtn = true;
-
                     return (
                         item.endTime <= "2020.02.10" &&
                         item.eventType == "exam" &&
@@ -390,9 +373,15 @@
                         item.isDone == false
                     );
                 } else if (status == "unFinish") {
+                    return (
+                        item.progress == "going"
+                    );
                     this.hideIconbtn = false;
                     return item.isDone == false;
                 } else if (status == "finish") {
+                    return (
+                        item.progress == "finish"
+                    );
                     this.hideIconbtn = false;
                     return item.isDone == true;
                 } else if (status == "overTime") {

+ 21 - 7
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue

@@ -15,7 +15,7 @@
 				</div>
 				<Select multiple v-model="voteForm.classes" :class="!voteFormEdit ? 'vote-form-disabled':''" :placeholder="$t('vote.form.targetPlace')"
 				 :not-found-text="$t('vote.form.noFoundText')" v-else>
-					<Option v-for="item in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="item.id">{{ item.name }}</Option>
+					<Option v-for="(item,index) in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="index">{{ item.name }}</Option>
 				</Select>
 			</FormItem>
 
@@ -200,7 +200,10 @@
 		},
 		created() {
 			/** 获取可选班级列表 */
-			this.getClassrooms(this.userInfo.TEAMModelId).then(res => this.classRooms = res)
+			this.getClassrooms(this.userInfo.TEAMModelId).then(res => {
+				console.log(res)
+				this.classRooms = res
+			})
 		},
 		methods: {
 			onClassTypeChange(val) {
@@ -269,10 +272,10 @@
 							params.options = this.voteOptionsContent
 							// 新增参数
 							params.creatorId = this.$store.state.userInfo.TEAMModelId
-							params.owner = this.$route.name === 'personalVote' && this.classType === 'private' ? this.$store.state.userInfo
-								.TEAMModelId : this.$store.state.userInfo.schoolCode
 							params.voteNum = this.voteForm.selectMax
 							params.times = this.voteForm.times
+							params.school = params.scope === 'school' ?  this.$store.state.userInfo.schoolCode : null
+							params.blobcntr = params.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
 							
 							if (this.isEdit && this.editInfo.id && this.editInfo.code) {
 								params.id = this.editInfo.id
@@ -419,7 +422,14 @@
 						code: this.$store.state.userInfo.schoolCode
 					}).then(res => {
 						if (!res.error && res.courses) {
-							r(res.courses)
+							this.$store.dispatch('user/getSchoolProfile').then(schoolProfile => {
+							    let schoolClasses =  schoolProfile.school_classes
+								console.log(schoolClasses)
+								r([...res.courses,...schoolClasses])
+							}).catch(err => {
+								r([])
+							})
+							
 						} else {
 							j(500)
 							this.$Message.error(this.$t('vote.form.getDataFailTip'))
@@ -491,8 +501,11 @@
 			 * 回显投票详情
 			 * @param item
 			 */
-			doRender(item) {
+			async doRender(item) {
 				console.log(item)
+				if(!this.classRooms.length){
+					this.classRooms = await this.getClassrooms(this.userInfo.TEAMModelId)
+				}
 				this.voteForm = null
 				this.voteOptionsContent = []
 				this.voteOptions = []
@@ -515,6 +528,7 @@
 				this.descriptionEditor.txt.html(item.description)
 				this.voteOptionsContent = item.options
 				this.voteOptions = item.options.map((item, index) => index)
+				
 				this.$nextTick(() => {
 					this.initEditors()
 					if (item.classes.length) {
@@ -545,7 +559,7 @@
 			descriptionEditor.config.onchange = (html) => {
 				this.voteForm.description = html
 			}
-			this.$editorTools.initMyEditor(descriptionEditor)
+			this.$editorTools.initMyEditor(descriptionEditor,this)
 			descriptionEditor.create()
 			this.descriptionEditor = descriptionEditor
 

+ 5 - 0
TEAMModelOS/ClientApp/src/css/site.css

@@ -146,6 +146,10 @@ html[white]{ /*白色主題*/
 		display: none;
 	}
 	
+	.richText-audio{
+		vertical-align: middle;
+	}
+	
 	.richText-audio .audio-info{
 		padding: 8px;
 		background-color: #f1f3f4;
@@ -162,6 +166,7 @@ html[white]{ /*白色主題*/
 		position: relative;
 		display: inline-block;
 		cursor: pointer;
+		vertical-align: middle;
 	}
 
 	.richText-video::after {

+ 7 - 2
TEAMModelOS/ClientApp/src/utils/editorTools.js

@@ -16,7 +16,12 @@ import {
 
 export default {
 	/* 初始化自定义富文本配置项 */
-	initMyEditor(editor) {
+	initMyEditor(editor,vm,isOption) {
+		// 初始化公式、视频、音频、画板功能
+		this.addFormula(vm,editor)
+		this.addVideoUpload(vm,editor)
+		this.addAudio(vm,editor)
+		this.addCanvas(vm,editor)
 		editor.config.uploadImgMaxSize = 2 * 1024 * 1024 // 2M
 		editor.config.uploadImgShowBase64 = true;
 		editor.config.uploadImgMaxLength = 5 // 一次最多上传 5 个图片
@@ -38,6 +43,7 @@ export default {
 			'canvas',
 			'formula'
 		]
+		isOption && editor.config.menus.splice(editor.config.menus.indexOf('video'),1)
 	},
 
 	/* 初始化自定义富文本简版配置项 */
@@ -64,7 +70,6 @@ export default {
 	
 	/* 添加自定义本地视频上传功能 */
 	addVideoUpload(vm, editor) {
-		this.addFormula(vm,editor)
 		// 获取必要的变量,这些在下文中都会用到
 		const {
 			$,

+ 1 - 3
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -384,13 +384,12 @@ export default {
 	
 	/* 获取完整的试卷数据 */
 	getStuPaper(paper,examScope){
-		//console.log('evTools换取学生试卷' , paper)
 		let curScope = examScope || paper.scope
 		return new Promise(async (r,j) => {
 			let blobHost = JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).blob_uri
 			let splitHost = blobHost.split('/')
 			// 根据试卷的Blob地址 去读取JSON文件
-			let sasString = curScope === 'school' ?  await $tools.getSchoolSas(paper.code) : await $tools.getPrivateSas(paper.code)
+			let sasString = curScope === 'school' ? await $tools.getSchoolSas(paper.code) : await $tools.getPrivateSas(paper.code)
 			try {
 				let jsonInfo = await $tools.getFile(sasString.url + '/' + paper.code + paper.blob + '/index.json' + sasString.sas)
 				let jsonData = JSON.parse(jsonInfo)
@@ -443,7 +442,6 @@ export default {
 			// 根据试卷的Blob地址 去读取JSON文件
 			let sasString = paper.scope === 'school' ? await $tools.getSchoolSas(paper.code) : await $tools.getPrivateSas(paper.code)
 			try {
-				console.log(paper.blob + sasString.sas)
 				let jsonInfo = await $tools.getFile(paper.blob + sasString.sas)
 				let jsonData = JSON.parse(jsonInfo)
 				// 获取试卷包含的试题数据并包装好

+ 5 - 4
TEAMModelOS/ClientApp/src/utils/kityformula.js

@@ -31,14 +31,15 @@ export default function(editor) {
 						const kfe = node.contentWindow.kfe
 						let latex = kfe.execCommand('get.source')
 						// 去掉空格
-						latex = latex.replace(/\s/g, '') 
+						// latex = latex.replace(/\s/g, '') 
 						// 将latex转换成svg输出
-						const html = window.MathJax.tex2svg(latex,{em: 12, ex: 6, display: false})
+						const html = window.MathJax.tex2svg(latex,{em: 12, ex: 6})
 						// 匹配输出的svg标签内容直接插入到编辑器中
 						var regex = /\<svg .*\>.*\<\/svg\>/;
 						var arr = html.outerHTML.match(regex);
-						// editor.cmd["do"]('insertHTML', `<span class="formula">${ arr[0] }</span>`);
-						editor.cmd["do"]('insertHTML', arr[0]);
+						// 插入到富文本编辑器内
+						editor.cmd["do"]('insertHTML', `<span class="formula"><span>&nbsp;</span>${ arr[0] }<span>&nbsp;</span></span>`);
+						editor.change.emit()
 						return true
 					}
 				}]

+ 92 - 52
TEAMModelOS/ClientApp/src/utils/public.js

@@ -171,7 +171,8 @@ export default {
 	},
 	// 生成随机UUID工具
 	guid: function() {
-		return (this.randomId() + this.randomId() + '-' + this.randomId() + '-' + this.randomId() + '-' + this.randomId() +
+		return (this.randomId() + this.randomId() + '-' + this.randomId() + '-' + this.randomId() + '-' + this
+			.randomId() +
 			'-' + this.randomId() + this.randomId() + this.randomId())
 	},
 
@@ -245,8 +246,9 @@ export default {
 		}
 		if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length))
 		for (var k in o)
-			if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[
-				k]).substr(('' + o[k]).length)))
+			if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : ((
+				'00' + o[
+					k]).substr(('' + o[k]).length)))
 		return fmt
 	},
 
@@ -356,7 +358,8 @@ export default {
 	 */
 	getPrivateSas(code) {
 		return new Promise((r, j) => {
-			if (!store.state.privateSas || checkSas(store.state.privateSas.timeout) || store.state.privateSas.name !== store.state.userInfo.TEAMModelId) {
+			if (!store.state.privateSas || checkSas(store.state.privateSas.timeout) || store.state.privateSas
+				.name !== store.state.userInfo.TEAMModelId) {
 				$api.blob.blobSasRCW({
 					name: code || store.state.userInfo.TEAMModelId,
 					role: 'teacher'
@@ -384,7 +387,8 @@ export default {
 	 */
 	getSchoolSas(code) {
 		return new Promise((r, j) => {
-			if (!store.state.schoolSas || checkSas(store.state.schoolSas.timeout)  || store.state.schoolSas.name !== store.state.userInfo.schoolCode) {
+			if (!store.state.schoolSas || checkSas(store.state.schoolSas.timeout) || store.state.schoolSas
+				.name !== store.state.userInfo.schoolCode) {
 				$api.blob.blobSasRCW({
 					name: code || store.state.userInfo.schoolCode,
 					role: 'school'
@@ -469,11 +473,11 @@ export default {
 			render: (h) => {
 				return h('div', {
 					'class': 'my-spin',
-					style:{
-						background:'#000',
-						padding:'20px',
-						borderRadius:'5px',
-						color:'#fff'
+					style: {
+						background: '#000',
+						padding: '20px',
+						borderRadius: '5px',
+						color: '#fff'
 					}
 				}, [
 					h('Icon', {
@@ -490,12 +494,12 @@ export default {
 		const blobTool = require('./blobTool.js')
 		const isSchool = vm.$parent.exerciseScope ? vm.$parent.exerciseScope === 1 : vm.exerciseScope === 1
 		const sasData = isSchool ? await this.getSchoolSas() : await this.getPrivateSas()
-		
+
 		const scope = isSchool ? 'school' : 'private'
 		const blobToolClass = blobTool.default
 		//初始化Blob
 		let containerClient = new blobToolClass(sasData.url, sasData.name, sasData.sas, scope)
-		try{
+		try {
 			let id = vm.curId || vm.$parent.curId
 			// 上传文件
 			let blobFile = await containerClient.upload(file, 'item/' + id)
@@ -503,16 +507,21 @@ export default {
 			const fileSas = await this.getFileSas(blobFile.url)
 			const fileBlobUrl = fileSas.url
 			const posterBase64 = await this.getVideoBase64(fileBlobUrl)
-			editor.txt.append('<p><video src=' +
-				fileBlobUrl + ' class="richText-video" width="300" preload controls="controls"></video></p>')
+			editor.selection.getSelectionStartElem().elems[0].innerHTML += '<span><span>&nbsp;</span><video src=' +
+				fileBlobUrl + ' class="richText-video" width="300" preload controls="controls"></video><span>&nbsp;</span></span>'
 			editor.change.emit()
+			vm.$EventBus.$emit('noSave', {
+				path: blobFile.blob,
+				size: blobFile.size,
+				scope: scope
+			})
 			vm.$Spin.hide();
-		}catch(e){
+		} catch (e) {
 			vm.$Message.error(e.spaceError)
 			vm.$Spin.hide();
 		}
 	},
-	
+
 	/* 上传视频到BLob */
 	async doUploadAudio(vm, file, editor) {
 		console.log(vm)
@@ -520,11 +529,11 @@ export default {
 			render: (h) => {
 				return h('div', {
 					'class': 'my-spin',
-					style:{
-						background:'#000',
-						padding:'20px',
-						borderRadius:'5px',
-						color:'#fff'
+					style: {
+						background: '#000',
+						padding: '20px',
+						borderRadius: '5px',
+						color: '#fff'
 					}
 				}, [
 					h('Icon', {
@@ -541,12 +550,11 @@ export default {
 		const blobTool = require('./blobTool.js')
 		const isSchool = vm.$parent.exerciseScope ? vm.$parent.exerciseScope === 1 : vm.exerciseScope === 1
 		const sasData = isSchool ? await this.getSchoolSas() : await this.getPrivateSas()
-		
 		const scope = isSchool ? 'school' : 'private'
 		const blobToolClass = blobTool.default
 		//初始化Blob
 		let containerClient = new blobToolClass(sasData.url, sasData.name, sasData.sas, scope)
-		try{
+		try {
 			let id = vm.curId || vm.$parent.curId
 			// 上传文件
 			let blobFile = await containerClient.upload(file, 'item/' + id)
@@ -554,22 +562,52 @@ export default {
 			// 获取blob链接以及视频封面截图
 			const fileSas = await this.getFileSas(blobFile.url)
 			const fileBlobUrl = fileSas.url
-			editor.txt.append(
-				`<span class="richText-audio" contenteditable="false" >
+			editor.selection.getSelectionStartElem().elems[0].innerHTML += `<span><span>&nbsp;&nbsp;</span><span class="richText-audio" contenteditable="false" >
 					<span class="audio-info">
 						<i class="ivu-icon ivu-icon-ios-musical-notes" style="font-size: 24px;margin:0 10px"></i>
 						<span class="audio-name">${ file.name }</span>
 					</span>
 					<audio src="${ fileBlobUrl }"  id="audio" controls="controls" controlsList="nodownload"></audio>
-				</span>`
-			);
+				</span><span>&nbsp;</span></span>`
 			editor.change.emit()
+			vm.$EventBus.$emit('noSave', {
+				path: blobFile.blob,
+				size: blobFile.size,
+				scope: scope
+			})
 			vm.$Spin.hide();
-		}catch(e){
+		} catch (e) {
 			vm.$Message.error(e.spaceError)
 			vm.$Spin.hide();
 		}
 	},
+	/* 删除未保存的BLOB多媒体文件 */
+	async deleteNoSave(noSaveArr) {
+		const blobTool = require('./blobTool.js')
+		const schoolSas = await this.getSchoolSas()
+		const privateSas = await this.getPrivateSas()
+		const blobToolClass = blobTool.default
+		let schoolBlobClient = new blobToolClass(schoolSas.url, schoolSas.name, schoolSas.sas, 'school')
+		let privateBlobClient = new blobToolClass(privateSas.url, privateSas.name, privateSas.sas, 'private')
+		let promiseArr = []
+		for (let i = 0; i < noSaveArr.length; i++) {
+			let item = noSaveArr[i]
+			promiseArr.push(new Promise((r, j) => {
+				let myClient = item.scope === 'school' ? schoolBlobClient : privateBlobClient
+				myClient.deleteBlob(item.path, item.size).then(res => {
+					r(200)
+				}).catch(err => {
+					j(err)
+				})
+			}))
+		}
+		Promise.all(promiseArr).then(result => {
+			localStorage.setItem('noSave','[]')
+		}).catch(err => {
+			console.log(err)
+		})
+
+	},
 	isEqual: function(x, y) {
 		// If both x and y are null or undefined and exactly the same 
 		if (x === y) {
@@ -613,8 +651,8 @@ export default {
 		}
 		return true;
 	},
-	
-	getLevelStuPercent(val,subjectIndex,index){
+
+	getLevelStuPercent(val, subjectIndex, index) {
 		let result = []
 		val.students.forEach(stu => {
 			result.push([
@@ -623,40 +661,41 @@ export default {
 				stu.no || '-',
 				val.fScores[subjectIndex].Value[index],
 				stu.subjects[subjectIndex].fieldPoint[index],
-				(stu.subjects[subjectIndex].fieldPoint[index] / val.fScores[subjectIndex].Value[index]).toFixed(2)
+				(stu.subjects[subjectIndex].fieldPoint[index] / val.fScores[subjectIndex].Value[index])
+				.toFixed(2)
 			])
 		})
 		return result
 	},
-	
-	getLevelClassPercent(val,subjectIndex,index){
+
+	getLevelClassPercent(val, subjectIndex, index) {
 		let result = []
 		val.classes.forEach(classItem => {
 			result.push(classItem.subjects[subjectIndex].field[index])
 		})
 		return result
 	},
-	
-	getLevelPercent(val,subjectIndex){
+
+	getLevelPercent(val, subjectIndex) {
 		let stuResult = {}
 		let classResult = {}
-		val.fieldName[subjectIndex].Value.forEach((item,index) => {
-			stuResult[item] = this.getLevelStuPercent(val,subjectIndex,index)
-			classResult[item] = this.getLevelClassPercent(val,subjectIndex,index)
+		val.fieldName[subjectIndex].Value.forEach((item, index) => {
+			stuResult[item] = this.getLevelStuPercent(val, subjectIndex, index)
+			classResult[item] = this.getLevelClassPercent(val, subjectIndex, index)
 		})
 		stuResult.grade = val.fieldAllPer[subjectIndex].Value
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
 		classResult.className = []
 		let obj = {
-			stuResult:stuResult,
-			classResult:classResult
+			stuResult: stuResult,
+			classResult: classResult
 		}
 		return obj
 	},
-	
+
 	/* 学情知识点模块数据转换 */
-	getKnowStuPercent(val,subjectIndex,index){
+	getKnowStuPercent(val, subjectIndex, index) {
 		let result = []
 		val.students.forEach(stu => {
 			result.push([
@@ -665,34 +704,35 @@ export default {
 				stu.no || '-',
 				val.kScores[subjectIndex].Value[index],
 				stu.subjects[subjectIndex].point[index],
-				(stu.subjects[subjectIndex].point[index] / val.kScores[subjectIndex].Value[index]).toFixed(2)
+				(stu.subjects[subjectIndex].point[index] / val.kScores[subjectIndex].Value[index])
+				.toFixed(2)
 			])
 		})
 		return result
 	},
-	
-	getKnowClassPercent(val,subjectIndex,index){
+
+	getKnowClassPercent(val, subjectIndex, index) {
 		let result = []
 		val.classes.forEach(classItem => {
 			result.push(classItem.subjects[subjectIndex].point[index])
 		})
 		return result
 	},
-	
-	getKnowPercent(val,subjectIndex){
+
+	getKnowPercent(val, subjectIndex) {
 		let stuResult = {}
 		let classResult = {}
-		val.knowName[subjectIndex].Value.forEach((item,index) => {
-			stuResult[item] = this.getKnowStuPercent(val,subjectIndex,index)
-			classResult[item] = this.getKnowClassPercent(val,subjectIndex,index)
+		val.knowName[subjectIndex].Value.forEach((item, index) => {
+			stuResult[item] = this.getKnowStuPercent(val, subjectIndex, index)
+			classResult[item] = this.getKnowClassPercent(val, subjectIndex, index)
 		})
 		stuResult.grade = val.knowAllper[subjectIndex].Value
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
 		classResult.className = []
 		let obj = {
-			stuResult:stuResult,
-			classResult:classResult
+			stuResult: stuResult,
+			classResult: classResult
 		}
 		return obj
 	},

+ 13 - 0
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -100,11 +100,24 @@
             }
         },
         mounted() {
+			
+			if(localStorage.getItem('noSave') && JSON.parse(localStorage.getItem('noSave')).length){
+				this.$tools.deleteNoSave(JSON.parse(localStorage.getItem('noSave')))
+			}else{
+				localStorage.setItem('noSave','[]')
+			}
+			
 			this.$EventBus.$off('onGlobalLoading')
 			this.$EventBus.$on('onGlobalLoading', val => {
 				this.isLoading = val
             })
             
+			this.$EventBus.$off('noSave')
+			this.$EventBus.$on('noSave', val => {
+				let curNoSaveArr = JSON.parse(localStorage.getItem('noSave'))
+				curNoSaveArr.push(val)
+				localStorage.setItem('noSave',JSON.stringify(curNoSaveArr))
+			})
            
         },
         watch: {

+ 1 - 0
TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue

@@ -697,6 +697,7 @@
 						option: "update",
 					})
 					.then((res) => {
+						localStorage.setItem('noSave','[]')
 						this.$Message.success(this.$t('evaluation.editSuc'));
 						this.$refs.editRef.isLoading = false;
 						this.editExerciseModal = false;

+ 1 - 4
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue

@@ -491,10 +491,7 @@
 			analysisEditor.config.onchange = (html) => {
 				this.analysisContent = html;
 			},
-			this.$editorTools.addVideoUpload(this, analysisEditor)
-			this.$editorTools.addAudio(this, analysisEditor)
-			this.$editorTools.addCanvas(this, analysisEditor)
-			this.$editorTools.initMyEditor(analysisEditor)
+			this.$editorTools.initMyEditor(analysisEditor,this)
 			analysisEditor.create();
 			this.analysisEditor = analysisEditor;
 			

+ 1 - 4
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue

@@ -814,10 +814,7 @@
 			analysisEditor.config.onchange = (html) => {
 				this.analysisContent = html;
 			},
-			this.$editorTools.addVideoUpload(this, analysisEditor)
-			this.$editorTools.addAudio(this, analysisEditor)
-			this.$editorTools.addCanvas(this, analysisEditor)
-			this.$editorTools.initMyEditor(analysisEditor)
+			this.$editorTools.initMyEditor(analysisEditor,this)
 			
 			analysisEditor.create();
 			this.analysisEditor = analysisEditor;

+ 33 - 21
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue

@@ -97,7 +97,7 @@
             }
         },
         created() {
-            this.uploadUrl = window.location.origin  + '/import/parse-word '
+            this.uploadUrl = window.location.origin  + '/import/parse-docx'
 			this.curLang = localStorage.getItem('local')
 			this.hostName = this.$store.state.privateSas ? this.$store.state.privateSas.url : 'https://teammodelstorage.blob.core.chinacloudapi.cn'
         },
@@ -292,26 +292,38 @@
              * 上传文件成功回调
              * @param response
              */
-            uploadSuccess(response) {
-				console.log(response)
-				if(response.tests.length && !response.emferror.length){
-					this.$Message.success(this.$t('evaluation.importFile.warningTips3'))
-					this.$emit('importFinish',response.tests)
-					this.isImportFinish = false
-					this.isBtnLoading = false
-					this.exerciseList = []
-				}else if(response.emferror.length){
-					this.errorModal = true
-					this.importList = response.tests
-					this.errorList = response.emferror
-					this.isImportFinish = false
-					this.isBtnLoading = false
-				}else{
-					this.$Message.error(this.$t('evaluation.importFile.warningTips4'))
-					this.isBtnLoading = false
-				}
-				
-				this.isSelectFinish = false
+            uploadSuccess(res) {
+				// 匹配模板文档中的数学公式
+				var regex = /(\<math.*?<\/math\>)/g;
+				var html = res.html
+				var arr = html.match(regex);
+				// 对所有的mathml进行转换成svg操作
+				arr.forEach(math => {
+					let svgHtml = window.MathJax.mathml2svg(math, { em: 12, ex: 6 })
+					var regex2 = /\<svg .*\>.*\<\/svg\>/;
+					var arr2 = svgHtml.outerHTML.match(regex2);
+					html = html.replace(math, `<span>&nbsp;</span>${arr2[0]}<span>&nbsp;</span>`)
+				})
+				// 解析成题目列表
+				this.$api.SaveAnalyzeHtml({ html : html }).then(response => {
+					if(response.tests.length && !response.emferror.length){
+						this.$Message.success(this.$t('evaluation.importFile.warningTips3'))
+						this.$emit('importFinish',response.tests)
+						this.isImportFinish = false
+						this.isBtnLoading = false
+						this.exerciseList = []
+					}else if(response.emferror.length){
+						this.errorModal = true
+						this.importList = response.tests
+						this.errorList = response.emferror
+						this.isImportFinish = false
+						this.isBtnLoading = false
+					}else{
+						this.$Message.error(this.$t('evaluation.importFile.warningTips4'))
+						this.isBtnLoading = false
+					}
+					this.isSelectFinish = false
+				})
             },
         },
         computed: {

+ 86 - 87
TEAMModelOS/ClientApp/src/view/evaluation/components/BasePoints.vue

@@ -1,24 +1,25 @@
 <template>
 	<div class="points-container">
-		<Button type="info" class="btn-add-point" @click="addPointsModal = true" v-show="curScope === 'school'">{{$t('evaluation.points.addPoint')}}</Button>
+		<Button type="info" class="btn-add-point" @click="addPointsModal = true"
+			v-show="curScope === 'school'">{{$t('evaluation.points.addPoint')}}</Button>
 		<div class="filter-wrap">
 			<Select v-model="selectPeriod" @on-change="onPeriodChange" :disabled="curScope === 'school'">
 				<Option v-for="(item, index) in periodList" :value="item.id" :key="index">{{ item.name }}</Option>
 			</Select>
-			
+
 			<Select v-model="selectSubject" @on-change="onSubjectChange" :disabled="curScope === 'school'">
 				<Option v-for="(item, index) in subjectList" :value="item.id" :key="index">{{ item.name }}</Option>
 			</Select>
 		</div>
-		
-		<!--  -->
+
 		<div style="margin-top: 20px;">
 			<Loading hideMask v-show="isLoading"></Loading>
-			<Input icon="ios-close" v-model="searchSchoolPoint" :placeholder="$t('evaluation.points.searchPoint')" autofocus style="width: 98%;margin-left:1%;margin-bottom:10px"
-			 @on-change="onSearchSchoolChange" @on-enter="onSearchSchoolChange" />
+			<Input icon="ios-close" v-model="searchSchoolPoint" :placeholder="$t('evaluation.points.searchPoint')"
+				autofocus style="width: 98%;margin-left:1%;margin-bottom:10px" @on-change="onSearchSchoolChange"
+				@on-enter="onSearchSchoolChange" />
 			<div v-if="schoolPointList.length === 0" style="margin:5px">{{$t('evaluation.points.noPoint')}}</div>
 			<CheckboxGroup v-model="checkedList" @on-change="onCheckChange" v-else>
-				<Checkbox v-for="(item,index) in schoolPointList" :label="item.name" :key="item.id">{{ item.name }}</Checkbox>
+				<Checkbox v-for="(item,index) in schoolPointList" :label="item" :key="item">{{ item }}</Checkbox>
 			</CheckboxGroup>
 		</div>
 
@@ -27,16 +28,14 @@
 			<span class="point-item" v-for="(item,index) in checkedList" :key="index">{{ item }}</span>
 		</div>
 
-		<Modal v-model="addPointsModal" :title="$t('evaluation.points.addPoint')" ref="pointRef" width="400px" class="related-point-modal" style="z-index:99999">
-<!-- 			<span>知识点类型</span>
-			<Select v-model="newPointType" style="margin:10px 0">
-				<Option value="school">校本知识点</Option>
-			</Select> -->
+		<Modal v-model="addPointsModal" :title="$t('evaluation.points.addPoint')" ref="pointRef" width="400px"
+			class="related-point-modal" style="z-index:99999">
 			<span>{{$t('evaluation.points.pointName')}}</span>
 			<Input v-model="newPointName" :placeholder="$t('evaluation.points.inputNewPoint')" style="margin:10px 0" />
 			<div slot="footer">
 				<Button type="text" @click="addPointsModal = false">{{$t('evaluation.cancel')}}</Button>
-				<Button type="primary" @click="onAddNewPoint" :loading="isAddLoading">{{$t('evaluation.confirm')}}</Button>
+				<Button type="primary" @click="onAddNewPoint"
+					:loading="isAddLoading">{{$t('evaluation.confirm')}}</Button>
 			</div>
 		</Modal>
 	</div>
@@ -58,8 +57,8 @@
 				type: String,
 				default: 'school'
 			},
-			points:{
-				type:Array,
+			points: {
+				type: Array,
 				default: () => []
 			},
 			max: {
@@ -69,7 +68,7 @@
 		},
 		data() {
 			return {
-				isLoading:false,
+				isLoading: false,
 				addPointsModal: false,
 				isAddLoading: false,
 				tabName: 'school',
@@ -77,11 +76,17 @@
 				newPointName: '',
 				searchPoint: '',
 				searchSchoolPoint: '',
-				curScope:'',
-				selectPeriod:0,
-				selectSubject:0,
-				periodList:[{id:'0',name:'0'}],
-				subjectList:[{id:'0',name:'0'}],
+				curScope: '',
+				selectPeriod: 0,
+				selectSubject: 0,
+				periodList: [{
+					id: '0',
+					name: '0'
+				}],
+				subjectList: [{
+					id: '0',
+					name: '0'
+				}],
 				pointList: [],
 				schoolPointList: [],
 				checkedList: [],
@@ -92,16 +97,17 @@
 					code: '',
 					periodId: null,
 					subjectId: null,
-					school_code:null,
+					school_code: null,
 					type: 1
-				}
+				},
+				curPointResponse: null
 			}
 		},
 		created() {
 			console.log('period' + this.period)
 			console.log('subject' + this.subject)
 			console.log('scope' + this.scope)
-			if(this.period && this.subject){
+			if (this.period && this.subject) {
 				this.selectPeriod = this.period
 				this.selectSubject = this.subject
 			}
@@ -114,22 +120,22 @@
 			// 获取当前学校学段学科等基本信息
 			initSchoolData() {
 				this.$store.dispatch('user/getSchoolProfile').then(res => {
-						let schoolBaseInfo = res.school_base
-						if(schoolBaseInfo && schoolBaseInfo.period.length){
-							this.periodList = schoolBaseInfo.period
-							if(this.selectPeriod){
-								console.log(this.selectPeriod)
-								this.subjectList = this.periodList.filter(i => i.id === this.selectPeriod)[0].subjects
-								console.log(this.subjectList.map(i => i.id))
-								console.log(this.selectSubject)
-							}else{
-								this.selectPeriod = schoolBaseInfo.period[0].id
-								this.onPeriodChange(this.periodList[0].id)
-							}
+					let schoolBaseInfo = res.school_base
+					if (schoolBaseInfo && schoolBaseInfo.period.length) {
+						this.periodList = schoolBaseInfo.period
+						if (this.selectPeriod) {
+							console.log(this.selectPeriod)
+							this.subjectList = this.periodList.filter(i => i.id === this.selectPeriod)[0].subjects
+							console.log(this.subjectList.map(i => i.id))
+							console.log(this.selectSubject)
+						} else {
+							this.selectPeriod = schoolBaseInfo.period[0].id
+							this.onPeriodChange(this.periodList[0].id)
 						}
+					}
 				})
 			},
-			
+
 			// 学段切换处理
 			onPeriodChange(val) {
 				this.subjectList = this.periodList.filter(i => i.id === val)[0].subjects
@@ -137,68 +143,65 @@
 				this.selectSubject = this.subjectList[0].id
 				this.subjectList.length && this.getPoints()
 			},
-			
-			onSubjectChange(val){
+
+			onSubjectChange(val) {
 				this.getPoints()
 			},
 
 			doReset() {
 				this.getPoints()
 				this.checkedList = []
-
 			},
 
 			/**
 			 * 获取知识点仓库数据
 			 */
 			getPoints() {
-				if(this.periodList.length && this.subjectList.length){
+				if (this.periodList.length && this.subjectList.length) {
 					this.isLoading = true
 					// if (this.pointList.length && this.schoolPointList.length) return
-					this.defaultParams.code =  this.$store.state.userInfo.schoolCode
-					this.defaultParams.school_code =  this.$store.state.userInfo.schoolCode
+					this.defaultParams.code = this.$store.state.userInfo.schoolCode
+					this.defaultParams.school_code = this.$store.state.userInfo.schoolCode
 					this.defaultParams.periodId = this.selectPeriod
 					this.defaultParams.subjectId = this.selectSubject
-					console.log(this.defaultParams.subjectId)
-					if (this.defaultParams.periodId && this.defaultParams.subjectId){
+
+					if (this.defaultParams.periodId && this.defaultParams.subjectId) {
 						this.$api.knowledge.GetSchoolPoints(this.defaultParams).then(res => {
-							if (!res.error && res.knowledges) {
-									this.schoolPointList = res.knowledges
-									this.originSchoolList = res.knowledges
-								    this.originPointList = this.originPointList.concat(res.knowledges)
+							if (!res.error && res.length) {
+								this.curPointResponse = res[0]
+								this.schoolPointList = res[0].points
+								this.originSchoolList = res[0].points
+								this.originPointList = this.originPointList.concat(res[0].points)
 							} else {
-								this.$Message.warning('获取数据失败')
+								this.$Message.warning('暂无数据')
+								this.uuid = Math.uuid()
+								this.curPointResponse = {
+									blocks: [],
+									code: `Knowledge-${this.$store.state.userInfo.schoolCode}-${this.uuid}`,
+									id: this.uuid,
+									owner: this.$store.state.userInfo.schoolCode,
+									periodId: this.defaultParams.periodId,
+									pk: 'Knowledge',
+									points: [],
+									scope: 'school',
+									subjectId: this.defaultParams.subjectId
+								}
 							}
 							this.isLoading = false
 						})
 					}
 					this.isLoading = true
 				}
-				
-				
+
+
 			},
 
 			/** 添加新知识点 */
 			onAddNewPoint() {
 				let newName = this.newPointName
-				this.uuid = Math.uuid()
 				if (newName) {
-					let params = {
-						type: 1,
-						name: newName,
-						alias: newName,
-						subjectId: this.selectSubject,
-						code: this.$store.state.userInfo.schoolCode,
-						order: 706,
-						status: 1,
-						knowledgeId: this.uuid,
-						periodId: this.period,
-						source: 1,
-						points: [],
-						id: null
-					}
-
-					this.savePoint(params)
+					this.curPointResponse.points.push(newName)
+					this.savePoint()
 				} else {
 					this.$Message.warning(this.$t('evaluation.points.noNameTips'))
 				}
@@ -209,9 +212,9 @@
 			 * @param pointItem
 			 * @param BlockItem
 			 */
-			savePoint(pointItem) {
+			savePoint() {
 				this.isAddLoading = true
-				this.$api.knowledge.SaveOrUpdateKnowledge([pointItem]).then(res => {
+				this.$api.knowledge.SaveOrUpdateKnowledge(this.curPointResponse).then(res => {
 					if (!res.error && res) {
 						this.$Message.success(this.$t('evaluation.points.addSuc'))
 						this.addPointsModal = false
@@ -228,7 +231,9 @@
 
 			onCheckChange(val) {
 				if (val.length > this.max) {
-					this.$Message.warning(`${this.$t('evaluation.points.noNameTips') + this.max + this.$t('evaluation.points.noNameTips')}`)
+					this.$Message.warning(
+						`${this.$t('evaluation.points.noNameTips') + this.max + this.$t('evaluation.points.noNameTips')}`
+						)
 					this.checkedList.splice(this.checkedList.length - 1, 1)
 				} else {
 					this.$emit('onCheckChange', val, this.originPointList)
@@ -239,25 +244,19 @@
 				this.checkedList.splice(index, 1)
 			},
 
-			// 搜索学科输入框onchange事件
-			onSearchChange() {
-				this.pointList = this.originList.filter(item => item.name.indexOf(this.searchPoint) > -1)
-			},
-
 			onSearchSchoolChange() {
-				this.schoolPointList = this.originSchoolList.filter(item => item.name.indexOf(this.searchSchoolPoint) > -1)
+				this.schoolPointList = this.originSchoolList.filter(item => item.indexOf(this.searchSchoolPoint) > -1)
 			},
 		},
 		mounted() {
-			if(this.points.length){
+			if (this.points.length) {
 				this.checkedList = this.points
 			}
 			this.curScope = this.scope
-			console.log(this.curScope)
 		},
-		watch:{
-			scope:{
-				handler(n,o){
+		watch: {
+			scope: {
+				handler(n, o) {
 					console.log(n)
 				}
 			}
@@ -269,13 +268,13 @@
 	.points-container {
 		position: relative;
 	}
-	
-	.points-container .filter-wrap{
+
+	.points-container .filter-wrap {
 		padding: 5px 0 10px 5px;
 		border-bottom: 1px solid #e0e0e0;
 	}
-	
-	.points-container .ivu-select-single{
+
+	.points-container .ivu-select-single {
 		width: 120px;
 		display: inline-block;
 		margin-right: 20px;

+ 4 - 7
TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.vue

@@ -106,9 +106,9 @@
 
 		<Button type="text" @click="backToBank" class="btn-back-to-bank" icon="md-arrow-round-back" style="margin-left: 10px">{{ $t('evaluation.newExercise.backToBank')}}</Button>
 
-		<Modal v-model="selectPointsModal" :title="$t('evaluation.newExercise.choosePoint')" ref="pointRef" width="600px" class="related-point-modal" style="z-index: 99999">
+		<Modal v-model="selectPointsModal" :title="$t('evaluation.newExercise.choosePoint')"  width="600px" class="related-point-modal" style="z-index: 99999">
 			<BasePoints v-if="selectPointsModal" :period="schoolInfo.period[exercisePeriod].id" :subject="subjectList[exerciseSubject].id"
-			 @onCheckChange="onCheckChange" :points="exercisePoints" :scope="curScope"></BasePoints>
+			 @onCheckChange="onCheckChange" :points="exercisePoints" :scope="curScope" ref="pointRef"></BasePoints>
 			<div slot="footer">
 				<Button type="text" @click="selectPointsModal = false">{{ $t('evaluation.cancel') }}</Button>
 				<Button type="primary" @click="selectPointsModal = false">{{ $t('evaluation.confirm') }}</Button>
@@ -412,6 +412,7 @@
 								option: "insert",
 							}).then((res) => {
 								this.isComplete = true
+								localStorage.setItem('noSave','[]')
 								this.$router.push({
 									name: this.exerciseScope === 0 ? "personalBank" : "schoolBank",
 									params: {
@@ -553,7 +554,6 @@
 			 */
 			onDeletePoint(index) {
 				this.exercisePoints.splice(index, 1);
-				this.$refs.pointRef.$children[1].onDeletePoint(index);
 			},
 
 			// 题目类型转换
@@ -680,10 +680,7 @@
 			analysisEditor.config.onchange = (html) => {
 					this.analysisContent = html;
 				},
-				this.$editorTools.addVideoUpload(this, analysisEditor)
-			this.$editorTools.addAudio(this, analysisEditor)
-			this.$editorTools.addCanvas(this, analysisEditor)
-			this.$editorTools.initMyEditor(analysisEditor)
+			this.$editorTools.initMyEditor(analysisEditor,this)
 			analysisEditor.create();
 			this.analysisEditor = analysisEditor;
 		},

+ 2 - 8
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue

@@ -51,10 +51,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			stemEditor.create()
 
 			let answerEditor = new E(this.$refs.answerEditor)
@@ -62,10 +59,7 @@
 				this.answerContent = html
 			}
 			answerEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, answerEditor)
-			this.$editorTools.addAudio(this, answerEditor)
-			this.$editorTools.addCanvas(this, answerEditor)
-			this.$editorTools.initMyEditor(answerEditor)
+			this.$editorTools.initMyEditor(answerEditor,this)
 			answerEditor.create()
 
 			this.stemEditor = stemEditor

+ 1 - 4
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompose.vue

@@ -35,10 +35,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			stemEditor.create()
 			this.stemEditor = stemEditor
 			

+ 2 - 8
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseConnector.vue

@@ -45,10 +45,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			
 			stemEditor.create()
 
@@ -57,10 +54,7 @@
 				this.answerContent = html
 			}
 			answerEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, answerEditor)
-			this.$editorTools.addAudio(this, answerEditor)
-			this.$editorTools.addCanvas(this, answerEditor)
-			this.$editorTools.initMyEditor(answerEditor)
+			this.$editorTools.initMyEditor(answerEditor,this)
 			
 			answerEditor.create()
 

+ 2 - 8
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCorrect.vue

@@ -45,10 +45,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			
 			stemEditor.create()
 
@@ -57,10 +54,7 @@
 				this.answerContent = html
 			}
 			answerEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, answerEditor)
-			this.$editorTools.addAudio(this, answerEditor)
-			this.$editorTools.addCanvas(this, answerEditor)
-			this.$editorTools.initMyEditor(answerEditor)
+			this.$editorTools.initMyEditor(answerEditor,this)
 			
 			answerEditor.create()
 

+ 1 - 4
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseJudge.vue

@@ -43,10 +43,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			
 			stemEditor.create()
 			this.stemEditor = stemEditor

+ 3 - 10
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseMultiple.vue

@@ -68,9 +68,7 @@
 						}
 						
 						editor.config.uploadImgShowBase64 = true;
-						this.$editorTools.addAudio(this, editor)
-						this.$editorTools.addCanvas(this, editor)
-						this.$editorTools.initMyEditor(editor)
+						this.$editorTools.initMyEditor(editor,this,true)
 
 							// 选项编辑器内容发生变化时
 							editor.config.onchange = (html) => {
@@ -111,9 +109,7 @@
 					this.existOptions.push(newIndex)
 					this.$nextTick(() => {
 						let editor = new E(that.$refs['singleOption' + newIndex][0])
-						this.$editorTools.addAudio(this, editor)
-						this.$editorTools.addCanvas(this, editor)
-						this.$editorTools.initMyEditor(editor)
+						this.$editorTools.initMyEditor(editor,this,true)
 						editor.config.onchange = (html) => {
 							let key = String.fromCharCode(64 + parseInt(newIndex + 1))
 							let codeArr = this.optionsContent.map(item => item.code)
@@ -289,10 +285,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			stemEditor.create()
 			this.stemEditor = stemEditor
 			this.initEditors()

+ 3 - 11
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -65,10 +65,7 @@
 								}
 							}
 						}
-
-						this.$editorTools.addAudio(this, editor)
-						this.$editorTools.addCanvas(this, editor)
-						this.$editorTools.initMyEditor(editor)
+						this.$editorTools.initMyEditor(editor,this,true)
 
 						// 选项编辑器内容发生变化时
 						editor.config.onchange = (html) => {
@@ -110,9 +107,7 @@
 					this.existOptions.push(newIndex)
 					this.$nextTick(() => {
 						let editor = new E(that.$refs['singleOption' + newIndex][0])
-						this.$editorTools.addAudio(this, editor)
-						this.$editorTools.initMyEditor(editor)
-						this.$editorTools.addCanvas(this, editor)
+						this.$editorTools.initMyEditor(editor,this,true)
 						editor.config.onchange = (html) => {
 							let key = String.fromCharCode(64 + parseInt(newIndex + 1))
 							let codeArr = this.optionsContent.map(item => item.code)
@@ -241,10 +236,7 @@
 				this.stemContent = html
 			} 
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 
 			stemEditor.create()
 			this.stemEditor = stemEditor

+ 2 - 8
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSubjective.vue

@@ -45,10 +45,7 @@
 				this.stemContent = html
 			}
 			stemEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, stemEditor)
-			this.$editorTools.addAudio(this, stemEditor)
-			this.$editorTools.addCanvas(this, stemEditor)
-			this.$editorTools.initMyEditor(stemEditor)
+			this.$editorTools.initMyEditor(stemEditor,this)
 			
 			stemEditor.create()
 
@@ -57,10 +54,7 @@
 				this.answerContent = html
 			}
 			answerEditor.config.uploadImgShowBase64 = true;
-			this.$editorTools.addVideoUpload(this, answerEditor)
-			this.$editorTools.addAudio(this, answerEditor)
-			this.$editorTools.addCanvas(this, answerEditor)
-			this.$editorTools.initMyEditor(answerEditor)
+			this.$editorTools.initMyEditor(answerEditor,this)
 			
 			answerEditor.create()
 

+ 38 - 16
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue

@@ -184,6 +184,7 @@
 	import AddPoint from './operation/AddPoint'
 	import ComposeBlock from './operation/ComposeBlock'
 	import draggable from "vuedraggable"
+import { json } from 'd3'
 
 	export default {
 		data() {
@@ -400,22 +401,39 @@
 
 			// 根据学科获取所有知识块信息
 			getBlocksData() {
-				let that = this
-				that.pointDatas = []
-				let params = JSON.parse(JSON.stringify(this.currentParams))
-				params.type = 0
+                let that = this
+                that.pointDatas = []
+                let params = JSON.parse(JSON.stringify(this.currentParams))
+                params.type = 0
 				this.$api.knowledge.GetSchoolPoints(params).then(res => {
-					if (res.length) {
-						that.pointDatas = res
-						let list = res[0].blocks
-						this.blockList = list
-						this.originBlockList = JSON.parse(JSON.stringify(list))
-						// this.handleBlockTap(0, list.length ? list[0] : null)
-						setTimeout(function () {
-							that.isLoadBlocks = false
-						}, 400)
-					} else {
-						that.isLoadBlocks =false
+					console.log(res.length)
+                    if (res.length > 0) {
+                        console.log('知识点', JSON.stringify(res))
+                        that.pointDatas = res
+                        let list = res[0].blocks
+                        this.blockList = list
+                        this.originBlockList = JSON.parse(JSON.stringify(list))
+                        // this.handleBlockTap(0, list.length ? list[0] : null)
+                        setTimeout(function () {
+                            that.isLoadBlocks = false
+                        }, 400)
+                    } else {
+						that.isLoadBlocks = false
+                        let params = [{
+                            "owner": this.currentParams.school_code,
+                            "scope": "school",
+                            "periodId": this.currentParams.periodId,
+                            "subjectId": this.currentParams.subjectId,
+                            "points": [],
+                            "blocks": [],
+                            "id": this.$tools.guid(),
+                            "code": "Knowledge" + '-' + this.currentParams.school_code + '-' + this.currentParams.subjectId,
+                            "pk": "Knowledge",
+						}]
+                        that.pointDatas = params
+                        let list = params[0].blocks
+                        this.blockList = list
+                        this.originBlockList = JSON.parse(JSON.stringify(list))
                     } 
 				}).catch(err => {
 					this.$Message.error('知识块数据获取失败')
@@ -429,6 +447,7 @@
 				//this.currentParams.type = 1
 				this.$api.knowledge.GetSchoolPoints(this.currentParams).then(res => {
 					if (res.length) {
+						console.log(res)
 						this.pointList = res[0].points
 						this.originPointList = JSON.parse(JSON.stringify(res[0].points))
 						setTimeout(function () {
@@ -803,9 +822,12 @@
                     params = this.pointDatas[0]
                     params.points = [...this.originPointList]
 					params.blocks = [...this.originBlockList]
+                    console.log(params)
                     this.$api.knowledge.SaveOrUpdateKnowledge(params).then(res => {
                         if (res) {
-                            this.$Message.success('保存数据成功')
+							this.$Message.success('保存数据成功')
+							this.getPointsData()
+							this.initBlockCount()
                         } else {
                             this.$Message.warning('保存数据失败')
                         }

+ 8 - 8
TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue

@@ -262,7 +262,7 @@ export default {
                 targets: [
                     { required: true, message: this.$t('learnActivity.createEv.errTips6'), type: 'array', trigger: 'change' }
                 ],
-                targetClassIds: [
+                classes: [
                     { required: true, message: this.$t('learnActivity.createEv.errTips6'), type: 'array', trigger: 'change' }
                 ],
                 publish: [
@@ -279,7 +279,7 @@ export default {
             evaluationInfo: {
                 name: '',
                 targets: [],
-                targetClassIds: [],
+                classes: [],
                 scope: 'school',
                 type: '',  //测试类别
                 source: '',
@@ -308,7 +308,7 @@ export default {
         //重置课程类型
         resetCourse() {
             this.evaluationInfo.targets = []
-            this.evaluationInfo.targetClassIds = []
+            this.evaluationInfo.classes = []
         },
         //新结构 校本和个人课程一个API返回
         getCourseList() {
@@ -465,7 +465,7 @@ export default {
                             })
                             if (defCus) {
                                 defCus.children.forEach(item => {
-                                    if (this.evaluationInfo.targetClassIds.indexOf(item.value) > -1) {
+                                    if (this.evaluationInfo.classes.indexOf(item.value) > -1) {
                                         let arr = [defCus.value, item.value]
                                         this.evaluationInfo.targets.push(arr)
                                     }
@@ -515,8 +515,8 @@ export default {
             }
 
             //获取施测对象id 
-            this.evaluationInfo.targetClassIds = []
-            this.evaluationInfo.targetClassIds = this.evaluationInfo.targets.map(item => {
+            this.evaluationInfo.classes = []
+            this.evaluationInfo.classes = this.evaluationInfo.targets.map(item => {
                 return item[1]
             })
             //设置评测“学科”
@@ -682,13 +682,13 @@ export default {
                 year: new Date().getFullYear(),
                 // range: this.mode,
                 source: this.evaluationInfo.source,
-                targetClassIds: this.evaluationInfo.targetClassIds,
+                classes: this.evaluationInfo.classes,
                 publish: this.evaluationInfo.publish,
                 startTime: this.evaluationInfo.publish == 0 ? Math.round(new Date()) : this.evaluationInfo.startTime,
                 endTime: this.evaluationInfo.endTime,
                 scope: this.evaluationInfo.scope,
                 createDate: Math.round(new Date()),
-                owner: this.evaluationInfo.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId //后面新增字段
+                blobcntr: this.evaluationInfo.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId //后面新增字段
             }
 
             this.$api.learnActivity.SaveExamInfo(requestData).then(

+ 5 - 5
TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue

@@ -176,7 +176,7 @@ export default {
             evaluationInfo: {
                 name: '',
                 targets: [],
-                targetClassIds: [],
+                classes: [],
                 grades: [],
                 type: '',  //测试类别
                 source: '',
@@ -238,7 +238,7 @@ export default {
 
         treeChange(data) {
             //获取classIds
-            this.evaluationInfo.targetClassIds = data.map(item => {
+            this.evaluationInfo.classes = data.map(item => {
                 return item[1]
             })
             //获取年级对象
@@ -496,13 +496,13 @@ export default {
                 year: new Date().getFullYear(),
                 range: this.mode,
                 source: this.evaluationInfo.source,
-                targetClassIds: this.evaluationInfo.targetClassIds,
+                classes: this.evaluationInfo.classes,
                 publish: this.evaluationInfo.publish,
                 startTime: this.evaluationInfo.publish == 0 ? Math.round(new Date()) : this.evaluationInfo.startTime,
                 endTime: this.evaluationInfo.endTime,
                 scope: this.mode,
                 createDate: Math.round(new Date()),
-                owner: this.$store.state.userInfo.schoolCode //后面新增字段
+                blobcntr: this.$store.state.userInfo.schoolCode //后面新增字段
             }
 
             this.$api.learnActivity.SaveExamInfo(requestData).then(
@@ -660,7 +660,7 @@ export default {
             this.$store.dispatch('user/getSchoolProfile').then(
                 res => {
                     let f = res.school_classes.filter((item) => {
-                        return routerData.targetClassIds.indexOf(item.id) > -1
+                        return routerData.classes.indexOf(item.id) > -1
                     })
                     this.evaluationInfo.targets = []
                     f.forEach((item, index) => {

+ 3 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue

@@ -81,7 +81,7 @@
                 </div>
                 <!-- 试卷评测打分 -->
                 <div :class="curBarIndex == 0 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="curBarIndex == 0">
-                    <Scoring :examInfo="examDetaiInfo" ref="score-box"></Scoring>
+                    <PrivScoring :examInfo="examDetaiInfo" ref="score-box"></PrivScoring>
                 </div>
             </div>
         </Split>
@@ -89,11 +89,11 @@
 </template>
 <script>
 import TestPaper from '@/view/evaluation/index/TestPaper.vue'
-import Scoring from './Scoring.vue'
+import PrivScoring from './PrivScoring.vue'
 export default {
     components: {
         TestPaper,
-        Scoring
+        PrivScoring
     },
     inject: ['reload'],
     data() {

+ 11 - 5
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -320,6 +320,11 @@ export default {
             default: '',
             required: true
         },
+        examScope:{
+            type: String,
+            default: '',
+            required: true
+        },
         subjectId: {
             type: String,
             default: '',
@@ -379,7 +384,7 @@ export default {
                 "subjectId": this.subjectId,
                 "classId": this.studentAnswer.classId,
                 // "code": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "code": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "code": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
             }).then(
                 res => {
                     this.$Message.success(this.$t('learnActivity.score.markOk'))
@@ -492,12 +497,12 @@ export default {
             let requestData = {
                 "id": this.examId,
                 // "code": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "code": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "code": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
                 "point": this.studentAnswer.scores,
                 "studentId": this.studentAnswer.id,
                 "classId": this.studentAnswer.classId,
                 // "school": this.paperInfo.code,//这种方式paper code规则调整了,会多Paper-"
-                "school": this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
+                "school": this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId,//暂时取代上面的方式
                 "subjectId": this.subjectId
             }
             this.$api.learnActivity.UpsertAllRecord(requestData).then(res => {
@@ -580,6 +585,7 @@ export default {
         },
         paperInfo: {
             handler(newPaper) {
+                console.log('newPaper',newPaper)
                 if (newPaper && newPaper.item) {
                     this.dataLoading = true
                     let that = this
@@ -613,8 +619,8 @@ export default {
                 if (!this.studentAnswer.status) {
                     if (newValue.answers.length) {
                         try {
-                            let sas = this.scope == 'school' ? this.$store.state.user.schoolProfile.blob_sas : this.$store.state.user.userProfile.blob_sas
-                            let container = this.scope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+                            let sas = this.examScope == 'school' ? this.$store.state.user.schoolProfile.blob_sas : this.$store.state.user.userProfile.blob_sas
+                            let container = this.examScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
                             //为了兼容原来完整的路径,这里做判断
                             let a = null
                             if (newValue.answers[0].indexOf('https://teammodelstorage') > -1) {

+ 97 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.less

@@ -0,0 +1,97 @@
+@main-bgColor: rgb(40,40,40); //主背景颜色
+@borderColor: #424242;
+@primary-textColor: #fff; //文本主颜色
+@second-textColor: #a5a5a5; //文本副级颜色
+@primary-fontSize: 14px;
+@second-fontSize: 16px;
+
+.ev-scoring {
+    width: 100%;
+    height: 100%;
+    padding: 0px 0px 20px 0px;
+}
+.ev-scoring {
+    .ev-scoring-header {
+        width: 100%;
+        height: 36px;
+        line-height: 36px;
+        color: @second-textColor;
+        border-bottom: 1px solid @borderColor;
+    }
+
+    .subject-item {
+        display: inline-block;
+        margin-right: 15px;
+        color: @second-textColor;
+        cursor: pointer;
+        line-height: 30px;
+        padding:0px 5px;
+        font-size: 15px;
+        text-align: center;
+        margin-left: 10px;
+    }
+
+    .subject-item-active {
+        color: @primary-textColor;
+        border-bottom: 2px solid white;
+        font-weight: 500;
+    }
+}
+.common-icon-text {
+    color: white;
+    cursor: pointer;
+    user-select: none;
+}
+.scoring-main-wrap {
+    width: ~"calc(100% - 10px)";
+    // width: 100%;
+    height: ~"calc(100% - 45px)";
+}
+
+.ev-target-box {
+    // margin-top: 20px;
+    width: ~"calc(100% - 10px)";
+    color: #ffffff;
+    background: rgba(50, 50, 50, 1);
+    padding: 10px 10px 10px 5px;
+    position: sticky;
+    top: 0px;
+    z-index: 9999;
+    .filter-select {
+        display: inline-block;
+        width: 120px;
+        margin-right: 25px;
+    }
+}
+
+.scoring-handle-box {
+    height: 100%;
+    background:white;
+    padding-bottom:15px;
+}
+
+.stu-status-tag{
+    background: #ed4014;
+    font-size: 12px;
+    padding: 3px 8px;
+    font-weight: 800;
+    border-radius: 4px;
+    color: white;
+}
+.select-status-tag{
+    display: inline-block;
+    width: 7px;
+    height: 7px;
+    border-radius: 50%;
+    margin-right: 5px;
+}
+.simple-analysis-box{
+    width: 100%;
+    height: 200px;
+    // background: white;
+}
+.page-wrap{
+    float: right;
+    margin-top: 15px;
+    color: white;
+}

+ 703 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.vue

@@ -0,0 +1,703 @@
+<template>
+    <div class="ev-scoring dark-iview-table">
+        <vuescroll ref="score-main-warp">
+            <SimpleAnalysis :examInfo="examInfo" v-show="!showTest" :overviewInfo="overviewInfo"></SimpleAnalysis>
+            <div class="ev-target-box dark-iview-select">
+                <span class="filter-label" v-if="examInfo.grades && examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
+                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-if="examInfo.grades && examInfo.grades.length > 0" style="margin-right:5px" transfer>
+                    <Option v-for="(item,index) in examInfo.grades" :value="item.id" :key="index">{{ item.name }}</Option>
+                </Select>
+                <span>{{$t('learnActivity.score.classLabel')}}</span>
+                <Select filterable v-model="chooseClass" class="filter-select" style="width:140px;" @on-change="getClassStudent" size="small" transfer>
+                    <Option v-for="(item,index) in classList" :value="item.id" :key="index">{{ item.name }}</Option>
+                </Select>
+                <span style="margin-left:5px" v-show="showTest">{{$t('learnActivity.score.stuLabel')}}</span>
+                <Select filterable v-model="chooseStudent.id" label-in-value class="filter-select" style="width:140px;" size="small" clearable @on-change="setStuInfo" v-show="showTest" transfer>
+                    <Option v-for="(item,index) in students" :value="item.id" :key="index">
+                        <span class="select-status-tag" :style="{'background':item.status == 1 ? '#ed4014' : item.status == 2 ? '#ff9900' : '#19be6b'}"></span>
+                        {{ item.name }}
+                    </Option>
+                </Select>
+                <span v-show="showTest" class="common-icon-text" style=" float: right; margin-right: 25px;" @click="toggleScoreStatus" icon="md-apps">
+                    <Icon :custom="showTest ? 'iconfont icon-table':'iconfont icon-scoring'" style="margin-right:5px;" />
+                    {{showTest ? $t('learnActivity.score.scoreView'):$t('learnActivity.score.scoring')}}
+                </span>
+            </div>
+            <div class="scoring-main-wrap">
+                <Table v-show="!showTest" class="score-box" border :columns="tableColumn" :data="tableData" :loading="tableLoading" @on-sort-change="onSortChange" :no-data-text="$t('learnActivity.score.classNoStu')">
+                    <template slot-scope="{ row,index }" :slot="'qu'+qIndex" v-for="(item,qIndex) in quCount">
+                        <div :key="'qu'+qIndex" @click="getStuScore(row,qIndex)" style="cursor:pointer;">
+                            <span @click="noAnswer" v-if="row.data[qIndex] == -1 && row.status == 1">- -</span>
+                            <Icon size="20" type="ios-create-outline" color="#2db7f5" v-else-if="row.data[qIndex] == -1 && row.status !== 1" />
+                            <span style="color:#2db7f5;" v-else>{{row.data[qIndex]}}</span>
+                        </div>
+                    </template>
+                    <!-- <template slot-scope="{ row,index }" slot="total">
+                        <strong>{{getcount(studentScore[row._index].data)}}</strong>
+                    </template> -->
+                    <!-- 1: 未作答 2:未评分 3:已评分 -->
+                    <template slot-scope="{ row,index }" slot="status">
+                        <span class="stu-status-tag" @click="getStuScore(row,0)" :style="{'background':row.status == 1 ? '#c5c8ce' : row.status == 2 ? '#ff9900' : '#19be6b', 'cursor':row.status == 1 ? 'text':'pointer'}">
+                            {{row.status == 1 ? $t('learnActivity.score.status1') : row.status == 2 ? $t('learnActivity.score.status2') : $t('learnActivity.score.status3')}}
+                        </span>
+                    </template>
+                    <Loading slot="loading" :top="-50"></Loading>
+                </Table>
+                <!-- 分页 -->
+                <div class="page-wrap dark-ivew-select" v-show="!showTest">
+                    <Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" :page-size-opts="pageSizeOpts" @on-change="pageChange" @on-page-size-change="pageSizeChange" show-sizer />
+                </div>
+                <div class="dark-iview-table scoring-handle-box" v-show="showTest">
+                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :examScope="examInfo.scope" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
+                    <Loading :top="200" type="1" style="text-align:center" v-show="dataLoading"></Loading>
+                </div>
+            </div>
+        </vuescroll>
+    </div>
+</template>
+<script>
+import PaperScore from "./PaperScore.vue";
+import SimpleAnalysis from "./SimpleAnalysis.vue";
+export default {
+    props: {
+        examInfo: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        }
+    },
+    components: {
+        PaperScore, SimpleAnalysis
+    },
+    data() {
+        return {
+            schoolClassList: [],
+            originData: [],
+            studentScore: [],
+            tableData: [],
+            currentPage: 1,
+            pageSize: 10,
+            pageSizeOpts: [5, 10, 20, 30, 40],
+            overviewInfo: {
+                total: 0,
+                answered: 0,
+                noAnswer: 0,
+                scored: 0,
+                noScore: 0
+            },
+            defaultIndex: 0,
+            tableLoading: false,
+            showTest: false, //是否评分
+            studentData: [],
+            dataLoading: false,
+            chooseGrade: "",
+            chooseClass: "",
+            chooseSubject: "",
+            chooseStudent: {
+                id: "",
+                name: "",
+                scores: [],
+                answers: []
+            },
+            classStudents:[], //校本名单学生列表,可以从这里面获取班级信息
+            scoreList: [
+                {
+                    title: this.$t('learnActivity.score.column1'),
+                    key: "name",
+                    fixed: "left",
+                    align: "center",
+                    minWidth: 150,
+                },
+                {
+                    title: this.$t('learnActivity.score.column2'),
+                    key: "total",
+                    align: "center",
+                    sortable: true,
+                    fixed: "right",
+                    width: 100
+                },
+                {
+                    title: this.$t('learnActivity.score.column3'),
+                    slot: "status",
+                    align: "center",
+                    fixed: "right",
+                    width: 100,
+                }
+            ],
+            tableColumn: [],
+            quCount: [],
+            paperInfo: {},
+            students: [],
+            privStuList: undefined,
+            routerScope: ''
+        }
+    },
+    methods: {
+        // 排序操作
+        onSortChange(data) {
+            let order = data.order // 当前排序方式 升序、降序、正常
+            let key = data.key // 当前排序依据
+            switch (order) {
+                case 'asc':
+                    this.studentScore = this.originData.sort((a, b) => { return Number(a[key]) - Number(b[key]) })
+                    break
+                case 'desc':
+                    this.studentScore = this.originData.sort((a, b) => { return Number(b[key]) - Number(a[key]) })
+                    break
+                case 'normal':
+                    this.studentScore = this.students
+                    break
+                default:
+                    break
+            }
+            console.log('1', this.studentScore[0].name)
+            console.log(2, this.originData[0].name)
+            this.pageChange(1)
+        },
+        // 页面size变化
+        pageSizeChange(val) {
+            this.pageSize = val
+            this.pageChange(1)
+        },
+        // 分页页面变化
+        pageChange(page) {
+            let start = this.pageSize * (page - 1)
+            let end = this.pageSize * page
+            this.currentPage = page
+            this.tableData = this.studentScore.slice(start, end)
+        },
+        toggleScoreStatus() {
+            this.$refs['paperScore'].isComplete = false
+            this.showTest = !this.showTest
+        },
+        getNextStu() {
+            let flag = false
+            for (let index in this.paperInfo[this.chooseClass].studentAns.studentScores) {
+                if (this.paperInfo[this.chooseClass].studentAns.studentScores[index].indexOf(-1) >= 0) {
+                    if (this.paperInfo[this.chooseClass].studentAns.studentAnswers[index].length) {
+                        flag = true
+                        this.chooseStudent.id = this.paperInfo[this.chooseClass].studentAns.studentIds[index]
+                        let curStu = this.students.find(item => {
+                            return item.id == this.chooseStudent.id
+                        })
+                        if (curStu) this.chooseStudent.name = curStu.name
+                        this.chooseStudent.answers = this.paperInfo[this.chooseClass].studentAns.studentAnswers[index]
+                        this.chooseStudent.scores = this.paperInfo[this.chooseClass].studentAns.studentScores[index]
+                        this.chooseStudent.classId = this.chooseClass
+                        this.chooseStudent.status = false
+                        this.$refs['paperScore'].isComplete = false
+                        break
+                    }
+                }
+            }
+            if (!flag) {
+                this.showTest = false
+                this.$Message.warning(this.$t('learnActivity.score.finishScore'))
+            }
+        },
+        //学生未作答提示
+        noAnswer() {
+            this.$Message.warning(this.$t('learnActivity.score.unableScore'))
+        },
+        //点击学生题号前往评分页面
+        getStuScore(data, qIndex) {
+            if (data.status == 2 || data.status == 3) {
+                this.$refs['paperScore'].isComplete = false
+                this.showTest = true
+                this.defaultIndex = qIndex
+                this.chooseStudent.id = data.id
+                this.chooseStudent.name = data.name
+                this.chooseStudent.classId = this.chooseClass
+                let answerIndex = this.paperInfo[this.chooseClass].studentAns.studentIds.indexOf(data.id)
+                if (answerIndex >= 0) {
+                    this.chooseStudent["scores"] = this.paperInfo[this.chooseClass].studentAns.studentScores[answerIndex]
+                    this.chooseStudent["answers"] = this.paperInfo[this.chooseClass].studentAns.studentAnswers[answerIndex]
+                    this.chooseStudent["status"] = false
+                }
+            }
+        },
+        //获取当前学生信息
+        setStuInfo(data) {
+            if (data) {
+                this.chooseStudent.name = data.label;
+                this.chooseStudent.classId = this.chooseClass
+                let answerIndex = this.paperInfo[this.chooseClass].studentAns.studentIds.indexOf(data.value);
+                if (answerIndex >= 0) {
+                    this.chooseStudent["scores"] = this.paperInfo[this.chooseClass].studentAns.studentScores[answerIndex];
+                    this.chooseStudent["answers"] = this.paperInfo[this.chooseClass].studentAns.studentAnswers[answerIndex];
+                    this.chooseStudent["status"] = false;
+                }
+            }
+        },
+        //分数求和
+        getcount(arr) {
+            return arr.reduce((total, item) => {
+                if (item !== -1) {
+                    return total + item;
+                } else {
+                    return total;
+                }
+            }, 0);
+        },
+        // 获取班级名单
+        async getClassStudent() {
+            this.showTest = false
+            this.tableLoading = true
+            if (!this.chooseClass) return
+            let stuRes = undefined
+            try {
+                //个人自定义名单则直接根据学生id换name
+                if (this.examInfo.scope == 'private') {
+                    let stuListInfo = this.privStuList.find(item => {
+                        return item.id == this.chooseClass
+                    })
+                    if (stuListInfo) {
+                        stuRes = await this.$api.courseMgmt.findStuSummary({
+                            students: stuListInfo.students
+                        })
+                    }
+                }
+                //校本名单或教室则根据班级id或学生
+                else {
+                    let requestData = {
+                        ids: [this.chooseClass],
+                        scope: this.examInfo.scope == 'private' ? 'private' : 'school',
+                        // school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }
+                    stuRes = await this.$api.schoolSetting.getClassroomStudent(requestData)
+                }
+            } catch (e) {
+                this.$Message.error('获取学生名单失败')
+            }
+            console.log('***', stuRes)
+            if (!stuRes.error) {
+                if (!this.paperInfo[this.chooseClass]) {
+                    this.paperInfo[this.chooseClass] = {}
+                }
+                let classStu = {
+                    students: this.examInfo.scope == 'private' ? stuRes.stus || [] : stuRes.stus ? stuRes.stus[0] : [],
+                    id: this.chooseClass
+                }
+                this.$set(this.paperInfo[this.chooseClass], "students", classStu)
+                this.students = []
+                this.tableData = []
+                this.studentScore = []
+                this.tableColumn = [...this.scoreList]
+                let defSocre = []
+                if (this.examInfo.progress == 'pending') {//如果评测未发布,没有学生数据,则直接渲染表格
+                    this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0
+                    for (let i = 0; i < this.quCount; i++) {
+                        let data = {
+                            title: "Q" + (i + 1),
+                            slot: "qu" + i,
+                            align: "center",
+                            minWidth: 65,
+                        }
+                        this.tableColumn.push(data)
+                        defSocre.push(-1)
+                    }
+                    let classStu = this.paperInfo[this.chooseClass].students.students
+                    for (let k = 0; k < classStu.length; k++) {
+                        let score = {}
+                        score.name = classStu[k].name
+                        score.id = classStu[k].id
+                        score.data = defSocre
+                        score.total = 0
+                        score.status = 1
+                        this.studentScore.push(score)
+                    }
+                    this.pageChange(1)
+                    this.tableLoading = false
+                } else {//如果获取进行中或已结束则需要拉取学生数据
+                    this.getStudentAnswer()
+                }
+            } else {
+                this.$Message.error("API ERROR!");
+            }
+        },
+        //计算总览数据
+        calcOverView(data) {
+            //计算已作答未作答
+            this.overviewInfo.noAnswer = 0
+            data.studentAnswers.forEach(item => {
+                if (item.length == 0) {
+                    this.overviewInfo.noAnswer++
+                }
+            })
+            this.overviewInfo.answered = data.studentAnswers.length - this.overviewInfo.noAnswer
+            // 计算已评分未评分
+            this.overviewInfo.noScore = 0
+            data.studentScores.forEach(item => {
+                let flag = item.find(item => {
+                    return item == -1
+                })
+                if (flag) {
+                    this.overviewInfo.noScore++
+                }
+            })
+            this.overviewInfo.scored = data.studentScores.length - this.overviewInfo.noScore
+            // 班级总人数
+            this.overviewInfo.total = data.studentIds.length
+        },
+        getStudentAnswer() {
+            this.dataLoading = true
+            let requestData = {
+                id: this.examInfo.id,
+                code: this.examInfo.scope == 'school' ? this.$store.state.user.schoolCode : this.$store.state.userInfo.TEAMModelId,
+                subjectId: this.chooseSubject,
+                classId: this.chooseClass,
+            };
+            this.$api.learnActivity.FindAllStudent(requestData).then(
+                (res) => {
+                    if (res.examClassResults) {
+                        this.paperInfo[this.chooseClass]["studentAns"] = res.examClassResults[0];
+                        this.setTableData();
+                        if (res.examClassResults[0]) {
+                            this.calcOverView(res.examClassResults[0])
+                        }
+                    }
+                },
+                (err) => {
+                    this.$Message.error("API ERROR!");
+                }
+            ).finally(() => {
+                setTimeout(() => {
+                    this.dataLoading = false
+                    this.tableLoading = false
+                }, 500);
+            });
+        },
+        //初始化表单数据
+        setTableData() {
+            if (this.paperInfo[this.chooseClass] && this.paperInfo[this.chooseClass]["students"] && this.paperInfo[this.chooseClass]["studentAns"]) {
+                let studentData = this.paperInfo[this.chooseClass]["students"]
+                let studentAns = this.paperInfo[this.chooseClass]["studentAns"]
+                this.studentScore = []
+                this.tableColumn = [...this.scoreList]
+                this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
+                // this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0 //不用试卷信息计算题目
+                for (let i = 0; i < this.quCount; i++) {
+                    let data = {
+                        title: "Q" + (i + 1),
+                        slot: "qu" + i,
+                        align: "center",
+                        minWidth: 65,
+                    }
+                    this.tableColumn.push(data);
+                }
+                let ans = []
+                for (let i = 0; i < studentAns.studentIds.length; i++) {
+                    for (let k = 0; k < studentData.students.length; k++) {
+                        let score = {}
+                        if (studentAns.studentIds[i] == studentData.students[k].id) {
+                            score.name = studentData.students[k].name
+                            score.id = studentAns.studentIds[i]
+                            score.data = studentAns.studentScores[i]
+                            score.total = this.getcount(score.data)
+                            if (studentAns.studentAnswers[i].length == 0) {//学生未作答
+                                score.status = 1
+                            } else if (studentAns.studentScores[i].indexOf(-1) >= 0) {//已作答,未评分
+                                score.status = 2
+                            } else {//已批改
+                                score.status = 3
+                            }
+                            this.studentScore.push(score)
+                        }
+                    }
+                }
+                this.originData = this._.cloneDeep(this.studentScore)
+                this.students = this._.cloneDeep(this.studentScore)
+                this.pageChange(1)
+                if (ans.length) {
+                    for (let k = 0; k < this.paperInfo.papers.item.length; k++) {
+                        this.$set(
+                            this.paperInfo.papers.item[k],
+                            "answerData",
+                            ans[k]
+                        );
+                        this.$set(
+                            this.paperInfo.papers.item[k],
+                            "stuScore",
+                            score[k]
+                        );
+                    }
+                }
+            }
+
+        },
+        getBack(data) {
+            if (data == "1") {
+                this.getClassStudent();
+            }
+            this.showTest = false;
+        },
+        //获取单个学生作答数据
+        getStudentInfo(data, index) {
+            this.dataLoading = true;
+            if (this.studentInfo !== undefined) {
+                let filData = "";
+                filData = this.studentInfo.id;
+                let ans = [];
+                let score = [];
+                for (let i = 0; i < this.classDatas.studentIds.length; i++) {
+                    if (this.classDatas.studentIds[i] == filData) {
+                        ans = this.classDatas.studentAnswers[i];
+                        score = this.classDatas.studentScores[i];
+                    }
+                }
+                if (ans.length) {
+                    for (let k = 0; k < this.paperInfo.papers.item.length; k++) {
+                        this.$set(this.paperInfo.papers.item[k], "answerData", ans[k]);
+                        this.$set(this.paperInfo.papers.item[k], "stuScore", score[k]);
+                    }
+                }
+                this.dataLoading = false;
+            } else {
+                this.dataLoading = false;
+                this.$Message.warning(this.$t('learnActivity.score.stStuWarning'));
+            }
+            this.selectIndex = index;
+        },
+        getAnswer(data) {
+            //处理学生作答信息
+            let listArr = [];
+            data.forEach(function (el, index) {
+                for (var i = 0; i < listArr.length; i++) {
+                    if (listArr[i].group == el.group) {
+                        listArr[i].listInfo.push(el);
+                        return;
+                    }
+                }
+                listArr.push({
+                    group: el.group,
+                    listInfo: [el],
+                });
+            });
+            return listArr;
+        },
+    },
+    watch: {
+        examInfo: {
+            handler(n, o) {
+                this.privStuList = undefined
+                if (n.subjects && n.subjects.length) {
+                    this.chooseSubject = n.subjects[0].id;
+                }
+                if (n.grades && n.grades.length) {
+                    this.chooseGrade = n.grades[0].id;
+                }
+                if (n.papers && n.papers.length) {
+                    this.paperInfo = n.papers[0] //个人评测只有单科
+                } else {
+                    this.paperInfo = {};
+                }
+                if (n.scope == 'school') {
+                    let requestData = {
+                        ids: this.examInfo.classes,
+                        scope: this.examInfo.scope,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }
+                    this.$api.schoolSetting.getClassroomStudent(requestData).then(
+                        res => {
+                            if (res && res.stus) {
+                                this.classStudents = res.stus
+                            }
+                        },
+                        err => {
+                            console.log('获取发布对象失败')
+                        }
+                    )
+                }
+            },
+            deep: true,
+        },
+        classList: {
+            handler(n, o) {
+                if (n && n.length) {
+                    this.chooseClass = n[0].id;
+                    this.getClassStudent();
+                } else {
+                    this.chooseClass = undefined
+                }
+            },
+            deep: true,
+        },
+        chooseStudent: {
+            handler(n, o) {
+                if (n.id) {
+                    let curStu = this.studentScore.find(item => {
+                        return item.id == n.id
+                    })
+                    if (curStu.status == 2) {
+                        let flag = n.scores.find(item => {
+                            return item == -1
+                        })
+                        if (!flag) {
+                            curStu.status = 3
+                            this.overviewInfo.noScore--
+                            this.overviewInfo.scored++
+                        }
+                    }
+                }
+            },
+            deep: true
+        }
+    },
+    computed: {
+        classList() {
+            if (this.examInfo && this.examInfo.classes) {
+                //发布对象为校本名单
+                if (this.examInfo.scope == 'school') {
+                    this.showTest = false
+                    //classStudents 监听评测数据的时候就获取了
+                    let classes = this.classStudents.map(item=>{
+                        return {
+                            id: item[0].classId,
+                            name: item[0].className
+                        }
+                    })
+                    console.log('班级学生数据',classes)
+                    return classes
+                }
+                // 发布对象为个人创建的自定义名单
+                else {
+                    if (!this.privStuList) {
+                        //查询当前老师所有stulist
+                        let params = {
+                            code: this.$store.state.userInfo.TEAMModelId,
+                            scope: 'private'
+                        }
+                        this.$api.courseMgmt.findStulist(params).then(
+                            res => {
+                                this.privStuList = res.stuList
+                            },
+                            err => {
+                                this.$Message.error('API error')
+                            }
+                        )
+                        return this.privStuList
+                    } else {
+                        //过滤当前评测对象
+                        let list = this.privStuList.filter(item => {
+                            return this.examInfo.classes.indexOf(item.id) >= 0
+                        })
+                        return list
+                    }
+                }
+            } else {
+                return []
+            }
+        },
+    },
+    created() {
+        this.$store.dispatch('user/getSchoolProfile').then(
+            res => {
+                this.schoolBase = res.school_base
+                this.schoolClassList = res.school_classes
+            }
+        )
+        if (this.$route.name == 'privateEvaluation') {
+            this.routerScope = 'private'
+        } else {
+            this.routerScope = 'school'
+        }
+    }
+};
+</script>
+
+<style scoped lang="less">
+@import "./Scoring.less";
+</style>
+<style lang="less">
+.scoring-main-wrap .ivu-table-fixed-body {
+    background: #353535;
+    // background: #2b2b2e;
+    // max-height: 653px;
+}
+.scoring-main-wrap .ivu-table-tip {
+    position: relative;
+    z-index: 9999;
+}
+.scoring-main-wrap .ivu-table-fixed-right::before,
+.scoring-main-wrap .ivu-table-fixed::before {
+    display: none;
+}
+.scoring-main-wrap .ivu-table-fixed-header thead tr th {
+    background: #353535;
+    // background: #2b2b2e;
+    border-color: #606060;
+    color: white;
+}
+.scoring-main-wrap {
+    .ivu-table-header thead tr th {
+        // background: #353535;
+        background: rgba(53, 53, 53, 0.5);
+    }
+    .ivu-table td {
+        // background: #353535;
+        background: rgba(53, 53, 53, 0.5);
+    }
+}
+.page-wrap .ivu-page-item {
+    background: rgba(40, 40, 40, 0.5);
+}
+
+.page-wrap .ivu-page-item:hover {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active {
+    background: #bfbfb9;
+}
+
+.page-wrap .ivu-page-item a {
+    color: #f1f1f1;
+}
+
+.page-wrap .ivu-page-next,
+.page-wrap .ivu-page-prev {
+    background: rgba(0, 0, 0, 0);
+}
+
+.page-wrap .ivu-page-next a,
+.page-wrap .ivu-page-prev a {
+    color: #e4eadb;
+}
+
+.page-wrap .ivu-page-next:hover,
+.page-wrap .ivu-page-prev:hover {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active,
+.page-wrap .ivu-page-item:hover a {
+    border-color: #e4eadb;
+}
+
+.page-wrap .ivu-page-item-active a {
+    color: #595959;
+}
+.page-wrap
+    .ivu-select-small.ivu-select-single
+    .ivu-select-selection
+    .ivu-select-selected-value {
+    height: 27px;
+    line-height: 27px;
+    font-size: 12px;
+}
+.page-wrap .ivu-select-single .ivu-select-selection {
+    height: 30px;
+    background: transparent;
+    border: 1px solid #595959;
+    box-shadow: none;
+    color: #cecece;
+}
+
+.page-wrap .ivu-select-single .ivu-select-placeholder {
+    height: 30px;
+    line-height: 30px;
+    font-size: 16px;
+}
+</style>

+ 48 - 28
TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue

@@ -3,16 +3,16 @@
         <vuescroll ref="score-main-warp">
             <SimpleAnalysis :examInfo="examInfo" v-show="!showTest" :overviewInfo="overviewInfo"></SimpleAnalysis>
             <div class="ev-target-box dark-iview-select">
-                <span class="filter-label" v-show="examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
-                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-show="examInfo.grades.length > 0" style="margin-right:5px" transfer>
+                <span class="filter-label" v-if="examInfo.grades && examInfo.grades.length > 0">{{$t('learnActivity.score.gradeLabel')}}</span>
+                <Select filterable v-model="chooseGrade" class="filter-select" size="small" v-if="examInfo.grades && examInfo.grades.length > 0" style="margin-right:5px" transfer>
                     <Option v-for="(item,index) in examInfo.grades" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
                 <span>{{$t('learnActivity.score.classLabel')}}</span>
                 <Select filterable v-model="chooseClass" class="filter-select" style="width:140px;" @on-change="getClassStudent" size="small" transfer>
                     <Option v-for="(item,index) in classList" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
-                <span class="filter-label" v-show="examInfo.scope == 'school'">{{$t('learnActivity.score.subjectLabel')}}</span>
-                <Select filterable v-model="chooseSubject" class="filter-select" size="small" @on-change="getCurPaper" v-show="examInfo.scope == 'school'" transfer>
+                <span class="filter-label" v-show="examInfo.code == 'Exam-'+$store.state.userInfo.schoolCode">{{$t('learnActivity.score.subjectLabel')}}</span>
+                <Select filterable v-model="chooseSubject" class="filter-select" size="small" @on-change="getCurPaper" v-show="examInfo.code == 'Exam-'+$store.state.userInfo.schoolCode" transfer>
                     <Option v-for="(item,index) in examInfo.subjects" :value="item.id" :key="index">{{ item.name }}</Option>
                 </Select>
                 <span style="margin-left:5px" v-show="showTest">{{$t('learnActivity.score.stuLabel')}}</span>
@@ -52,7 +52,7 @@
                     <Page show-total size="small" :current="currentPage" :total="studentScore.length" :page-size="pageSize" :page-size-opts="pageSizeOpts" @on-change="pageChange" @on-page-size-change="pageSizeChange" show-sizer />
                 </div>
                 <div class="dark-iview-table scoring-handle-box" v-show="showTest">
-                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
+                    <PaperScore ref="paperScore" :defaultIndex="defaultIndex" :examId="examInfo.id" :examScope="examInfo.scope" :paper="paperInfo" :studentAnswer="chooseStudent" :subjectId="chooseSubject" @nextStu="getNextStu" style="color:#515a6e;"></PaperScore>
                     <Loading :top="200" type="1" style="text-align:center" v-show="dataLoading"></Loading>
                 </div>
             </div>
@@ -129,13 +129,11 @@ export default {
                 }
             ],
             tableColumn: [],
-
             quCount: [],
             paperInfo: {},
             students: [],
-            privClassList: undefined,
+            privStuList: undefined,
             routerScope: ''
-
         }
     },
     methods: {
@@ -210,6 +208,7 @@ export default {
             let paperInfo = this.examInfo.papers.find((item) => {
                 return item.subjectId == this.chooseSubject;
             })
+            console.log('试卷数据', paperInfo)
             this.paperInfo = this._.cloneDeep(paperInfo)
             this.getClassStudent()
         },
@@ -261,11 +260,11 @@ export default {
             let requestData = {
                 ids: [this.chooseClass],
                 scope: this.examInfo.scope == 'private' ? 'private' : 'school',
-                school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                // school_code: this.examInfo.scope == 'private' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode,
+                school_code: this.$store.state.userInfo.schoolCode
             };
             this.$api.schoolSetting.getClassroomStudent(requestData).then((res) => {
                 if (!res.error) {
-                    console.log('paper', this.paperInfo)
                     if (!this.paperInfo[this.chooseClass]) {
                         this.paperInfo[this.chooseClass] = {}
                     }
@@ -372,8 +371,8 @@ export default {
                 let studentAns = this.paperInfo[this.chooseClass]["studentAns"]
                 this.studentScore = []
                 this.tableColumn = [...this.scoreList]
-                // this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
-                this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0
+                this.quCount = studentAns.studentScores[0] ? studentAns.studentScores[0].length : 0
+                // this.quCount = this.paperInfo.item ? this.paperInfo.item.length : 0 //不用试卷信息计算题目
                 for (let i = 0; i < this.quCount; i++) {
                     let data = {
                         title: "Q" + (i + 1),
@@ -477,7 +476,7 @@ export default {
     watch: {
         examInfo: {
             handler(n, o) {
-                this.privClassList = undefined
+                this.privStuList = undefined
                 if (n.subjects && n.subjects.length) {
                     this.chooseSubject = n.subjects[0].id;
                 }
@@ -485,9 +484,8 @@ export default {
                 if (n.grades && n.grades.length) {
                     this.chooseGrade = n.grades[0].id;
                 }
-                console.log('评测详细信息', n)
                 if (n.papers && n.papers.length) {
-                    if (n.scope == 'school') {
+                    if (n.code == 'Exam' + this.$store.state.userInfo.schoolCode) { //**现在不能通过scope判断是校本还是个人发布的评测
                         let res = n.papers.find((item) => {
                             return item.subjectId == this.chooseSubject;
                         });
@@ -535,30 +533,52 @@ export default {
     },
     computed: {
         classList() {
-            if (this.examInfo && this.examInfo.targetClassIds) {
+            if (this.examInfo && this.examInfo.classes) {
+                //发布对象为校本名单
                 if (this.examInfo.scope == 'school') {
                     this.showTest = false
                     let classes = this.schoolClassList.filter(item => {
-                        return this.examInfo.targetClassIds.indexOf(item.id) >= 0 && (item.gradeId == this.chooseGrade || !this.chooseGrade)
+                        return this.examInfo.classes.indexOf(item.id) >= 0 && (item.gradeId == this.chooseGrade || !this.chooseGrade)
                     })
                     return classes
-                } else {
-                    //根据targetClassIds查询班级信息
-                    if (!this.privClassList) {
-                        this.$api.schoolSetting.getClassByIds({
+                }
+                // 发布对象为个人创建的自定义名单
+                else {
+                    //根据classes查询班级信息
+                    if (!this.privStuList) {
+                        // this.$api.schoolSetting.getClassByIds({
+                        //     code: this.$store.state.userInfo.TEAMModelId,
+                        //     ids: this.examInfo.classes
+                        // }).then(
+                        //     res => {
+                        //         if (res.className && res.className.length) this.chooseClass = res.className[0].id
+                        //         this.privStuList = res.className
+                        //     },
+                        //     err => {
+                        //         console.log(err)
+                        //     }
+                        // )
+                        //查询当前老师所有stulist
+                        let params = {
                             code: this.$store.state.userInfo.TEAMModelId,
-                            ids: this.examInfo.targetClassIds
-                        }).then(
+                            scope: 'private'
+                        }
+                        this.$api.courseMgmt.findStulist(params).then(
                             res => {
-                                if (res.className && res.className.length) this.chooseClass = res.className[0].id
-                                this.privClassList = res.className
+                                this.privStuList = res.stuList
                             },
                             err => {
-                                console.log(err)
+                                this.$Message.error('API error')
                             }
                         )
+                        return this.privStuList
+                    } else {
+                        //过滤当前评测对象
+                        let list = this.privStuList.filter(item => {
+                            return this.examInfo.classes.indexOf(item.id) >= 0
+                        })
+                        return list
                     }
-                    return this.privClassList
                 }
             } else {
                 return []
@@ -590,7 +610,7 @@ export default {
 .scoring-main-wrap .ivu-table-fixed-body {
     background: #353535;
     // background: #2b2b2e;
-    max-height: 653px;
+    // max-height: 653px;
 }
 .scoring-main-wrap .ivu-table-tip {
     position: relative;

+ 2 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/SimpleAnalysis.vue

@@ -19,7 +19,7 @@
             </div>
             <!-- 班级数 -->
             <div class="count-box">
-                <span class="count-subject-num">{{examInfo.targetClassIds.length}}</span>
+                <span class="count-subject-num">{{examInfo.classes.length}}</span>
                 <span class="count-subject-text">
                     <Icon custom="iconfont icon-class-self" class="count-icon" />
                     {{$t('learnActivity.simple.classLabel')}}
@@ -115,7 +115,7 @@ export default {
             default: () => {
                 return {
                     subjects: [],
-                    targetClassIds: []
+                    classes: []
                 }
             },
             type: Object

+ 26 - 0
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.less

@@ -180,4 +180,30 @@
 .list-name-box{
     color: #a5a5a5;
     margin-bottom: -30px;
+}
+.priv-table-wrap{
+    width: 100%;
+    .table-header{
+        color: white;
+        height: 45px;
+        line-height: 45px;
+        padding-left: 15px;
+    }
+}
+.action-btn-wrap{
+    float: right;
+    color: white;
+    padding-right: 20px;
+}
+.cus-tips-wrap{
+    display: inline-block;
+    margin-left: 15px;
+}
+.no-class-tips{
+    color:#ed4014 ;
+    cursor: pointer;
+}
+.no-time-tips{
+    color:#ff9900 ;
+    cursor: pointer;
 }

+ 187 - 20
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="my-course-container dark-iview-split">
         <Loading v-if="listLoading" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
-        <Split v-model="split1">
+        <Split v-show="!isShowSchd" v-model="split1">
             <!--课程列表-->
             <div class="course-list" slot="left">
                 <!--列表内容-->
@@ -13,6 +13,7 @@
                                     <div style="margin-top:5px;">
                                         <Icon type="md-add" v-show="listType == 'private'" class="add-icon" :title="$t('cusMgt.addCus')" @click="addCusStatus = true" />
                                         <Icon type="md-create" v-show="(listType == 'school' && courseListS.length) || (listType == 'private' && courseListP.length) " class="add-icon" :title="$t('cusMgt.editCus')" @click="editCus()" />
+                                        <Icon custom="iconfont icon-schedule" v-show="listType == 'school' && courseListS.length" class="add-icon" title="课表模式" @click="showSchedule" />
                                         <Icon type="md-trash" v-show="listType == 'private'" class="add-icon" :title="$t('cusMgt.delCus')" @click="delCourse" />
                                     </div>
                                 </transition>
@@ -59,7 +60,7 @@
                     <div class="course-classroom-list" slot="left">
                         <div class="course-classroom-list-header">
                             <span class="course-classroom-label">{{$t('courseManage.classroom.classroomList')}}</span>
-                            <Icon custom="iconfont icon-schedule" v-show="listType == 'school'" class="add-icon" size="16" title="课表模式" />
+                            <!-- <Icon custom="iconfont icon-schedule" v-show="listType == 'school'" class="add-icon" size="16" title="课表模式" /> -->
                             <Icon type="md-add" v-show="listType == 'private'" class="add-icon" @click="newSlStatus = true" />
                             <!-- 暂未处理编辑个人自定义名单 -->
                             <!-- <Icon type="md-create" v-show="listType == 'private' && teaClassList.length" class="add-icon" @click="editClassStatus = true" /> -->
@@ -68,17 +69,18 @@
                         <div class="course-classroom-list-content">
                             <vuescroll>
                                 <div v-for="(item,index) in teaClassList" :key="index" @click="changeClassroom(index)" :class="['block-bg','tea-class-item',curClassIndex == index ? 'block-bg-active':'']">
-                                    <p class="class-attr-item">
+                                    <p class="class-attr-item" v-show="listType == 'school'">
                                         <span class="attr-label">教室:</span>
                                         <span class="class-name">{{item.classId ? item.classInfo.name:'未设置'}}</span>
-                                        <!-- <span class="class-label" :style="{color:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900',borderColor:item.type == '专科教室' ? '#2db7f5' : item.type == '普通教室' ? '#19be6b' : '#ff9900'}">
-                                                    {{item.type}}
-                                                </span> -->
                                     </p>
                                     <p class="class-attr-item">
                                         <span class="attr-label">名单:</span>
                                         <span :class="item.stulist ? 'class-name':'def-class-name'">{{item.stulist ? item.listName : '默认名单'}}</span>
                                     </p>
+                                    <p class="class-attr-item" v-show="listType == 'private'">
+                                        <span class="attr-label">学生数:</span>
+                                        <span class="class-name">{{item.students ? item.students.length : 0}}人</span>
+                                    </p>
                                 </div>
                                 <EmptyData v-if="teaClassList.length == 0" :top="160" textContent="暂无上课名单"></EmptyData>
                             </vuescroll>
@@ -210,6 +212,42 @@
                 </Split>
             </div>
         </Split>
+        <div v-show="isShowSchd" class="priv-table-wrap">
+            <vuescroll>
+                <div class="table-header dark-iview-select">
+                    <span v-show="cusPd.length  >  1">学段:</span>
+                    <Select v-model="curPd" style="width:200px" v-show="cusPd.length  >  1">
+                        <Option v-for="item in cusPd" :value="item.id" :key="item.id">{{ item.name }}</Option>
+                    </Select>
+                    <div class="cus-tips-wrap">
+                        <Tooltip v-show="noClassCus.length">
+                            <div slot="content">
+                                <p v-for="(item,index) in noClassCus" :key="index">
+                                    {{`${index+1}.${item.name}`}}
+                                </p>
+                            </div>
+                            <span class="no-class-tips">课程未安排教室:{{`${noClassCus.length}/${schdData.length}`}}</span>
+                        </Tooltip>
+                        <Tooltip v-show="noTimeCus.length" style="margin-left:15px;">
+                            <div slot="content">
+                                <p v-for="(item,index) in noTimeCus" :key="index">
+                                    {{`${index+1}.${item.name}`}}
+                                </p>
+                            </div>
+                            <span class="no-time-tips">课程未设时间:{{`${noTimeCus.length}/${schdData.length}`}}</span>
+                        </Tooltip>
+                    </div>
+                    <div class="action-btn-wrap">
+                        <span @click="isShowSchd = !isShowSchd">
+                            <Icon type="md-list" />
+                            列表模式
+                        </span>
+                    </div>
+
+                </div>
+                <TeaTable :schedData="schdData" :teacher="$store.state.userInfo.TEAMModelId" :periodId="curPd" mode="view"></TeaTable>
+            </vuescroll>
+        </div>
         <Drawer :title="$t('cusMgt.cusInfo')" class-name="dark-iview-drawer" width="450" :closable="false" v-model="showCusInfo" @on-close="baseEditStatus = true">
             <!--基础信息-->
             <div class="course-base-info-content dark-iview-form disabled-iview-select dark-wang-editor">
@@ -273,9 +311,10 @@ import QRCode from 'qrcodejs2'
 import PersonalPhoto from '@/components/public/personalPhoto/Index.vue'
 import E from '@/utils/wangEditor.js'
 import StudentList from '@/components/coursemgt/StudentList.vue'
+import TeaTable from './TeaTable.vue'
 export default {
     components: {
-        StudentList, PersonalPhoto
+        StudentList, PersonalPhoto, TeaTable
     },
     data() {
         // 验证只能是字母和数字
@@ -291,6 +330,11 @@ export default {
             }
         }
         return {
+            curPd: '',
+            isShowSchd: false,
+            schoolBase: {
+                period: []
+            },
             split1: 0.2,
             split2: 0.2,
             acTypeList: [
@@ -424,6 +468,80 @@ export default {
         }
     },
     methods: {
+        //显示课表模式
+        showSchedule() {
+            let promises = []
+            this.listLoading = true
+            this.isShowSchd = !this.isShowSchd
+            this.courseListS.forEach(item => {
+                let requestData = {
+                    'code': this.$store.state.userInfo.schoolCode,
+                    'scope': 'school',
+                    'id': item.id
+                }
+                promises.push(this.$api.courseMgmt.findCusInfo(requestData))
+            })
+            Promise.all(promises).then(
+                resAll => {
+                    resAll.forEach(async (res, index) => {
+                        if (res.courses && res.courses.length > 0) {
+                            res.courses[0].schedule = res.courses[0].schedule ? res.courses[0].schedule : []
+                            //过滤当前教师的schedule
+                            res.courses[0].schedule = res.courses[0].schedule.filter(item => {
+                                return item.teacherId == this.$store.state.userInfo.TEAMModelId
+                            })
+                            console.log(res.courses[0].schedule)
+                            // 获取自定义名单信息
+                            let ids = res.courses[0].schedule.map(item => {
+                                return item.stulist
+                            })
+                            for (let i = 0; i < ids.length; i++) {
+                                if (!ids[i]) {
+                                    ids.splice(i, 1)
+                                    i--
+                                }
+                            }
+                            if (ids.length) {
+                                try {
+                                    let listRes = await this.getListInfo([...ids])
+                                    if (listRes) this.stuList.push(...listRes.stuList)
+                                } catch (e) {
+                                    this.$Message.error('获取自定义名单失败')
+                                }
+                            }
+
+                            res.courses[0].schedule.forEach(item => {
+                                //补充教室信息
+                                if (item.classId) {
+                                    let classInfo = this.classList.find(classItem => {
+                                        return classItem.id == item.classId
+                                    })
+                                    item.classInfo = {
+                                        id: item.classId,
+                                        name: classInfo ? classInfo.name : '--'
+                                    }
+                                }
+                                //补充名单信息
+                                if (ids.length && item.stulist) {
+                                    let listInfo = this.stuList.find(listItem => {
+                                        return listItem.id == item.stulist
+                                    })
+                                    item.listName = listInfo ? listInfo.name : '未找到对应名单'
+                                    item.students = listInfo ? listInfo.students : []
+                                    item.fullStu = false
+                                }
+                            })
+                        }
+                        this.$set(this.courseListS, index, res.courses[0])
+                    })
+                },
+                err => {
+                    this.$Message.error('API ERROR')
+                }
+            ).finally(() => {
+                this.listLoading = false
+            })
+        },
         //获取学生名单
         getStuList() {
             this.tabName = 'stus'
@@ -712,7 +830,7 @@ export default {
                     let index = _this.curClassIndex
                     _this.curClassIndex = 0
                     _this.courseListShow[_this.curCusIndex].schedule.splice(index, 1)
-                   _this.updCusInfo()
+                    _this.updCusInfo()
                 }
             })
         },
@@ -732,7 +850,7 @@ export default {
                 this.baseEditStatus = !this.baseEditStatus
             }
         },
-        
+
         //初始化富文本编辑器
         initEditor() {
             if (!this.noticeEditor) {
@@ -829,13 +947,9 @@ export default {
                         notice: '',
                         listName: this.listName,
                         stulist: stuList.id,
-                        // teacher: {
-                        //     id: this.$store.state.userInfo.TEAMModelId,
-                        //     name: this.$store.state.userInfo.name
-                        // },
                         teacherId: this.$store.state.userInfo.TEAMModelId,
                         teacherName: this.$store.state.userInfo.name,
-                        time:[]
+                        time: []
                     })
                     this.updCusInfo()
                 },
@@ -959,7 +1073,7 @@ export default {
                 }
             ).catch(() => {
                 this.$Message.error('更新失败')
-            }).finally(()=>{
+            }).finally(() => {
                 this.listLoading = false
             })
         },
@@ -1013,6 +1127,11 @@ export default {
                     if (!res.error) {
                         if (res.courses && res.courses.length > 0) {
                             res.courses[0].schedule = res.courses[0].schedule ? res.courses[0].schedule : []
+                            //过滤当前教师的schedule
+                            res.courses[0].schedule = res.courses[0].schedule.filter(item => {
+                                return item.teacherId == this.$store.state.userInfo.TEAMModelId
+                            })
+                            console.log(res.courses[0].schedule)
                             // 获取自定义名单信息
                             let ids = res.courses[0].schedule.map(item => {
                                 return item.stulist
@@ -1062,7 +1181,7 @@ export default {
                         this.changeClassroom(0)
                     }
                 }
-            ).finally(()=>{
+            ).finally(() => {
                 this.listLoading = false
             })
         },
@@ -1080,6 +1199,7 @@ export default {
         //直接读取登录成功拿到得学校基础信息
         this.$store.dispatch('user/getSchoolProfile').then(res => {
             this.classList = res.school_classes
+            this.schoolBase = res.school_base
             this.getCourseList()
         })
 
@@ -1089,6 +1209,53 @@ export default {
         })
     },
     computed: {
+        //课程学段
+        cusPd() {
+            let pds = this.courseListS.map(item => {
+                return item.period
+            })
+            let res = []
+            pds.forEach(item => {
+                let r = res.find(resItem => {
+                    return item.id == resItem.id
+                })
+                if (!r) {
+                    res.push(item)
+                }
+            })
+            if (res.length) {
+                this.curPd = res[0].id
+            }
+            return res
+        },
+        //课程表当前显示的课程
+        schdData() {
+            let pdCus = []
+            pdCus = this.courseListS.filter(item => {
+                return item.period.id == this.curPd && item.schedule
+            })
+            console.log(pdCus)
+            return pdCus
+        },
+        //无教室课程
+        noClassCus() {
+            console.log(this.schdData)
+            return this.schdData.filter(item => {
+                let res = item.schedule.find(schdItem => {
+                    return schdItem.classId && schdItem.teacherId == this.$store.state.userInfo.TEAMModelId
+                })
+                return !res
+            })
+        },
+        //无时段课程
+        noTimeCus() {
+            return this.schdData.filter(item => {
+                let res = item.schedule.find(schdItem => {
+                    return (schdItem.time && schdItem.time.length) && schdItem.teacherId == this.$store.state.userInfo.TEAMModelId
+                })
+                return !res
+            })
+        },
         //是否为默认名单
         isDefList() {
             if (this.teaClassList[this.curClassIndex] && this.teaClassList[this.curClassIndex].stulist) {
@@ -1116,16 +1283,16 @@ export default {
             }
         },
         //当前班级活动列表
-        acList(){
+        acList() {
             let list = []
             let id = this.teaClassList[this.curClassIndex] ? this.teaClassList[this.curClassIndex].stulist || this.teaClassList[this.curClassIndex].classId : ''
-            if(!id){
+            if (!id) {
                 return []
             }
             switch (this.curAcType) {
                 case 'ev':
-                    list = this.evList.filter(item=>{
-                        return item.targetClassIds.indexOf(id) > -1
+                    list = this.evList.filter(item => {
+                        return item.classes.indexOf(id) > -1
                     })
                     break
                 case 'vote':

+ 5 - 1
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.less

@@ -253,9 +253,13 @@
     position: sticky;
     top: 0px;
     background: #303030;
-    z-index: 9999;
+    z-index: 99;
     .add-list-label{
         color: #a5a5a5;
         margin-right: 5px;
     }
+}
+.list-name-box{
+    color: #a5a5a5;
+    margin-bottom: -30px;
 }

+ 433 - 91
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue

@@ -1,5 +1,6 @@
 <template>
     <div class="manage-course-container dark-iview-split">
+        <Loading v-if="listLoading" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
         <!-- 头部 -->
         <div class="mgt-course-header">
             <Dropdown class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ filterPeriod = e }" @on-visible-change="dropdownStates" v-if="$store.state.user.schoolProfile.school_base">
@@ -25,7 +26,6 @@
                     <Icon type="ios-people" size="16" />
                     <span>自定义名单</span>
                 </span>
-
             </div>
         </div>
         <Split v-model="split1">
@@ -61,13 +61,12 @@
                 </div>
             </div>
             <div slot="right" class="cus-schd-box">
-
                 <Split v-model="split2">
                     <!-- 授课教师列表 -->
                     <div slot="left" class="teacher-list">
                         <div class="teacher-list-header">
                             <span>教师</span>
-                            <Icon type="md-add" size="16" class="tea-action-icon" @click="addTeaStatus = true" />
+                            <Icon type="md-add" size="16" class="tea-action-icon" @click="toggleAddTea" />
                             <Icon type="md-trash" size="16" class="tea-action-icon" @click="removeTeacher" />
                         </div>
                         <div class="tea-list-content">
@@ -105,10 +104,6 @@
                                     <Icon type="md-trash" size="16" />
                                     <span>移除名单</span>
                                 </span>
-                                <!-- <span v-show="curTab == 1">授课教室:</span>
-                                <Select v-show="curTab == 1" v-model="setCurClass" style="width:200px;margin-right:30px" size="small">
-                                    <Option v-for="(item,index) in schdClassList" :value="item.classId" :key="index">{{ item.classInfo.name }}</Option>
-                                </Select> -->
                             </div>
                         </div>
                         <!-- 教师上课时段设置 -->
@@ -149,7 +144,7 @@
                                             <Select ref="sltStuList" v-show="!isDefault" clearable v-model="schdList[curClassIndex].stulist" style="width:200px;margin-right:5px" size="small">
                                                 <Option v-for="(item,index) in stuList" :value="item.id" :key="index" @click.native="updateStuList(item.name)">{{ item.name }}</Option>
                                             </Select>
-                                            <Icon type="md-add-circle" v-show="!isDefault" style="cursor:pointer" @click="goMgtStuList" />
+                                            <Icon type="md-add-circle" v-show="!isDefault" style="cursor:pointer" @click="addStuListStatus = true" />
                                         </div>
                                         <Table v-if="schdList[curClassIndex]" :columns="schdList[curClassIndex].stulist ? listColumn : classColumn" :data="students" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
                                             <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
@@ -178,7 +173,7 @@
                             </div>
                             <!-- 教师课表 -->
                             <vuescroll v-show="curTab == 1">
-                                <TeaTable v-if="hasTimeTable" :teaClassList="schdClassList" :teacher="teaList[curTeaIndex] ? teaList[curTeaIndex].id : ''" :periodId="filterPeriod" :schedData="[courseListShow[this.curCusIndex]]" @selectCell="selectCell" @cancelCell="cancelCell"></TeaTable>
+                                <TeaTable style="height: calc(100% - 45px)" :courseId="courseId" v-if="hasTimeTable" :teaClassList="schdClassList" :teacher="teaList[curTeaIndex] ? teaList[curTeaIndex].id : ''" :periodId="filterPeriod" :schedData="schdData" @selectCell="selectCell" @cancelCell="cancelCell"></TeaTable>
                                 <div v-else>
                                     <p class="no-time-table-tips">
                                         {{filterPeriodName}}暂未设置时段,请先
@@ -189,66 +184,43 @@
                             </vuescroll>
                         </div>
                     </div>
-                    <!-- 添加名单UI -->
-                    <div slot="right" class="class-setting dark-el-cascader dark-iview-select dark-iview-table" v-show="isAddStuList">
-                        <div class="add-list-header">
-                            <!-- <span class="add-list-label">教师:</span>
-                            <Select ref="sltStuList" clearable label-in-value v-model="schedule.teacherId" style="width:200px;margin-right:30px" size="small" @on-change="setTeaName">
-                                <Option v-for="(item,index) in $store.state.teachers.teacherList" :value="item.id" :key="index">{{ item.name }}</Option>
-                            </Select> -->
-                            <span class="add-list-label">教室:</span>
-                            <el-cascader size="small" placeholder="请设置上课教室" :show-all-levels="false" clearable v-model="schedule.classId" :options="csOptions" :props="props" @change="setClassName($event,'insert')" style="width:180px;">
-                            </el-cascader>
-                            <span v-show="schedule.classId" class="attr-label" style="margin-left:20px">默认名单</span>
-                            <Tooltip v-show="schedule.classId" content="默认名单为教室对应的名单,否则需要指定自定义名单。" max-width="200">
-                                <Icon type="ios-information-circle-outline" style="margin-left:2px;margin-right:5px" />
-                            </Tooltip>
-                            <span v-show="schedule.classId">
-                                <i-switch v-model="preDefault" size="small" />
-                            </span>
-                            <span class="add-list-label" v-show="!preDefault || !schedule.classId" style="margin-left:40px">名单:</span>
-                            <Select ref="sltStuList" v-show="!preDefault || !schedule.classId" clearable v-model="schedule.stulist" style="width:200px;margin-right:5px" size="small">
-                                <Option v-for="(item,index) in stuList" :value="item.id" :key="index" @click.native="getStuList(item.name)">{{ item.name }}</Option>
-                            </Select>
-                            <Icon type="md-add-circle" v-show="!preDefault || !schedule.classId" class="create-list-icon" @click="goMgtStuList" />
-                            <div class="action-btn-wrap">
-                                <span class="action-btn" style="margin-right:40px" @click="confirmAddSchd">
-                                    <Icon type="md-add" size="16" />
-                                    <span>确认添加</span>
-                                </span>
-                                <span class="action-btn" @click="cancelAddSchd">
-                                    <Icon type="md-close" size="16" />
-                                    <span>取消添加</span>
-                                </span>
-                            </div>
-                        </div>
-                        <Table :columns="schedule.stulist ? listColumn : classColumn" :data="preStus" class="stu-list-table" :loading="stuLoading" no-data-text="暂无学生">
-                            <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
-                            <template slot-scope="{ row }" slot="picture">
-                                <PersonalPhoto :name="row.name" :picture="row.picture" />
-                            </template>
-                            <template slot-scope="{ row,index }" slot="no">
-                                <span>{{row.no}}</span>
-                            </template>
-                            <template slot-scope="{ row ,index}" slot="action">
-                                <div class="item-tools" v-if="$access.can('admin.*|student-upd')">
-                                    <Icon type="md-create" size="18" color="white" @click="resetNo(index)" :title="$t('schoolBaseInfo.editSeat')" />
-                                    <Icon type="md-remove-circle" size="18" color="white" style="margin-left:10px" @click="removeStudent(index)" :title="$t('schoolBaseInfo.delStuBtn')" />
+                    <!-- 添加名单UI 批量添加-->
+                    <div slot="right" class="class-setting dark-iview-input dark-iview-select dark-iview-table" v-show="isAddStuList">
+                        <vuescroll>
+                            <div class="add-tea-header">
+                                <RadioGroup v-model="addType" type="button" button-style="solid" size="small">
+                                    <Radio label="class">校本名单</Radio>
+                                    <Radio label="stulist">自定义名单</Radio>
+                                </RadioGroup>
+                                <!-- <Input search placeholder="搜索" style="width:240px;margin-top:0px;margin-left:15px;" size="small" /> -->
+                                <div class="action-btn-wrap">
+                                    <span class="action-btn" style="margin-right:40px" @click="confirmAddSchd">
+                                        <Icon type="md-add" size="16" />
+                                        <span>确认添加</span>
+                                    </span>
+                                    <span class="action-btn" @click="cancelAddSchd">
+                                        <Icon type="md-close" size="16" />
+                                        <span>取消添加</span>
+                                    </span>
                                 </div>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupId">
-                                <span>{{row.groupId ? row.groupId : '- -'}}</span>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="groupName">
-                                <span>{{row.groupName ? row.groupName : '未分组'}}</span>
-                            </template>
-                        </Table>
+                            </div>
+                            <Table ref="sltClass" v-show="addType == 'class'" :columns="classroomCol" :data="calssTable" style="margin-top:10px" @on-selection-change="(selection)=>{sltClass = selection}">
+                                <template slot-scope="{ row }" slot="grade">
+                                    <span>{{$jsFn.getGradeName(schoolBase,row.gradeId)}}</span>
+                                </template>
+                            </Table>
+                            <Table ref="sltList" v-show="addType == 'stulist'" :columns="listCol" :data="stuList" style="margin-top:10px" @on-selection-change="(selection)=>{sltList = selection}">
+                                <template slot-scope="{ row }" slot="count">
+                                    <span>{{row.students.length}}</span>
+                                </template>
+                            </Table>
+                        </vuescroll>
                     </div>
                     <!-- 添加授课教师UI -->
                     <div slot="right" class="class-setting dark-iview-input dark-iview-table" v-show="addTeaStatus">
                         <vuescroll>
                             <div class="add-tea-header">
-                                <Input search placeholder="" style="width:240px;margin-top:4px" size="small" />
+                                <Input search placeholder="搜索" style="width:240px;margin-top:4px" size="small" />
                                 <div class="action-btn-wrap">
                                     <span class="action-btn" style="margin-right:40px" @click="confirmAddTea">
                                         <Icon type="md-add" size="16" />
@@ -260,7 +232,7 @@
                                     </span>
                                 </div>
                             </div>
-                            <Table :columns="teaCol" :data="teacherList" style="margin-top:10px" @on-selection-change="(selection)=>{sltTeachers = selection}">
+                            <Table ref="sltTea" :columns="teaCol" :data="teacherList" style="margin-top:10px" @on-selection-change="(selection)=>{sltTeachers = selection}">
                                 <template slot-scope="{ row }" slot="picture">
                                     <PersonalPhoto :name="row.name" :picture="row.picture" />
                                 </template>
@@ -298,12 +270,14 @@
                 </FormItem>
             </Form>
         </Modal>
-        <!-- 添加授课教师 -->
-        <!-- <Modal v-model="addTeaStatus" title="添加教师" class-name="dark-iview-modal dark-iview-select" @on-ok="confirmAddTea">
-            <Select ref="addTea" label-in-value multiple clearable :placeholder="$t('cusMgt.teacherHolder')" :max-tag-count="3" filterable @on-change="seltChange">
-                <Option v-for="(item,index) in $store.state.teachers.teacherList" :value="item.id" :key="index">{{ item.name }}</Option>
-            </Select>
-        </Modal> -->
+        <!-- 创建名单stulist -->
+        <Modal v-model="addStuListStatus" title="创建自定义名单" width="1200" @on-ok="confirmAddStuList" class-name="dark-iview-modal" :loading="modalLoading">
+            <div class="dark-iview-input list-name-box">
+                <span>名称:</span>
+                <Input v-model="listName" placeholder="请输入名单名称..." style="width: 300px" />
+            </div>
+            <StudentList @getSelectInfo="(selction)=>{listSelections = selction}"></StudentList>
+        </Modal>
         <!-- 时段设置 -->
         <Drawer title="时段设置" class-name="dark-iview-drawer" :closable="false" v-model="showTime" :width="450">
             <TimeSetting :periodId="filterPeriod"></TimeSetting>
@@ -333,6 +307,13 @@ export default {
             }
         }
         return {
+            listLoading: false,
+            classList: [],
+            addType: 'class',
+            listName: '',
+            addStuListStatus: false,
+            modalLoading: false,
+            listSelections: [],
             isUpd: false,
             props: {
                 value: 'id',
@@ -351,6 +332,8 @@ export default {
             isDefault: true,
             teacherList: [],
             sltTeachers: [],
+            sltClass: [],
+            sltList: [],
             teaCol: [
                 {
                     type: 'selection',
@@ -379,6 +362,40 @@ export default {
                     align: 'center '
                 }
             ],
+            listCol: [
+                {
+                    type: 'selection',
+                    width: 60,
+                    align: 'center'
+                },
+                {
+                    title: '名称',
+                    key: 'name',
+                    align: 'center '
+                },
+                {
+                    title: '学生人数',
+                    slot: 'count',
+                    align: 'center '
+                }
+            ],
+            classroomCol: [
+                {
+                    type: 'selection',
+                    width: 60,
+                    align: 'center'
+                },
+                {
+                    title: '名称',
+                    key: 'name',
+                    align: 'center '
+                },
+                {
+                    title: '编码',
+                    key: 'no',
+                    align: 'center '
+                }
+            ],
             classColumn: [
                 {
                     title: ' ',
@@ -494,25 +511,176 @@ export default {
                     id: '',
                     name: ''
                 },
-                teacherId:'',
-                teacherName:'',
+                teacherId: '',
+                teacherName: '',
                 stulist: '',
                 time: [],
                 notice: ''
-            }
+            },
+            teaSchds: {}
         }
     },
     methods: {
+        //查询教师课表数据
+        async getTeaSchd() {
+            let teaId = this.teaList[this.curTeaIndex].id
+            try {
+                let cusList = await this.getTeaCourse(teaId)
+                let cusSchd = await this.getTeaDetail(cusList)
+                this.$set(this.teaSchds, teaId, [])
+                console.log(cusSchd)
+                cusSchd.forEach(item => {
+                    this.teaSchds[teaId].push(...item.courses)
+                })
+                console.log('hehe', this.teaSchds)
+            } catch (e) {
+                console.log(e)
+                this.$Message.error('API ERROR!')
+            }
+        },
+        //获取教师所有课程列表
+        getTeaCourse(teaId) {
+            return new Promise((r, j) => {
+                let requestData = {
+                    'code': teaId,
+                    'schoolId': this.$store.state.userInfo.schoolCode,
+                    'scope': 'private'
+                }
+                this.$api.courseMgmt.findCourse(requestData).then(
+                    (res) => {
+                        if (res.error == null) {
+                            let schoolCus = res.courses.filter(item => {
+                                return item.scope == 'school'
+                            })
+                            r(schoolCus)
+                        } else {
+                            j(res.error)
+                        }
+                    },
+                    (err) => {
+                        j(res.error)
+                    }
+                )
+            })
+        },
+        //获取教师所有课程详细信息
+        getTeaDetail(cusList) {
+            return new Promise((r, j) => {
+                let promises = []
+                cusList.forEach(item => {
+                    let requestData = {
+                        'code': this.$store.state.userInfo.schoolCode,
+                        'scope': 'school',
+                        'id': item.id
+                    }
+                    promises.push(this.$api.courseMgmt.findCusInfo(requestData))
+                })
+                Promise.all(promises).then(
+                    resAll => {
+                        resAll.forEach(async (res, index) => {
+                            if (res.courses && res.courses.length > 0) {
+                                res.courses[0].schedule = res.courses[0].schedule ? res.courses[0].schedule : []
+                                //过滤当前教师的schedule
+                                let teaId = this.teaList[this.curTeaIndex].id
+                                res.courses[0].schedule = res.courses[0].schedule.filter(item => {
+                                    return item.teacherId == teaId
+                                })
+                                res.courses[0].schedule.forEach(item => {
+                                    //补充教室信息
+                                    if (item.classId) {
+                                        let classInfo = this.classList.find(classItem => {
+                                            return classItem.id == item.classId
+                                        })
+                                        item.classInfo = {
+                                            id: item.classId,
+                                            name: classInfo ? classInfo.name : '--'
+                                        }
+                                    }
+                                })
+                            }
+                        })
+                        r(resAll)
+                    },
+                    err => {
+                        j(err)
+                    }
+                )
+            })
+
+        },
+        toggleAddTea() {
+            this.initStatus()
+            this.addTeaStatus = true
+        },
+        initStatus() {
+            this.isAddStuList = false
+            this.addTeaStatus = false
+        },
+        confirmAddStuList() {
+            if (!this.listName) {
+                this.$Message.warning('请输入名单名称')
+                this.modalLoading = false
+                setTimeout(() => {
+                    this.modalLoading = true
+                }, 0)
+            } else {
+                let stuList = {
+                    name: this.listName,
+                    id: this.$tools.guid(),
+                    code: this.$store.state.userInfo.schoolCode,
+                    students: this.listSelections.map(item => { //这里没有学生名字, 需要先查看id集合再查学生信息?
+                        return {
+                            id: item.id,
+                            code: item.code //学生所在学校的编码,这里先传当前学校编码,暂无未考虑跨校名单
+                        }
+                    }),
+                    tmids: [],
+                    course: null
+                }
+                this.saveStuList(stuList)
+            }
+        },
+        // 保存名单
+        saveStuList(stuList) {
+            let params = {
+                stuList,
+                scope: "school"
+            }
+            this.$api.courseMgmt.upsertStulist(params).then(
+                res => {
+                    this.$Message.success('添加成功')
+                    this.addStuStatus = false
+                    this.stuList.unshift(params.stuList)
+                    this.listName = ''
+                },
+                err => {
+                    this.modalLoading = false
+                    setTimeout(() => {
+                        this.modalLoading = true
+                    }, 0)
+                }
+            )
+        },
+        clearTable() {
+            this.$refs.sltTea.selectAll(false)
+            this.$refs.sltList.selectAll(false)
+            this.$refs.sltClass.selectAll(false)
+        },
         selectCus(index) {
             this.selectClass(0)
             this.selectTea(0)
             this.cancelAddTea()
             this.cancelAddSchd()
             this.curCusIndex = index
+
         },
         selectTab(index) {
             this.curTab = index
             this.setDefClass()
+            let teaId = this.teaList[this.curTeaIndex].id
+            if (index == 1 && teaId && !this.teaSchds[teaId]) {
+                this.getTeaSchd()
+            }
         },
         //设置默认授课教室
         setDefClass() {
@@ -546,6 +714,25 @@ export default {
                 })
                 this.isUpd = true
             }
+            //更新课程表数据
+            if (this.teaList[this.curTeaIndex] && this.teaSchds[this.teaList[this.curTeaIndex].id]) {
+                let tableData = this.teaSchds[this.teaList[this.curTeaIndex].id].find(item => {
+                    return item.id == this.courseListShow[this.curCusIndex].id
+                })
+                if (tableData) {
+                    let s = tableData.schedule.find(item => {
+                        return item.classId == data.setClass && item.teacherId == this.teaList[this.curTeaIndex].id
+                    })
+                    if (s) {
+                        s.time.push({
+                            week: data.col,
+                            id: data.row.id
+                        })
+                    }
+                }else{
+                    this.teaSchds[this.teaList[this.curTeaIndex].id].push(this._.cloneDeep(this.courseListShow[this.curCusIndex]))
+                }
+            }
         },
         //取消课程时段设置
         cancelCell(data) {
@@ -561,6 +748,25 @@ export default {
                     }
                 }
             }
+            //更新课程表数据
+            if (this.teaList[this.curTeaIndex] && this.teaSchds[this.teaList[this.curTeaIndex].id]) {
+                let tableData = this.teaSchds[this.teaList[this.curTeaIndex].id].find(item => {
+                    return item.id == this.courseListShow[this.curCusIndex].id
+                })
+                if (tableData) {
+                    let s = tableData.schedule.find(item => {
+                        return item.classId == data.setClass && item.teacherId == this.teaList[this.curTeaIndex].id
+                    })
+                    if (s) {
+                        for (let index in s.time) {
+                            if (s.time[index].week == data.col && s.time[index].id == data.row.id) {
+                                s.time.splice(index, 1)
+                                break
+                            }
+                        }
+                    }
+                }
+            }
         },
         //修改上课名单
         updateStuList(listName) {
@@ -598,6 +804,7 @@ export default {
         selectClass(index) {
             this.curClassIndex = index
             this.setIsDefault()
+            this.initStatus()
         },
         //教师列表选择事件
         selectTea(index) {
@@ -605,6 +812,12 @@ export default {
             this.curTeaIndex = index
             this.setIsDefault()
             this.setDefClass()
+            this.initStatus()
+            //获取老师所有授课数据渲染课程表
+            let teaId = this.teaList[this.curTeaIndex].id
+            if (this.curTab == 1 && teaId && !this.teaSchds[teaId]) {
+                this.getTeaSchd()
+            }
         },
         /**
          * 添加名单的时候获取名单对应的学生信息
@@ -701,25 +914,60 @@ export default {
                 this.$Message.warning('请设置授课老师')
                 return
             }
-            if (!(this.schedule.classId || this.schedule.stulist)) {
-                this.$Message.warning('请设置教室或者名单')
+            if (this.addType == 'class' && this.sltClass.length > 0) {
+                //先判断是否有空的schedule(只是添加了老师,没有教室和名单)
+                this.courseListShow[this.curCusIndex].schedule.forEach((item, index) => {
+                    if (item.teacherId == this.schedule.teacherId && !item.stulist && !item.classId) {
+                        this.courseListShow[this.curCusIndex].schedule.splice(index, 1)
+                    }
+                })
+                this.sltClass.forEach(item => {
+                    let exist = this.courseListShow[this.curCusIndex].schedule.find(schdItem => {
+                        return schdItem.classId == item.id && schdItem.teacherId == this.schedule.teacherId
+                    })
+                    if (!exist) {
+                        this.schedule.classId = item.id
+                        this.schedule.classInfo = {
+                            id: item.id,
+                            name: item.name
+                        }
+                        this.courseListShow[this.curCusIndex].schedule.push(JSON.parse(JSON.stringify(this.schedule)))
+                    }
+                })
+                this.sltClass = []
+            } else if (this.addType == 'stulist' && this.sltList.length > 0) {
+                //先判断是否有空的schedule(只是添加了老师,没有教室和名单)
+                this.courseListShow[this.curCusIndex].schedule.forEach((item, index) => {
+                    if (item.teacherId == this.schedule.teacherId && !item.stulist && !item.classId) {
+                        this.courseListShow[this.curCusIndex].schedule.splice(index, 1)
+                    }
+                })
+
+                this.sltList.forEach(item => {
+                    let exist = this.courseListShow[this.curCusIndex].schedule.find(schdItem => {
+                        return schdItem.stulist == item.id && schdItem.teacherId == this.schedule.teacherId
+                    })
+                    if (!exist) {
+                        this.schedule.stulist = item.id
+                        this.schedule.listName = item.name
+                        this.courseListShow[this.curCusIndex].schedule.push(JSON.parse(JSON.stringify(this.schedule)))
+                    }
+                })
+                this.sltList = []
+            } else {
+                this.$Message.warning('请先选择名单或者教室')
                 return
             }
-            this.courseListShow[this.curCusIndex].schedule.forEach((item, index) => {
-                if (item.teacherId == this.schedule.teacherId && !item.stulist && !item.classId) {
-                    this.courseListShow[this.curCusIndex].schedule.splice(index, 1)
-                }
-            })
-            this.courseListShow[this.curCusIndex].schedule.push(this.schedule)
             this.isAddStuList = false
             this.updCusInfo()
             this.initSchedule()
-            // this.selectTea(0)
+            this.clearTable()
         },
         //取消添加Schd
         cancelAddSchd() {
             this.isAddStuList = false
             this.initSchedule()
+            this.clearTable()
         },
         //确认或取消添加后初始化数据
         initSchedule() {
@@ -728,8 +976,8 @@ export default {
                     id: '',
                     name: ''
                 },
-                teacherId:'',
-                teacherName:'',
+                teacherId: '',
+                teacherName: '',
                 stulist: '',
                 time: [],
                 notice: ''
@@ -738,6 +986,7 @@ export default {
         //取消添加老师
         cancelAddTea() {
             this.addTeaStatus = false
+            this.clearTable()
         },
         //确认添加教师
         confirmAddTea() {
@@ -760,6 +1009,7 @@ export default {
                 })
                 this.updCusInfo()
                 this.sltTeachers = []
+                this.clearTable()
             }
         },
         // 更新课程数据
@@ -782,13 +1032,26 @@ export default {
         removeStuList() {
             this.$Modal.confirm({
                 title: '移除名单',
-                content: `是否确认移除${this.schdList[this.curClassIndex].listName || this.schdList[this.curClassIndex].classInfo.name }?`,
+                content: `是否确认移除${this.schdList[this.curClassIndex].listName || this.schdList[this.curClassIndex].classInfo.name}?`,
                 onOk: () => {
-                    for (let i in this.courseListShow[this.curCusIndex].schedule) {
-                        let curSchd = this.schdList[this.curClassIndex]
-                        if (this.courseListShow[this.curCusIndex].schedule[i].classId == curSchd.classId && this.courseListShow[this.curCusIndex].schedule[i].stulist == curSchd.stulist) {
-                            this.courseListShow[this.curCusIndex].schedule.splice(i, 1)
-                            break
+                    //如果只有一个名单的时候移除名单则为清空名单,不能真的删除
+                    if (this.schdList.length == 1) {
+                        for (let i in this.courseListShow[this.curCusIndex].schedule) {
+                            let curSchd = this.schdList[this.curClassIndex]
+                            if (this.courseListShow[this.curCusIndex].schedule[i].classId == curSchd.classId && this.courseListShow[this.curCusIndex].schedule[i].stulist == curSchd.stulist) {
+                                this.courseListShow[this.curCusIndex].schedule[i].classId = ''
+                                this.courseListShow[this.curCusIndex].schedule[i].stulist = ''
+                                this.courseListShow[this.curCusIndex].schedule[i].time = []
+                                break
+                            }
+                        }
+                    } else {
+                        for (let i in this.courseListShow[this.curCusIndex].schedule) {
+                            let curSchd = this.schdList[this.curClassIndex]
+                            if (this.courseListShow[this.curCusIndex].schedule[i].classId == curSchd.classId && this.courseListShow[this.curCusIndex].schedule[i].stulist == curSchd.stulist) {
+                                this.courseListShow[this.curCusIndex].schedule.splice(i, 1)
+                                break
+                            }
                         }
                     }
                     this.updCusInfo()
@@ -816,9 +1079,12 @@ export default {
             })
         },
         goMgtStuList() {
+            //不用跳转页面进行操作
             this.$router.push({
                 name: 'MgtStuList'
             })
+            // 在当前页面添加stulist
+            // this.addStuListStatus = true
         },
         // 切换课表模式和课程模式
         toggleView() {
@@ -834,6 +1100,20 @@ export default {
             this.courseListShow = this.courseList.filter(item => {
                 return item.period.id == this.filterPeriod
             })
+
+            let curGd = this.schoolBase.period.find(item => {
+                return item.id == this.filterPeriod
+            })
+            if (curGd) {
+                let filters = curGd.grades.map(item => {
+                    return {
+                        label: item.name,
+                        value: item.id
+                    }
+                })
+                //年级筛选条件
+                this.classroomCol[this.classroomCol.length - 1].filters = filters
+            }
             this.getCusInfo()
         },
         //关键字搜索课程
@@ -845,6 +1125,7 @@ export default {
         //获取课程列表
         getCourseList() {
             this.tableLoading = true
+            this.listLoading = true
             let requestData = {
                 'code': this.$store.state.userInfo.schoolCode,
                 'scope': 'school'
@@ -867,12 +1148,14 @@ export default {
             ).finally(() => {
                 setTimeout(() => {
                     this.tableLoading = false
+                    this.listLoading = false
                 }, 500)
             })
         },
         //获取课程完整信息
         getCusInfo() {
             if (this.courseListShow[this.curCusIndex]) {
+                this.listLoading = true
                 let requestData = {
                     'code': this.$store.state.userInfo.schoolCode,
                     'scope': 'school',
@@ -920,6 +1203,7 @@ export default {
                 ).finally(() => {
                     setTimeout(() => {
                         this.tableLoading = false
+                        this.listLoading = false
                     }, 500)
                 })
             }
@@ -1149,6 +1433,24 @@ export default {
                     this.hasTimeTable = this.schoolBase.period[0].timetable ? true : false
                 }
                 this.classList = JSON.parse(JSON.stringify(this.$store.state.user.schoolProfile.school_classes))
+                let curGd = this.schoolBase.period[0].grades
+                let filters = curGd.map(item => {
+                    return {
+                        label: item.name,
+                        value: item.id
+                    }
+                })
+                //年级筛选条件
+                this.classroomCol.push({
+                    title: '年级',
+                    slot: 'grade',
+                    align: 'center ',
+                    filters: filters,
+                    filterMultiple: false,
+                    filterMethod(value, row) {
+                        return row.gradeId == value
+                    }
+                })
             },
             err => {
                 this.$Message.warning(this.$t('cusMgt.noSchool'))
@@ -1163,6 +1465,25 @@ export default {
         this.findStuList()
     },
     computed: {
+        //当前课程id
+        courseId() {
+            return this.courseListShow[this.curCusIndex] ? this.courseListShow[this.curCusIndex].id : ''
+        },
+        //课表数据
+        schdData() {
+            if (this.teaList[this.curTeaIndex]) {
+                return this.teaSchds[this.teaList[this.curTeaIndex].id] || []
+            }
+            return []
+        },
+        //选择教室名单列表
+        calssTable() {
+            let tbData = []
+            tbData = this.classList.filter(item => {
+                return item.periodId == this.filterPeriod
+            })
+            return tbData
+        },
         //级联选择年级班级
         csOptions() {
             let data = []
@@ -1254,10 +1575,31 @@ export default {
     background: #505050;
 }
 .class-setting .ivu-input {
-    border-radius: 16px;
+    /* border-radius: 16px; */
 }
 .add-list-header .el-input--small .el-input__inner {
     height: 26px;
     line-height: 26px;
 }
+.add-tea-header
+    .ivu-radio-group-button-solid
+    .ivu-radio-wrapper-checked:not(.ivu-radio-wrapper-disabled) {
+    background: white;
+    border-color: white;
+    color: #515a6e;
+}
+.add-tea-header .ivu-radio-group-button .ivu-radio-wrapper {
+    background: #606060;
+    color: white;
+    border-color: #606060;
+}
+.add-tea-header .ivu-radio-group-button .ivu-radio-wrapper-checked,
+.add-tea-header
+    .ivu-radio-group-button
+    .ivu-radio-wrapper-checked.ivu-radio-focus {
+    box-shadow: none;
+}
+.add-tea-header .ivu-radio-group-button .ivu-radio-wrapper:after {
+    height: 0px;
+}
 </style>

+ 22 - 2
TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.less

@@ -9,7 +9,8 @@
 
 .cus-table-container {
     width: 100%;
-    height: ~"calc(100% - 45px)";
+    // height: ~"calc(100% - 45px)";
+    height: 100%;
     padding: 15px 0px 15px 10px;
 }
 .sch-title {
@@ -52,7 +53,12 @@
     overflow:hidden; 
     white-space:nowrap; 
 }
-
+.course-color{
+    color: #ff9900;
+}
+.classroom-color{
+    color: #ff9900 !important;
+}
 .classroom-name {
     color: #a5a5a5;
     font-size: 14px;
@@ -77,4 +83,18 @@
         color:#1cc0f3;
     }
 
+}
+.am-pm{
+    padding:10px 0px 4px 0px;
+    font-size: 20px;
+    writing-mode: vertical-lr;
+    height:150px;
+    margin: auto;
+    letter-spacing: 4px;
+}
+.no-class-tips{
+    color: white;
+    text-align: center;
+    margin: 15px 0px;
+    font-size: 16px;
 }

+ 31 - 21
TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue

@@ -18,7 +18,7 @@
             <Table :columns="timeColumns" disabled-hover :data="timetable" border :span-method="handleSpan" style="width:calc(100% - 15px);margin-top:00px;">
                 <!--上午/下午-->
                 <template slot-scope="{ row, index }" slot="sub">
-                    <p style="padding:10px 0px 4px 0px;font-size: 20px;">
+                    <p class="am-pm" style="">
                         {{parseInt(row.time.substr(0,2)) > 12 ? '下午':'上午'}}
                     </p>
                 </template>
@@ -34,88 +34,89 @@
                 <!--星期一-->
                 <template slot-scope="{ row, column }" slot="MON">
                     <div :class="row.weeklies.MON.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <div class="toggle-status-btn-wrap">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'" v-if="!row.weeklies[column.slot].courseId || row.weeklies[column.slot].courseId == courseId || !courseId">
                             <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" title="设置课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" title="修改课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" title="取消课程" @click="cancelCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="setClass" type="md-copy" title="重复操作" @click="copyCell(row, column.slot)" />
                         </div>
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.MON.classroomCode">{{row.weeklies.MON.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.MON.classroomCode">{{row.weeklies.MON.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.MON.classroomCode">{{row.weeklies.MON.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.MON.classroomCode">{{row.weeklies.MON.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期二-->
                 <template slot-scope="{ row, column }" slot="TUE">
                     <div :class="row.weeklies.TUE.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <div class="toggle-status-btn-wrap">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'" v-if="!row.weeklies[column.slot].courseId || row.weeklies[column.slot].courseId == courseId || !courseId">
                             <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" title="设置课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" title="修改课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" title="取消课程" @click="cancelCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="setClass" type="md-copy" title="重复操作" @click="copyCell(row, column.slot)" />
                         </div>
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.TUE.classroomCode">{{row.weeklies.TUE.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.TUE.classroomCode">{{row.weeklies.TUE.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.TUE.classroomCode">{{row.weeklies.TUE.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.TUE.classroomCode">{{row.weeklies.TUE.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期三-->
                 <template slot-scope="{ row, column }" slot="WED">
                     <div :class="row.weeklies.WED.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <div class="toggle-status-btn-wrap">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'" v-if="!row.weeklies[column.slot].courseId || row.weeklies[column.slot].courseId == courseId || !courseId">
                             <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" title="设置课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" title="修改课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" title="取消课程" @click="cancelCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="setClass" type="md-copy" title="重复操作" @click="copyCell(row, column.slot)" />
                         </div>
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.WED.classroomCode">{{row.weeklies.WED.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.WED.classroomCode">{{row.weeklies.WED.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.WED.classroomCode">{{row.weeklies.WED.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.WED.classroomCode">{{row.weeklies.WED.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期四-->
                 <template slot-scope="{ row, column }" slot="THU">
                     <div :class="row.weeklies.THU.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <div class="toggle-status-btn-wrap">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'" v-if="!row.weeklies[column.slot].courseId || row.weeklies[column.slot].courseId == courseId || !courseId">
                             <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" title="设置课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" title="修改课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" title="取消课程" @click="cancelCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="setClass" type="md-copy" title="重复操作" @click="copyCell(row, column.slot)" />
                         </div>
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.THU.classroomCode">{{row.weeklies.THU.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.THU.classroomCode">{{row.weeklies.THU.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.THU.classroomCode">{{row.weeklies.THU.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.THU.classroomCode">{{row.weeklies.THU.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期五-->
                 <template slot-scope="{ row, column }" slot="FRI">
                     <div :class="row.weeklies.FRI.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <div class="toggle-status-btn-wrap">
+                        <div class="toggle-status-btn-wrap" v-show="mode == 'set'" v-if="!row.weeklies[column.slot].courseId || row.weeklies[column.slot].courseId == courseId || !courseId">
                             <Icon class="cell-action-icon" v-show="!row.weeklies[column.slot].courseName" custom="iconfont icon-choose" title="设置课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-create" title="修改课程" @click="selectCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="row.weeklies[column.slot].courseName" type="md-close" title="取消课程" @click="cancelCell(row, column.slot)" />
                             <Icon class="cell-action-icon" v-show="setClass" type="md-copy" title="重复操作" @click="copyCell(row, column.slot)" />
                         </div>
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.FRI.classroomCode">{{row.weeklies.FRI.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.FRI.classroomCode">{{row.weeklies.FRI.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.FRI.classroomCode">{{row.weeklies.FRI.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.FRI.classroomCode">{{row.weeklies.FRI.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期六-->
                 <template slot-scope="{ row, column }" slot="SAT">
                     <div :class="row.weeklies.SAT.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.SAT.classroomCode">{{row.weeklies.SAT.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.SAT.classroomCode">{{row.weeklies.SAT.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.SAT.classroomCode">{{row.weeklies.SAT.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.SAT.classroomCode">{{row.weeklies.SAT.classroomName}}</p>
                     </div>
                 </template>
                 <!--星期日-->
                 <template slot-scope="{ row, column }" slot="SUN">
                     <div :class="row.weeklies.SUN.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
-                        <p class="course-name" v-show="curClass == 'all' || curClass == row.weeklies.SUN.classroomCode">{{row.weeklies.SUN.courseName}}</p>
-                        <p class="classroom-name" v-show="curClass == 'all' || curClass == row.weeklies.SUN.classroomCode">{{row.weeklies.SUN.classroomName}}</p>
+                        <p :class="['course-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'course-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.SUN.classroomCode">{{row.weeklies.SUN.courseName}}</p>
+                        <p :class="['classroom-name',(row.weeklies[column.slot].courseId == courseId && courseId) ? 'classroom-color':'']" v-show="curClass == 'all' || curClass == row.weeklies.SUN.classroomCode">{{row.weeklies.SUN.classroomName}}</p>
                     </div>
                 </template>
             </Table>
         </vuescroll>
         <Modal v-model="modalStatus" title="授课教室" @on-ok="modalOk" @on-cancel="modalCancel" class-name="dark-iview-modal dark-iview-select">
-            <Select v-model="setClass" style="display:inline-block;">
+            <Select v-show="teaClassList.length" v-model="setClass" style="display:inline-block;">
                 <Option v-for="(item,index) in teaClassList" :key="index" :value="item.classId">{{item.classInfo.name}}</Option>
             </Select>
+            <p class="no-class-tips">*暂未添加/设置授课教室</p>
         </Modal>
     </div>
 </template>
@@ -133,6 +134,10 @@ export default {
                 return []
             }
         },
+        courseId:{
+            type:String,
+            default:''
+        },
         teacher: {
             type: String,
             default: ''
@@ -142,6 +147,10 @@ export default {
             default: () => {
                 return []
             }
+        },
+        mode:{
+            type:String,
+            default:'set' //set:设置模式 view:视图模式,只渲染功能
         }
     },
     data() {
@@ -312,6 +321,7 @@ export default {
                                 schedItem.time.forEach(timeItem => {
                                     if (timeItem.id == item.id) {
                                         item.weeklies[timeItem.week].courseName = cusItem.name
+                                        item.weeklies[timeItem.week].courseId = cusItem.id
                                         item.weeklies[timeItem.week].classId = schedItem.classId
                                         item.weeklies[timeItem.week].classroomName = classInfo ? classInfo.name : '暂无数据'
                                     }

+ 8 - 7
TEAMModelOS/ClientApp/src/view/newcourse/TimeSetting.vue

@@ -12,9 +12,9 @@
                                     <span class="content">{{ '('+item.label+')'}}</span>
                                 </div>
                                 <div class="action-box">
-                                    <Icon type="md-add" @click="showAddTime(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
-                                    <Icon type="md-trash" @click="delTimeNode(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
-                                    <Icon type="md-create" @click="editTimeNode(curTmIndex)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-add" @click="showAddTime(index)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-trash" @click="delTimeNode(index)" color="white" size="18" style="cursor:pointer;" />
+                                    <Icon type="md-create" @click="editTimeNode(index)" color="white" size="18" style="cursor:pointer;" />
                                 </div>
                             </div>
                         </TimelineItem>
@@ -28,16 +28,16 @@
                 </vuescroll>
             </div>
         </div>
-        <Modal v-model="addTimeStatus" :title="status == 0 ? '添加节点' : '编辑节点'" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmAddTime" @on-cancel="initTimeNode">
+        <Modal v-model="addTimeStatus" :title="status == 0 ? '添加时段' : '编辑时段'" class-name="dark-iview-modal dark-iview-form" @on-ok="confirmAddTime" @on-cancel="initTimeNode">
             <Form ref="timeNode" :model="timeNode" :label-width="80" label-colon :rules="ruleValidate">
                 <FormItem label="名称" prop="label">
-                    <Input v-model="timeNode.label" placeholder="输入节点名称......" style="width: 240px"></Input>
+                    <Input v-model="timeNode.label" placeholder="输入时段名称......" style="width: 240px"></Input>
                 </FormItem>
                 <FormItem label="开始" prop="start">
-                    <TimePicker v-model="timeNode.start" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
+                    <TimePicker v-model="timeNode.start" :steps="[1, 5]" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
                 </FormItem>
                 <FormItem label="结束">
-                    <TimePicker v-model="timeNode.end" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
+                    <TimePicker v-model="timeNode.end" :steps="[1, 5]" format="HH:mm" placeholder="00:00" style="width: 240px"></TimePicker>
                 </FormItem>
                 <FormItem label="类型" prop="type">
                     <RadioGroup v-model="timeNode.type" style="color: white;">
@@ -106,6 +106,7 @@ export default {
         },
         //编辑时间节点
         editTimeNode(index) {
+            console.log(index)
             this.status = 1
             this.timeNodeIndex = index
             let times = this.timetable[index].time.split(' - ')

+ 81 - 42
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -52,8 +52,9 @@
 									<div class="qn-box-header-tools">
 										<!-- <span class="qn-box-header-tools-tool" v-show="currentQn.status !== 300 && qnList.length">
 											<Icon type="md-create" size="18" title="编辑" @click="onEditQn" /></span> -->
-										<span class="qn-box-header-tools-tool" v-show="currentQn.progress === 'going' && qnList.length">
-											<Icon type="md-undo" size="18" :title="$t('survey.undo')" @click="onCancelQn" style="margin-left: 8px" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" /></span>
+										<!-- <span class="qn-box-header-tools-tool" v-show="currentQn.progress === 'going' && qnList.length">
+											<Icon type="md-undo" size="18" :title="$t('survey.undo')" @click="onCancelQn" style="margin-left: 8px" v-if="($access.can('admin.*|schoolAc-upd') || isPrivate)" />
+										</span> -->
 									</div>
 								</div>
 								<vuescroll ref="qnDetailsScroll">
@@ -316,8 +317,8 @@
 				let qnBaseInfo = isQnFormEdit ? await this.$refs.qnForm.handleSubmit("qnForm") : this.currentQn;
 				let qnItems = this.$refs.qnPaper.items || [];
 				// 将问卷试题内容保存到blob 用blobUrl来替换quesitons字段
-				qnBaseInfo.ans = this.getSurveyAns(qnItems)
-				qnBaseInfo.questionUrl = await this.doUploadBlob(qnBaseInfo, qnItems);
+				qnBaseInfo.answers = this.getSurveyAns(qnItems)
+				qnBaseInfo.blob = await this.doUploadBlob(qnBaseInfo, qnItems);
 				// 开始保存问卷
 				this.saveorUpdataQn(qnBaseInfo)
 					.then((res) => {
@@ -334,9 +335,8 @@
 					});
 			},
 			
-			/* 保存问卷题目到Blob */
-			async doUploadBlob(qnBaseInfo, items) {
-				console.log('上传参数', qnBaseInfo)
+			/* 上传index.json */
+			async doUploadItems(qnBaseInfo,items){
 				return new Promise(async (resolve, reject) => {
 					let promiseArr = []
 					// 获取初始化Blob需要的数据
@@ -349,25 +349,6 @@
 						qnBaseInfo.scope
 					);
 					
-					// 上传index.json
-					promiseArr.push(new Promise(async (r, j) => {
-						// let itemJsonFile = await this.$evTools.createBlobItem(exerciseItem);
-						let file = new File([JSON.stringify(qnBaseInfo)], "index.json");
-						try {
-							// 等待上传blob的返回结果
-							let blobFile = await containerClient.upload(file, 'survey/' + qnBaseInfo.id);
-							if (blobFile.blob) {
-								console.log('上传Blob成功', blobFile)
-								r(blobFile.blob)
-							} else {
-								this.$Message.error(this.$t('evaluation.newExercise.uploadErrorTip'));
-							}
-						} catch (e) {
-							this.$Message.error(e.spaceError);
-						}
-					}))
-					
-					
 					for (let item of items) {
 						let curId = item.id || this.$tools.guid()
 						promiseArr.push(new Promise(async (r, j) => {
@@ -388,12 +369,42 @@
 						}))
 					}
 					Promise.all(promiseArr).then(result => {
-						console.log(result)
-						resolve(result.slice(1))
+						resolve(result)
 					})
 				})
 			},
 			
+			/* 保存问卷题目到Blob */
+			doUploadBlob(qnBaseInfo, items) {
+				return new Promise(async (resolve,reject) => {
+					let itemUrls = await this.doUploadItems(qnBaseInfo, items)
+					qnBaseInfo.slides = itemUrls
+					// 获取初始化Blob需要的数据
+					let sasData = qnBaseInfo.scope === 'private' ? await this.$tools.getPrivateSas() : await this.$tools.getSchoolSas();
+					//初始化Blob
+					let containerClient = new blobTool(
+						sasData.url,
+						sasData.name,
+						sasData.sas,
+						qnBaseInfo.scope
+					);
+					let file = new File([JSON.stringify(qnBaseInfo)], "index.json");
+					try {
+						// 等待上传blob的返回结果
+						let blobFile = await containerClient.upload(file, 'survey/' + qnBaseInfo.id);
+						if (blobFile.blob) {
+							delete qnBaseInfo.slides
+							resolve(blobFile.blob)
+						} else {
+							this.$Message.error(this.$t('evaluation.newExercise.uploadErrorTip'));
+						}
+					} catch (e) {
+						reject(e);
+					}
+				})
+				
+			},
+			
 			/* 获取当前问卷活动学生作答数据 */
 			async getSurveyStudents(surveyItem) {
 				this.isLoading = true
@@ -404,15 +415,15 @@
 					ids: surveyItem.classes,
 					scope:surveyItem.owner === this.$store.state.userInfo.schoolCode ? 'school' : 'private'
 				}).then(res => {
-					if (!res.error && res.classrooms.length) {
+					if (!res.error && res.stus.length) {
 						let list = []
-						res.classrooms.forEach(classroom => {
-							classroom.students.forEach(i => {
+						res.stus.forEach(classStus => {
+							classStus.forEach(i => {
 								list.push({
 									id: i.id,
 									name: i.name,
 									no: i.no,
-									classroomName: classroom.name
+									classroomName: i.className
 								})
 							})
 						})
@@ -429,6 +440,7 @@
 						this.isLoading = false
 					}
 				}).catch(err => {
+					console.log(err)
 					this.$Message.error(this.$t('vote.getClassDataFailTip'))
 					this.isLoading = false
 				})
@@ -454,17 +466,43 @@
 			
 			/* 获取正在进行中的投票活动的投票数据 */
 			getAnswerdRecord(surveyItem){
-				return new Promise((r,j) => {
-					this.$api.questionnaire.GetAnswerdRecord({
-						id: surveyItem.id,
-						code: surveyItem.code,
-					}).then(res => {
-						if(!res.error){
-							r(res.userids)
+				return new Promise(async (r,j) => {
+					if(surveyItem.progress !== 'finish'){
+						this.$api.questionnaire.GetAnswerdRecord({
+							id: surveyItem.id,
+							code: surveyItem.code,
+						}).then(res => {
+							if(!res.error){
+								r(res.userids)
+							}
+						}).catch(err => {
+							j(err)
+						})
+					}else{ // 如果是已结束的活动 则从blob读取作答数据 
+						try{
+							let curItemRecord = await this.getBlobJsonFile(surveyItem.scope,surveyItem.recordUrl)
+							r(curItemRecord.userids)
+						}catch(e){
+							j(e)
 						}
-					}).catch(err => {
-						j(err)
-					})
+					}
+					
+				})
+			},
+			
+			/* 根据已结束的RecordUrl来获取投票结果数据 */
+			getBlobJsonFile(scope,url){
+				return new Promise(async (resolve,reject) => {
+					let blobHost = scope === 'private' ?  JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri : JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri
+					// 根据试卷的Blob地址 去读取JSON文件
+					let sasString = scope === 'private' ?  await this.$tools.getPrivateSas() : await this.$tools.getSchoolSas()
+					try{
+						let itemJson = JSON.parse(await this.$tools.getFile(blobHost + url + sasString.sas))
+						resolve(itemJson)
+					}catch(e){
+						this.$Message.error('文件获取失败!')
+						reject(e)
+					}
 				})
 			},
 
@@ -585,6 +623,7 @@
 										this.deleteBlobPrefix(this.currentQn).then(status => {
 											if (status === 200) {
 												this.isLoading = false;
+												this.qnList.splice(this.qnList.reverse().indexOf(this.currentQn), 1);
 												this.$Message.success(this.$t('survey.deleteSuc'));
 												this.handleTabClick(
 													this.$route.name === "manageQuestionnaire" ? 0 : 1

+ 42 - 20
TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue

@@ -212,7 +212,7 @@
 				let fullItem = item.id ? await this.getVoteDetails(item) : item
 				this.currentVote = fullItem
 				this.activeVoteIndex = index
-				if (item.id) this.getVoteStudents(fullItem,fullItem.classes)
+				if (item.id && item.progress !== 'pending') this.getVoteStudents(fullItem,fullItem.classes)
 				this.$refs.voteForm.voteFormEdit = false
 				this.$refs.voteFormScroll.scrollTo({
 						y: 0,
@@ -241,24 +241,46 @@
 			},
 			
 			/* 获取正在进行中的投票活动的投票数据 */
-			getVoteRecord(voteItem){
-				return new Promise((r,j) => {
-					this.$api.learnActivity.FindVoteRecord({
-						id: voteItem.id,
-						code: voteItem.code,
-					}).then(res => {
-						if(!res.error){
-							r(res)
+			async getVoteRecord(voteItem){
+				return new Promise(async (r,j) => {
+					// 如果是进行中的活动 则从cosmos获取实时作答数据
+					if(voteItem.progress === 'going'){
+						this.$api.learnActivity.FindVoteRecord({
+							id: voteItem.id,
+							code: voteItem.code,
+						}).then(res => {
+							if(!res.error){
+								r(res)
+							}
+						}).catch(err => {
+							j(err)
+						})
+					}else{ // 如果是已结束的活动 则从blob读取作答数据 
+						try{
+							let curItemRecord = await this.getBlobJsonFile(voteItem.scope,voteItem.recordUrl)
+							r(curItemRecord)
+						}catch(e){
+							j(e)
 						}
-					}).catch(err => {
-						j(err)
-					})
+					}
+					
 				})
 			},
 			
 			/* 根据已结束的RecordUrl来获取投票结果数据 */
-			getRecordUrlData(){
-				
+			getBlobJsonFile(scope,url){
+				return new Promise(async (resolve,reject) => {
+					let blobHost = scope === 'private' ?  JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri : JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri
+					// 根据试卷的Blob地址 去读取JSON文件
+					let sasString = scope === 'private' ?  await this.$tools.getPrivateSas() : await this.$tools.getSchoolSas()
+					try{
+						let itemJson = JSON.parse(await this.$tools.getFile(blobHost + url + sasString.sas))
+						resolve(itemJson)
+					}catch(e){
+						this.$Message.error('文件获取失败!')
+						reject(e)
+					}
+				})
 			},
 			
 
@@ -288,13 +310,14 @@
 								scope: this.getCurScope
 							}).then(res => {
 								if (!res.error && res.flag) {
+									console.log(this.voteList.indexOf(this.currentVote))
+									this.voteList.splice(this.voteList.reverse().indexOf(this.currentVote), 1)
 									setTimeout(() => {
 										this.isLoading = false
 										this.$Message.success(this.$t('vote.deleteSuc'))
 										this.handleTabClick(this.$route.name === 'manageVote' ? 0 : 1)
 									},1000)
 									
-									// this.voteList.splice(this.voteList.indexOf(this.currentVote), 1)
 									// this.isLoading = false
 									// this.$Message.success(this.$t('vote.deleteSuc'))
 									// if (this.voteList.length) this.onVoteClick(this.voteList[0], 0)
@@ -325,7 +348,7 @@
 				this.isLoading = true
 				let records = await this.getVoteRecord(voteItem)
 				//  先查找 投票发布对象关联的学生清单 然后再去判断学生的作答情况
-				console.log(voteItem)
+				console.log('当前投票的作答数据======',records)
 				this.$api.schoolSetting.getClassroomStudent({
 					school_code: this.$store.state.userInfo.schoolCode,
 					ids: voteItem.classes,
@@ -339,7 +362,7 @@
 									id: i.id,
 									name: i.name,
 									no: i.no,
-									classroomName: i.classId
+									classroomName: i.className
 								})
 							})
 						})
@@ -363,16 +386,15 @@
 							console.log(this.studentsTable)
 							this.tableData = arr
 						} else {
+							this.studentsTable = []
 							this.tableData = []
 						}
-						this.isLoading = false
 					} else {
 						this.$Message.error(this.$t('vote.getDataFailTip'))
-						this.isLoading = false
 					}
 				}).catch(err => {
-					console.log(err)
 					this.$Message.error(this.$t('vote.getClassDataFailTip'))
+				}).finally(() => {
 					this.isLoading = false
 				})
 			},

+ 3 - 3
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -1873,7 +1873,7 @@ namespace TEAMModelOS.Controllers.Analysis
                         idName.Add(ids);
                     }
                 }
-                foreach (string s in info.targetClassIds)
+                foreach (string s in info.classes)
                 {
 
                     //存放每个班级学生总分
@@ -2309,7 +2309,7 @@ namespace TEAMModelOS.Controllers.Analysis
             List<string> classList = new List<string>();
             List<Dictionary<string, object>> exerciseScatter = new List<Dictionary<string, object>>();
             //Dictionary<string, object> scatterAnalysis = new Dictionary<string, object>();
-            classList = exam.targetClassIds;
+            classList = exam.classes;
             List<string> key = new List<string>
             {
                 "id",
@@ -2761,7 +2761,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 info.subjects = examDtos.subjects;
                 info.period = examDtos.period;
                 examDtos.targetClasses.ForEach(e => {
-                    info.targetClassIds.Add(e.id);
+                    info.classes.Add(e.id);
                 });
                 examDtos.papers.ForEach(p => {
                     PaperSimple simple = new PaperSimple();

+ 1 - 1
TEAMModelOS/Controllers/Analysis/AnalysisController.cs

@@ -289,7 +289,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
                 ipoint = gradeTotal[personCount];
                 //以班级为单位
-                foreach (string classId in info.targetClassIds)
+                foreach (string classId in info.classes)
                 {
                     Class classroom = null;
                     var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classId, new PartitionKey($"Class-{code}"));

+ 45 - 35
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -68,12 +68,12 @@ namespace TEAMModelOS.Controllers
                 request.code = "Exam-" + request.code;
                 request.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 int stuCount = 0;
-                for (int i = 0; i < request.targetClassIds.Count; i++)
+                for (int i = 0; i < request.classes.Count; i++)
                 {
                     List<string> ids = new List<string>();
                     //处理班级人数(公共部分的校本名单)
                     //List<Student> students = new List<Student>();
-                    await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.classId = '{request.targetClassIds[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{request.school}") }))
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.classId = '{request.classes[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{request.school}") }))
                     {
                         using var json = await JsonDocument.ParseAsync(item.ContentStream);
                         if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -90,7 +90,7 @@ namespace TEAMModelOS.Controllers
                     {                        
                         //处理发布对象为自选名单(个人)
                         List<StuList> stuLists = new List<StuList>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{request.targetClassIds[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
+                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{request.classes[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
                         {
                             stuLists.Add(item);
                         }
@@ -121,7 +121,7 @@ namespace TEAMModelOS.Controllers
                     {
                         //发布对象为自选名单(校本)
                         List<StuList> stuLists = new List<StuList>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{request.targetClassIds[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{code}") }))
+                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{request.classes[i]}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{code}") }))
                         {
                             stuLists.Add(item);
                         }
@@ -276,23 +276,23 @@ namespace TEAMModelOS.Controllers
             try
             {
                 if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
-                var query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.targetClassIds from c ";
+                var query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes from c ";
                 if (requert.TryGetProperty("classIds", out JsonElement classIds)) {
                     List<string> ids = classIds.ToObject<List<string>>();
                     HashSet<string> strs = new HashSet<string>();
                     if (ids.Count > 1)
                     {
                         foreach (string id in ids) {
-                            strs.Add($"array_contains(c.targetClassIds,'{id}')");
+                            strs.Add($"array_contains(c.classes,'{id}')");
                         }                           
                     }
                     else
                     {
                         string ssr = ids.Count > 0 ? ids[0] : "";
-                        strs.Add($"array_contains(c.targetClassIds,'{ssr}')");
+                        strs.Add($"array_contains(c.classes,'{ssr}')");
                     }
                     string ss = string.Join(" or ", strs);
-                    query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.targetClassIds from c where ({ss})";
+                    query = $"select c.id,c.name,c.code,c.period,c.startTime,c.endTime,c.stuCount,c.type,c.progress,c.examType,c.createTime, c.subjects, c.grades, c.scope,c.classes from c where ({ss})";
                 };
                 var client = _azureCosmos.GetCosmosClient();
                 List<ExamInfo> examInfo = new List<ExamInfo>();                
@@ -386,6 +386,7 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("paperId", out JsonElement paperId)) return BadRequest();
             //根据不同评测的类型返回对应的编码
             if (!request.TryGetProperty("code", out JsonElement school)) return BadRequest();
+            if (!request.TryGetProperty("scode", out JsonElement scode)) return BadRequest();
             try
             {
                 List<string> ids = new List<string>();
@@ -410,7 +411,7 @@ namespace TEAMModelOS.Controllers
                 List<PaperSimple> standerAnswers = new List<PaperSimple>();
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
                     queryText: $"select A0.point,A0.answers from c join A0 in c.papers where c.id = '{id}'and A0.id = '{paperId}'",
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school}") }))
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{scode}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -601,7 +602,7 @@ namespace TEAMModelOS.Controllers
                     }
                     if (flag)
                     {
-                        ExamInfo exam = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{school}"));
+                        ExamInfo exam = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"{scode}"));
                         result.progress = true;
                         exam.subjects.ForEach(s =>
                         {
@@ -610,7 +611,7 @@ namespace TEAMModelOS.Controllers
                                 s.classCount += 1;
                             }
                         });
-                        await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(exam, id.ToString(), new PartitionKey($"Exam-{school}"));
+                        await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(exam, id.ToString(), new PartitionKey($"{scode}"));
                     }
                     result.sum[newIndex] = result.studentScores[newIndex].Sum();
                     classResult = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(result, result.id, new PartitionKey($"{result.code}"));
@@ -835,16 +836,18 @@ namespace TEAMModelOS.Controllers
                 //if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                 if (!requert.TryGetProperty("studentId", out JsonElement studentId)) return BadRequest();
                 if (!requert.TryGetProperty("code", out JsonElement school)) return BadRequest();
+                if(!requert.TryGetProperty("scode", out JsonElement scode)) return BadRequest();
                 var client = _azureCosmos.GetCosmosClient();
                 var query = $"select c.id,c.code,A0.id paperId,A0.code paperCode,A0.name paperName,A0.multipleRule,A0.scope,A0.blob from c join A0 in c.papers where c.id ='{id}'";
                 List<object> papers = new List<object>();
                 List<object> subjects = new List<object>();
                 List<string> classIds = new List<string>();
-                //存放当前学生所在班级ID
+                //存放当前学生所在班级ID或者名单ID
                 HashSet<string> resultIds = new HashSet<string>();
-                //查询校本班级ID
-                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(
-                    queryText: $"select c.id from c join A0 in c.students where A0.id = '{studentId}' and c.pk = 'Class' "))
+                //List<string> ids = new List<string>();
+                //处理班级人数(公共部分的校本名单)
+                //List<Student> students = new List<Student>();
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.classId id from c where c.id = '{studentId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{school}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -857,23 +860,28 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                 }
-                //查询私人班级ID
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(
-                   queryText: $"select c.id from c join A0 in c.students where A0.id = '{studentId}' and c.pk = 'Class' "))
+                //获取自定义名单信息
+                List<StuList> stuLists = new List<StuList>();
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select c.id from c join A0 in c.students where A0.id = '{studentId}'" ,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
                 {
-                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    stuLists.Add(item);
+                }
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select c.id from c join A0 in c.students where A0.id = '{studentId}'",
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{school}") }))
+                {
+                    stuLists.Add(item);
+                }
+                if (stuLists.Count > 0)
+                {
+                    foreach (StuList stuList in stuLists)
                     {
-                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
-                        while (accounts.MoveNext())
-                        {
-                            JsonElement account = accounts.Current;
-                            resultIds.Add(account.GetProperty("id").GetString());
-                        }
+                        resultIds.Add(stuList.id);
                     }
+
                 }
-                var queryClassId = $"select c.targetClassIds id from c where c.id ='{id}'";
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: queryClassId, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school}") }))
+                var queryClassId = $"select c.classes id from c where c.id ='{id}'";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: queryClassId, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{scode}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -886,16 +894,18 @@ namespace TEAMModelOS.Controllers
                         }
 
                     }
-                    
+
                 }
                 //存放该学生所在班级参与当前评测的ID
                 List<string> infoIds = new List<string>();
-                foreach (string ids in resultIds) {
-                    if (classIds.Contains(ids)) {
+                foreach (string ids in resultIds)
+                {
+                    if (classIds.Contains(ids))
+                    {
                         infoIds.Add(ids);
                     }
                 }
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school}") }))
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{scode}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -908,7 +918,7 @@ namespace TEAMModelOS.Controllers
                 }
                 var querySubject = $"select A0.id,A0.name from c join A0 in c.subjects where c.id ='{id}'";
                 //List<object> props = new List<object>();
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: querySubject, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{school}") }))
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: querySubject, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{scode}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
                     if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
@@ -1013,7 +1023,7 @@ namespace TEAMModelOS.Controllers
                 {
                     foreach (string str in resultIds)
                     {
-                        strs.Add($"array_contains(c.targetClassIds,'{str}')");
+                        strs.Add($"array_contains(c.classes,'{str}')");
                         //builder.Append($"array_contains(c.targetClassIds,'{str}')").Append("or");
                     }
                     
@@ -1021,7 +1031,7 @@ namespace TEAMModelOS.Controllers
                 }
                 else {
                     string ssr = resultIds.Count > 0 ? resultIds[0] : "";
-                    strs.Add($"array_contains(c.targetClassIds,'{ssr}')");
+                    strs.Add($"array_contains(c.classes,'{ssr}')");
                     //builder.Append($" array_contains(c.targetClassIds,'{ssr}')");
                 }
                 string ss = string.Join(" or ", strs);

+ 10 - 10
TEAMModelOS/Controllers/Common/SurveyController.cs

@@ -290,7 +290,7 @@ namespace TEAMModelOS.Controllers
                 }
                 else
                 {
-                    if (survey.scope == "school" && survey.owner.Equals(school))
+                    if (survey.scope == "school" && survey.school.Equals(school))
                     {
                         flag = true;
                     }
@@ -302,7 +302,7 @@ namespace TEAMModelOS.Controllers
                     survey.status = 404;
                     survey = await client.GetContainer("TEAMModelOS", "Common").UpsertItemAsync(survey, new PartitionKey($"{survey.code}"));
                     var adid = survey.id;
-                    var adcode = $"Activity-{survey.owner}";
+                    var adcode = $"Activity-{survey.school}";
                     ActivityData data = null;
                     try
                     {
@@ -514,7 +514,7 @@ namespace TEAMModelOS.Controllers
                 if (survey != null)
                 {
                     var adid = survey.id;
-                    var adcode = $"Activity-{survey.owner}";
+                    var adcode = $"Activity-{survey.school}";
                     try {
                         if (survey.scope == "school")
                         {
@@ -561,10 +561,10 @@ namespace TEAMModelOS.Controllers
                                 }
                                 var cods = new { records = recs };
                                 //问卷整体情况
-                                await _azureStorage.UploadFileByContainer(survey.owner, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
+                                await _azureStorage.UploadFileByContainer(survey.blobcntr, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
                                 //结算每道题的答题情况
 
-                                var ContainerClient = _azureStorage.GetBlobContainerClient(survey.owner);
+                                var ContainerClient = _azureStorage.GetBlobContainerClient(survey.blobcntr);
                                 var route = ContainerClient.Uri.ToString();
 
                                 //获取
@@ -573,7 +573,7 @@ namespace TEAMModelOS.Controllers
                                 {
                                     List<string> items = await ContainerClient.List($"survey/{survey.id}/urecord");
                                     List<SurveyRecord> surveyRecords = new List<SurveyRecord>();
-                                    (string uri, string sas) blobAuth = _azureStorage.GetBlobContainerSAS(survey.owner, BlobContainerSasPermissions.Read);
+                                    (string uri, string sas) blobAuth = _azureStorage.GetBlobContainerSAS(survey.blobcntr, BlobContainerSasPermissions.Read);
                                     string sas = blobAuth.sas;
                                     var rcode = await _clientFactory.CreateClient().GetAsync(new Uri($"{route}/survey/{survey.id}/record.json?{sas}"));
                                     var jsonc = await JsonDocument.ParseAsync(await rcode.Content.ReadAsStreamAsync());
@@ -589,13 +589,13 @@ namespace TEAMModelOS.Controllers
                                         surveyRecords.Add(Record);
                                     }
                                     await _dingDing.SendBotMsg($"问卷调查问题结算数据{surveyRecords.ToJsonString()}", GroupNames.成都开发測試群組);
-                                    for (int index = 0; index < survey.ans.Count; index++)
+                                    for (int index = 0; index < survey.answers.Count; index++)
                                     {
                                         string url = $"{survey.id}/qrecord/{index}.json";
                                         QuestionRecord question = new QuestionRecord() { index = index };
                                         foreach (SurveyRecord record in surveyRecords)
                                         {
-                                            if (record.ans.Count == survey.ans.Count)
+                                            if (record.ans.Count == survey.answers.Count)
                                             {
                                                 foreach (var an in record.ans[index])
                                                 {
@@ -613,7 +613,7 @@ namespace TEAMModelOS.Controllers
                                                     }
                                                     else
                                                     {
-                                                        if (survey.ans[index].Contains(an))
+                                                        if (survey.answers[index].Contains(an))
                                                         {
                                                             //如果是客观题code
                                                             question.opt.Add(an, new HashSet<string> { record.userid });
@@ -627,7 +627,7 @@ namespace TEAMModelOS.Controllers
                                                 }
                                             }
                                         }
-                                        await _azureStorage.UploadFileByContainer(survey.owner, question.ToJsonString(), "survey", url);
+                                        await _azureStorage.UploadFileByContainer(survey.blobcntr, question.ToJsonString(), "survey", url);
                                     }
                                 }
                                 catch (Exception ex)

+ 5 - 7
TEAMModelOS/Controllers/Common/VoteController.cs

@@ -291,7 +291,7 @@ namespace TEAMModelOS.Controllers.Learn
                     flag = true;
                 }
                 else {
-                    if (vote.scope == "school"&& vote.owner.Equals(school)) {
+                    if (vote.scope == "school"&& vote.school.Equals(school)) {
                         flag = true;
                     }
                 }
@@ -302,7 +302,7 @@ namespace TEAMModelOS.Controllers.Learn
                     vote.status = 404;
                     vote = await client.GetContainer("TEAMModelOS", "Common").UpsertItemAsync(vote,  new PartitionKey($"{vote.code}"));
                     var adid = vote.id;
-                    var adcode = $"Activity-{vote.owner}";
+                    var adcode = $"Activity-{vote.school}";
                     ActivityData data = null;
                     try
                     {
@@ -537,12 +537,12 @@ namespace TEAMModelOS.Controllers.Learn
                         var gp = recordsBlob.GroupBy(x => x.userid).Select(x => new { key = x.Key, list = x.ToList() });
                         foreach (var g in gp)
                         {
-                            tasks.Add(_azureStorage.UploadFileByContainer(vote.owner, g.list.ToJsonString(), "vote", $"{vote.id}/urecord/{g.key}.json"));
+                            tasks.Add(_azureStorage.UploadFileByContainer(vote.blobcntr, g.list.ToJsonString(), "vote", $"{vote.id}/urecord/{g.key}.json"));
                         }
                         //处理活动方的记录, 
                         string url = $"/vote/{vote.id}/record.json";
                         vote.recordUrl = url;
-                        tasks.Add(_azureStorage.UploadFileByContainer(vote.owner,new{ options = countcds, records = recordsBlob }   .ToJsonString(), "vote", $"{vote.id}/record.json"));
+                        tasks.Add(_azureStorage.UploadFileByContainer(vote.blobcntr, new{ options = countcds, records = recordsBlob }   .ToJsonString(), "vote", $"{vote.id}/record.json"));
                         //处理投票者的记录
                         await Task.WhenAll(tasks);
                         //
@@ -556,7 +556,7 @@ namespace TEAMModelOS.Controllers.Learn
                             data = new ActivityData
                             {
                                 id = vote.id,
-                                code = $"Activity-{vote.owner}",
+                                code = $"Activity-{vote.school}",
                                 type = "vote",
                                 name = vote.name,
                                 startTime = vote.startTime,
@@ -566,7 +566,6 @@ namespace TEAMModelOS.Controllers.Learn
                                 progress = "finish",
                                 classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
                                 tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
-                                owner = vote.owner,
                                 subjects = new List<string> { "" }
 
                             };
@@ -587,7 +586,6 @@ namespace TEAMModelOS.Controllers.Learn
                                 scope = vote.scope,
                                 progress = "finish",
                                 classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
-                                owner = vote.owner,
                                 tmdids = new List<string> { "" },
                                 subjects = new List<string> { "" }
                             };

+ 22 - 4
TEAMModelOS/Controllers/Core/ImportController.cs

@@ -253,7 +253,7 @@ namespace TEAMModelOS.Controllers
         }
 
         /// <summary>
-        /// htmlString AnalyzeHtml
+        /// word直接转题目
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
@@ -268,16 +268,34 @@ namespace TEAMModelOS.Controllers
              (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
             return Ok(new { tests, emferror= error });
         }
+
+
+        /// <summary>
+        /// word转html
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("parse-docx")]
+        public IActionResult ParseDocx([FromForm] IFormFile file)
+        {
+            if (!FileType.GetExtention(file.FileName).ToLower().Equals("docx"))
+            {
+                return BadRequest(new Dictionary<string, object> { { "msg", "type is not docx!" }, { "code", ResponseCode.FAILED } });
+            }
+            var doc = _DOXC2HTMLTranslator.Translate(file.OpenReadStream());
+           // (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
+            return Ok(new { html= doc });
+        }
         /// <summary>
-        /// htmlString AnalyzeHtml
+        /// html转题目
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
         [HttpPost("parse-html")]
         public IActionResult AnalyzeHtml(JsonElement request)
         {
-            if (!request.TryGetProperty("htmlString", out JsonElement htmlString)) { return BadRequest(); }
-            (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(htmlString.GetString());
+            if (!request.TryGetProperty("html", out JsonElement html)) { return BadRequest(); }
+            (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(html.GetString());
             return Ok(new { tests, emferror= error });
         }
 

+ 136 - 131
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -396,160 +396,165 @@ namespace TEAMModelOS.Controllers
                 var client = _azureCosmos.GetCosmosClient();
                 List<object> stus = new List<object>();
                 List<string> stuIds = new List<string>();
-                
+                string info = "";
                 for (int i = 0; i < ids.GetArrayLength(); i++)
                 {
-                    List<object> scList = new List<object>();
-                    List<object> suList = new List<object>();
-                    List<(string id, string name, string pic, string code, string classId,string className, string groupId, string groupName, string no)> listStudent = new List<(string id, string name, string pic, string code, string classId, string className, string groupId, string groupName, string no)>();
-                    await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(
-                        queryText: $"select c.id,c.name,c.classId,c.code,c.groupId,c.groupName,c.no,c.picture from c where c.classId = '{ids[i].GetString()}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
-                    {
-                        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;
-                                stuIds.Add(account.GetProperty("id").GetString());
-                                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(account.GetProperty("classId").GetString(), new PartitionKey($"Class-{schoolId}"));
-                                string className = "";
-                                if (response.Status == 200)
+                    //ids.Add(id[i].ToJsonString());
+                    info += ids[i].ToJsonString() + ",";
+                }
+                //List<object> scList = new List<object>();
+                List<object> suList = new List<object>();
+                List<(string id, string name, string pic, string code, string classId ,string groupId, string groupName, string no)> listStudent = new List<(string id, string name, string pic, string code, string classId, string groupId, string groupName, string no)>();
+                //var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(ids[i].GetString(), new PartitionKey($"Class-{schoolId}"));
+                string className = "";
+                /*                if (response.Status == 200)
                                 {
                                     using var document = await JsonDocument.ParseAsync(response.ContentStream);
                                     Class @class = document.ToObject<Class>();
                                     className = @class.name;
-                                }
-                                listStudent.Add((account.GetProperty("id").GetString(),
-                                    account.GetProperty("name").GetString(), 
-                                    account.GetProperty("picture").GetString(),
-                                    account.GetProperty("code").GetString(), 
-                                    account.GetProperty("classId").GetString(),
-                                    className,
-                                    account.GetProperty("groupId").GetString(),
-                                    account.GetProperty("groupName").GetString(), 
-                                    account.GetProperty("no").GetString()));
-                            }
-                            var scinfos = listStudent.Select(o =>
-                                        new
-                                        {
-                                            o.id,
-                                            o.name,
-                                            o.pic,
-                                            o.code,
-                                            o.classId,
-                                            o.className,
-                                            o.groupId,
-                                            o.groupName,
-                                            o.no
-                                        });
-                            scList.AddRange(scinfos);
-                            stus.Add(scList);
+                                }*/
+                List<(string id, string name)> listClassList = new List<(string id,string name)>();
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(
+                                    queryText: $"select c.id,c.name from c where c.id in ({info[0..^1]})", 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 accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                        while (accounts.MoveNext())
+                        {
+                            JsonElement account = accounts.Current;
+                            listClassList.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
+                            //stuIds.Add(account.GetProperty("id").GetString());                           
                         }
                     }
-                    List<(string id, string code, string stuId,string name)> listStuList = new List<(string id, string code, string stuId,string name)> ();
-                    if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
+                }
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(
+                    queryText: $"select c.id,c.name,c.classId,c.code,c.groupId,c.groupName,c.no,c.picture from c where c.classId in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        List<StuList> stuLists = new List<StuList>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{ids[i].GetString()}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{schoolId}") }))
+                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                        while (accounts.MoveNext())
                         {
-                            stuLists.Add(item);
+                            JsonElement account = accounts.Current;
+                            stuIds.Add(account.GetProperty("id").GetString());
+
+                            listStudent.Add((account.GetProperty("id").GetString(),
+                                account.GetProperty("name").GetString(),
+                                account.GetProperty("picture").GetString(),
+                                account.GetProperty("code").GetString(),
+                                account.GetProperty("classId").GetString(),
+                                account.GetProperty("groupId").GetString(),
+                                account.GetProperty("groupName").GetString(),
+                                account.GetProperty("no").GetString()));
                         }
-                        if (stuLists.Count > 0)
+                    }
+                }
+                var grpBalance = listStudent.GroupBy(m => new { m.classId }).Distinct().Select(t =>t.ToList().Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.name,
+                                        o.pic,
+                                        o.code,
+                                        o.classId,
+                                        className = listClassList.FirstOrDefault(c => c.id == o.classId).name,
+                                        o.groupId,
+                                        o.groupName,
+                                        o.no
+                                    })
+                );
+                stus.AddRange(grpBalance);              
+                List<(string id, string code, string stuId, string name)> listStuList = new List<(string id, string code, string stuId, string name)>();
+                if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
+                {
+                    List<StuList> stuLists = new List<StuList>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{schoolId}") }))
+                    {
+                        stuLists.Add(item);
+                    }
+                    if (stuLists.Count > 0)
+                    {
+                        foreach (StuList stuList in stuLists)
                         {
-                            foreach (StuList stuList in stuLists)
+                            foreach (Students stu in stuList.students)
                             {
-                                foreach (Students stu in stuList.students)
-                                {
-                                    if (stu.code.Contains(schoolId.GetString()))
-                                    {
-                                        if (!stuIds.Contains(stu.id))
-                                        {
-                                            listStuList.Add((stu.id,
-                                                    stu.code,
-                                                    stuList.id,
-                                                    stuList.name));
-                                        }
-                                    }
-                                    else
-                                    {
-                                        listStuList.Add((stu.id,
-                                                    stu.code,
-                                                    stuList.id,
-                                                    stuList.name));
-                                    }
-                                }
-                                
+                                    listStuList.Add((stu.id,
+                                                stu.code,
+                                                stuList.id,
+                                                stuList.name));
                             }
-                            var infos = listStuList.Select(o =>
-                                        new
-                                        {
-                                            o.id,
-                                            o.code,
-                                            o.stuId,
-                                            o.name
-                                        });
-                            suList.AddRange(infos);
-                            stus.Add(suList);
+
                         }
+                        var infos = listStuList.GroupBy(m => new { m.stuId }).Distinct().Select(t => 
+                             t.ToList().Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.code,
+                                        o.stuId,
+                                        o.name
+                                    })
+                        );
+/*                        var infos = listStuList.Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.code,
+                                        o.stuId,
+                                        o.name
+                                    });*/
+                        stus.AddRange(infos);
+                        //stus.Add(suList);
                     }
-                    else {
-                        //处理发布对象为自选名单(个人)
-                        List<StuList> stuLists1 = new List<StuList>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id = '{ids[i].GetString()}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
-                        {
-                            stuLists1.Add(item);
-                        }
-                        if (stuLists1.Count > 0)
+                }
+                else
+                {
+                    //处理发布对象为自选名单(个人)
+                    List<StuList> stuLists1 = new List<StuList>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
+                    {
+                        stuLists1.Add(item);
+                    }
+                    if (stuLists1.Count > 0)
+                    {
+                        foreach (StuList stuList in stuLists1)
                         {
-                            foreach (StuList stuList in stuLists1)
+                            foreach (Students students in stuList.students)
+                            {
+
+                                    listStuList.Add((students.id,
+                                                students.code,
+                                                stuList.id,
+                                                stuList.name));
+                            }
+                            if (stuList.tmids.Count > 0)
                             {
-                                foreach (Students students in stuList.students)
+                                foreach (string tid in stuList.tmids)
                                 {
-                                    if (students.code.Contains(schoolId.GetString()))
-                                    {
-                                        if (!stuIds.Contains(students.id))
-                                        {
-                                            listStuList.Add((students.id,
-                                                    students.code,
-                                                    stuList.id,
-                                                    stuList.name));
-                                        }
-                                    }
-                                    else
-                                    {
-                                        listStuList.Add((students.id,
-                                                    students.code,
-                                                    stuList.id,
-                                                    stuList.name));
-                                    }
+                                    listStuList.Add((tid,
+                                                default,
+                                                stuList.id,
+                                                stuList.name));
                                 }
-                                if (stuList.tmids.Count > 0)
-                                {
-                                    foreach (string tid in stuList.tmids)
-                                    {
-                                        listStuList.Add((tid,
-                                                    default,
-                                                    stuList.id,
-                                                    stuList.name));
-                                    }
-                                }                               
                             }
-                            var infos = listStuList.Select(o =>
-                                       new
-                                       {
-                                           o.id,
-                                           o.code,
-                                           o.stuId,
-                                           o.name
-                                       });
-                            suList.AddRange(infos);
-                            stus.Add(suList);
                         }
+                        var infos = listStuList.GroupBy(m => new { m.stuId }).Distinct().Select(t => 
+                            t.ToList().Select(o =>
+                                    new
+                                    {
+                                        o.id,
+                                        o.code,
+                                        o.stuId,
+                                        o.name
+                                    })
+                        );
+                        stus.AddRange(infos);
+                        //stus.Add(suList);
                     }
-
-                }               
+                }             
                 return Ok(new { stus });
             }
             catch (Exception ex)

+ 1 - 1
TEAMModelOS/Controllers/Teacher/TeacherCommonController.cs

@@ -71,7 +71,7 @@ namespace TEAMModelOS.Controllers
         /// <returns></returns>
         [ProducesDefaultResponseType]
         [HttpPost("tch-find-activity")]
-        [AuthToken(Roles = "teacher")]
+        //[AuthToken(Roles = "teacher")]
         public async Task<IActionResult> FindTch(JsonElement requert)
         {
             var (id, _, _, school) = HttpContext.GetAuthTokenInfo();

+ 6 - 6
TEAMModelOS/Services/Common/ActivityStudentService.cs

@@ -331,10 +331,10 @@ namespace TEAMModelOS.Services.Common
             string tgSql = "";
             if (!string.IsNullOrWhiteSpace(joinSqlClasses))
             {
-                tgSql = $"and ({andSqlTmdids} or  {andSqlClasses } )";
+                tgSql = $" and ({andSqlTmdids} or  {andSqlClasses } )";
             }
             else {
-                tgSql = $"and {andSqlTmdids}";
+                tgSql = $" and {andSqlTmdids}";
             }
             //科目
             string joinSqlSubjects = "";
@@ -476,7 +476,7 @@ namespace TEAMModelOS.Services.Common
                 var client = _azureCosmos.GetCosmosClient();
                 Survey survey = null;
                 ///TODO 检查是否在投票范围内,包括在tmdids 及班级  但是需要处理认证金钥中的班级问题
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Survey>(queryText: $"select c.id,c.owner, c.code ,c.ans , c.progress,c.times,c.startTime,c.endTime from c where c.id = '{id}'",
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Survey>(queryText: $"select c.id,c.blobcntr, c.code ,c.answers , c.progress,c.times,c.startTime,c.endTime from c where c.id = '{id}'",
                     requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
                 {
                     survey = item;
@@ -490,7 +490,7 @@ namespace TEAMModelOS.Services.Common
                         if (request.TryGetProperty("record", out JsonElement record)) 
                         {
                             var recs = record.ToObject<List<List<string>>>();
-                            if (recs.IsNotEmpty() && recs.Count == survey.ans.Count)
+                            if (recs.IsNotEmpty() && recs.Count == survey.answers.Count)
                             {
                                 //处理问卷调查表的每一题选项数
                                // List<Task<string>> tasks = new List<Task<string>>();
@@ -498,7 +498,7 @@ namespace TEAMModelOS.Services.Common
                                     Dictionary<string, int> dict = new Dictionary<string, int>();
                                     if (recs[index].IsNotEmpty()) {
                                         recs[index].ForEach(x => {
-                                            if (survey.ans[index].Contains(x))
+                                            if (survey.answers[index].Contains(x))
                                             {
                                                 if (dict.ContainsKey(x))
                                                 {
@@ -547,7 +547,7 @@ namespace TEAMModelOS.Services.Common
                                 //处理other ,这里暂不处理, 结算再处理other 
                                 //await Task.WhenAll(tasks);
                                 //保存当前提交人的记录
-                                await _azureStorage.UploadFileByContainer(survey.owner,new SurveyRecord { ans= recs, userid=userid, time = curr }.ToJsonString(), "survey", $"{survey.id}/urecord/{userid}.json");
+                                await _azureStorage.UploadFileByContainer(survey.blobcntr, new SurveyRecord { ans= recs, userid=userid, time = curr }.ToJsonString(), "survey", $"{survey.id}/urecord/{userid}.json");
                                 await azureRedis.GetRedisClient(8).SetAddAsync($"Survey:Submit:{survey.id}", userid);
                                 msgid = 1;
                             }

+ 104 - 97
TEAMModelOS/Services/Common/ActivityTeacherService.cs

@@ -35,51 +35,48 @@ namespace TEAMModelOS.Services.Common
         /// <returns></returns>
         public static async Task<(List<ActivityData> datas, string continuationToken)> FindAsTch(JsonElement requert, string school, AzureCosmosFactory _azureCosmos, AzureRedisFactory _azureRedis)
         {
+
+            if (string.IsNullOrWhiteSpace(school))
+            {
+                school = requert.GetProperty("school").GetString();
+            }
             //开始时间,默认最近三十天
             var stimestamp = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds();
-
-
-            if (!requert.TryGetProperty("stime", out JsonElement stime))
+            if (requert.TryGetProperty("stime", out JsonElement stime))
             {
-                if (stime.TryGetInt64(out long data))
+                if (!stime.ValueKind.Equals(JsonValueKind.Undefined) && !stime.ValueKind.Equals(JsonValueKind.Null) && stime.TryGetInt64(out long data))
                 {
                     stimestamp = data;
                 }
             }
-
+            string stimesql = $" c.startTime >= {stimestamp}  ";
+            //默认当前时间,  未开始的不能查询
+            var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            string etimesql = $" and c.startTime <= {etimestamp}   ";
             var progresssql = "";
-            if (!requert.TryGetProperty("progress", out JsonElement progress))
+            if (requert.TryGetProperty("progress", out JsonElement progress))
             {
 
                 if (!progress.ValueKind.Equals(JsonValueKind.Undefined) && !progress.ValueKind.Equals(JsonValueKind.Null) && progress.ValueKind.Equals(JsonValueKind.String))
                 {
-                    progresssql = $" and c.progress='{progresssql}' ";
+                    progresssql = $" and c.progress='{progress}' ";
                 }
             }
             var typesql = "";
-            if (!requert.TryGetProperty("type", out JsonElement type))
+            if (requert.TryGetProperty("type", out JsonElement type))
             {
 
                 if (!type.ValueKind.Equals(JsonValueKind.Undefined) && !type.ValueKind.Equals(JsonValueKind.Null) && type.ValueKind.Equals(JsonValueKind.String))
                 {
-                    typesql = $" and c.type='{typesql}' ";
+                    typesql = $" and c.type='{type}' ";
                 }
             }
-            //默认当前时间,  未开始的不能查询
-            var etimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-            //if (!requert.TryGetProperty("etime", out JsonElement etime))
-            //{
-            //    if (etime.TryGetInt64(out long data))
-            //    {
-            //        etimestamp = data;
-            //    };
-            //};
-            string continuationToken = null;
+            string continuationTokenSchool = null;
             //默认不指定返回大小
             int? topcout = null;
-            if (!requert.TryGetProperty("count", out JsonElement jcount))
+            if (requert.TryGetProperty("count", out JsonElement jcount))
             {
-                if (jcount.TryGetInt32(out int data))
+                if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
                 {
                     topcout = data;
                 }
@@ -91,28 +88,44 @@ namespace TEAMModelOS.Services.Common
                 iscontinuation = true;
             }
             //如果指定了返回大小
-            if (!requert.TryGetProperty("continuationToken", out JsonElement continuation))
+            if (requert.TryGetProperty("continuationTokenSchool", out JsonElement continuationSchool))
             {
-                //指定了cancellationToken 表示需要进行分页
-                if (!continuation.ValueKind.Equals(JsonValueKind.Null) && continuation.ValueKind.Equals(JsonValueKind.String))
+                //指定了cancellationToken continuationSchool
+                if (!continuationSchool.ValueKind.Equals(JsonValueKind.Null) && continuationSchool.ValueKind.Equals(JsonValueKind.String))
                 {
-                    continuationToken = continuation.GetString();
-                    
+                    continuationTokenSchool = continuationSchool.GetString();
+
                 }
             }
             //班级
+            string joinSqlClasses = "";
+            string andSqlClasses = "";
             List<string> classes = null;
-            if (!requert.TryGetProperty("classes", out JsonElement jclasses))
+            if (requert.TryGetProperty("classes", out JsonElement jclasses))
             {
                 if (jclasses.ValueKind is JsonValueKind.Array)
                 {
                     classes = jclasses.ToObject<List<string>>();
+                    if (classes.IsNotEmpty())
+                    {
+                        joinSqlClasses = " join A1 in c.classes ";
+                        List<string> sqlList = new List<string>();
+                        classes.ForEach(x => { sqlList.Add($" '{x}' "); });
+                        string sql = string.Join(" , ", sqlList);
+                        andSqlClasses = $"   A1 in ({sql}) ";
+                    }
                 }
             }
-            //班级
+            string tgSql = "";
+            if (!string.IsNullOrWhiteSpace(joinSqlClasses))
+            {
+                tgSql = $" and    {andSqlClasses }  ";
+            }
+            
+            //科目
             string joinSqlSubjects = "";
             string andSqlSubjects = "";
-            if (!requert.TryGetProperty("subjects", out JsonElement jsubjects))
+            if (requert.TryGetProperty("subjects", out JsonElement jsubjects))
             {
                 if (jsubjects.ValueKind is JsonValueKind.Array)
                 {
@@ -123,45 +136,39 @@ namespace TEAMModelOS.Services.Common
                         List<string> sqlList = new List<string>();
                         subjects.ForEach(x => { sqlList.Add($" '{x}' "); });
                         string sql = string.Join(" , ", sqlList);
-                        andSqlSubjects = $" and A2 in ('{sql}') ";
+                        andSqlSubjects = $" and A2 in ({sql}) ";
                     }
                 }
             }
-            string query = null;
-            if (classes.IsNotEmpty())
-            {
-                List<string> sqlList = new List<string>();
-                classes.ForEach(x => { sqlList.Add($" '{x}' "); });
-                string sql = string.Join(" , ", sqlList);
-                query = $" SELECT distinct  value c   FROM c   JOIN A0 IN c.classes join A1 in c.tmdids {joinSqlSubjects}  where c.startTime >= {stimestamp} and c.startTime <= {etimestamp} and  c.pk='Activity' {typesql} {progresssql}  {andSqlSubjects}  and   (A0 in('{sql}') or A1 ='{school} ') ";
-            }
-            else
-            {
-                query = $" SELECT distinct  value c   FROM c    join A1 in c.tmdids  {joinSqlSubjects}  where c.startTime >= {stimestamp} and c.startTime <= {etimestamp}  and c.pk='Activity' {typesql} {progresssql}  {andSqlSubjects}  and   A1 ='{school}' ";
-            }
 
             List<ActivityData> datas = new List<ActivityData>();
             var client = _azureCosmos.GetCosmosClient();
+
             //班主任 ,任课教师只需要查询两种校园活动 和班级活动 ,  不查询私人教室创建的活动。  
-            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(query, continuationToken: continuationToken, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Activity-{school}") }))
+            if (!string.IsNullOrWhiteSpace(school))
             {
-                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                string querySchool = $" SELECT distinct  value c   FROM c {joinSqlClasses} {joinSqlSubjects}  where {stimesql}  {etimesql} and c.pk='Activity' {progresssql}  {typesql}  {andSqlSubjects}  {tgSql}";
+                //查询数据归属学校的
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(querySchool, continuationToken: continuationTokenSchool, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Activity-{school}") }))
                 {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        datas.Add(obj.ToObject<ActivityData>());
-                    }
-                    //如果需要分页则跳出
-                    if (iscontinuation)
-                    {
-                        continuationToken = item.GetContinuationToken();
-                        break;
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            datas.Add(obj.ToObject<ActivityData>());
+                        }
+                        //如果需要分页则跳出
+                        if (iscontinuation)
+                        {
+                            continuationTokenSchool = item.GetContinuationToken();
+                            break;
+                        }
                     }
                 }
             }
             bool tips = false;
-            if (!requert.TryGetProperty("tips", out JsonElement jtips))
+            if (requert.TryGetProperty("tips", out JsonElement jtips))
             {
                 if (!jtips.ValueKind.Equals(JsonValueKind.Null) && !jtips.ValueKind.Equals(JsonValueKind.True))
                 {
@@ -170,50 +177,50 @@ namespace TEAMModelOS.Services.Common
             }
             if (tips)
             {
-                DoActivityTips activityTips;
-                dynamic res = default;
-                foreach (var data in datas)
-                {
-                    //处理参与度,
-                    switch (data.type)
-                    {
-                        //投票
-                        case "vote":
-                            activityTips = DoVoteTips;
-                            //msgid, //0不能投票,1可以投票,2不在时间范围内,3周期内的可投票数不足
-                            //voteCount 可用投票数
-                            res = activityTips(data, _azureCosmos, school, _azureRedis);
-                            break;
-                        //问卷
-                        case "survey":
-                            //msgid 0 已作答, 1未作答,2,未完成
-                            activityTips = DoSurveyTips;
-                            res = activityTips(data, _azureCosmos, school, _azureRedis);
-                            break;
-                        //评测
-                        case "exam":
-                            //msgid 0 已作答, 1未作答,2,未完成, 用时间控制 相关发布状态,并且展示相应的结果
-                            activityTips = DoExamTips;
-                            res = activityTips(data, _azureCosmos, school, _azureRedis);
-                            break;
-                        //学习活动
-                        case "learn":
-                            //msgid 0 已完成, 1未开始,2,未完成
-                            activityTips = DoLearnTips;
-                            res = activityTips(data, _azureCosmos, school, _azureRedis);
-                            break;
-                        //作业活动
-                        case "homework":
-                            //msgid 0 已作答, 1未作答,2,未完成,3已批改,且有错误,4已批改,已完成
-                            //index:0,1,5 错误题序
-                            activityTips = DoHomeworkTips;
-                            res = activityTips(data, _azureCosmos, school, _azureRedis);
-                            break;
-                        default: break;
-                    }
-                }
+                //DoActivityTips activityTips;
+                // dynamic res = default;
+                //foreach (var data in datas)
+                //{
+                //    //处理参与度,
+                //    switch (data.type)
+                //    {
+                //        //投票
+                //        case "vote":
+                //            activityTips = DoVoteTips;
+                //            //msgid, //0不能投票,1可以投票,2不在时间范围内,3周期内的可投票数不足
+                //            //voteCount 可用投票数
+                //            res = activityTips(data, _azureCosmos, school, _azureRedis);
+                //            break;
+                //        //问卷
+                //        case "survey":
+                //            //msgid 0 已作答, 1未作答,2,未完成
+                //            activityTips = DoSurveyTips;
+                //            res = activityTips(data, _azureCosmos, school, _azureRedis);
+                //            break;
+                //        //评测
+                //        case "exam":
+                //            //msgid 0 已作答, 1未作答,2,未完成, 用时间控制 相关发布状态,并且展示相应的结果
+                //            activityTips = DoExamTips;
+                //            res = activityTips(data, _azureCosmos, school, _azureRedis);
+                //            break;
+                //        //学习活动
+                //        case "learn":
+                //            //msgid 0 已完成, 1未开始,2,未完成
+                //            activityTips = DoLearnTips;
+                //            res = activityTips(data, _azureCosmos, school, _azureRedis);
+                //            break;
+                //        //作业活动
+                //        case "homework":
+                //            //msgid 0 已作答, 1未作答,2,未完成,3已批改,且有错误,4已批改,已完成
+                //            //index:0,1,5 错误题序
+                //            activityTips = DoHomeworkTips;
+                //            res = activityTips(data, _azureCosmos, school, _azureRedis);
+                //            break;
+                //        default: break;
+                //    }
+                //}
             }
-            return (datas, continuationToken);
+            return (datas, continuationTokenSchool);
         }
 
         private async static Task<dynamic> DoVoteTips(ActivityData commonData, AzureCosmosFactory _azureCosmos, string userid, AzureRedisFactory _azureRedis)