Переглянути джерело

Merge branch 'develop5.0-grouplist' into develop5.0-tmd

CrazyIter_Bin 3 роки тому
батько
коміт
9228e15f76
100 змінених файлів з 3503 додано та 3334 видалено
  1. 7 6
      TEAMModeBI/Controllers/BIHome/StudyStatisController.cs
  2. 29 22
      TEAMModelFunction/ActivityHttpTrigger.cs
  3. 14 6
      TEAMModelFunction/CourseServiceBus.cs
  4. 6 47
      TEAMModelFunction/MonitorServicesBus.cs
  5. 122 0
      TEAMModelFunction/ScsApisHttpTrigger.cs
  6. 2 0
      TEAMModelFunction/Startup.cs
  7. 15 20
      TEAMModelFunction/TriggerExam.cs
  8. 4 2
      TEAMModelFunction/TriggerExamLite.cs
  9. 11 8
      TEAMModelFunction/TriggerHomework.cs
  10. 4 2
      TEAMModelFunction/TriggerStudy.cs
  11. 11 8
      TEAMModelFunction/TriggerSurvey.cs
  12. 9 8
      TEAMModelFunction/TriggerVote.cs
  13. 82 0
      TEAMModelOS.SDK/DI/HttpTrigger/HttpTrigger.cs
  14. 2 3
      TEAMModelOS/Controllers/Third/Helpers/AESHelper.cs
  15. 16 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Bloblog.cs
  16. 134 1
      TEAMModelOS.SDK/Models/Cosmos/Common/GroupList.cs
  17. 10 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Homework.cs
  18. 4 0
      TEAMModelOS.SDK/Models/Cosmos/School/AreaSetting.cs
  19. 1 1
      TEAMModelOS.SDK/Models/Cosmos/School/SchoolTeacher.cs
  20. 2 1
      TEAMModelOS.SDK/Models/Cosmos/Student/Student.cs
  21. 380 0
      TEAMModelOS.SDK/Models/Service/ActivityService.cs
  22. 272 358
      TEAMModelOS.SDK/Models/Service/GroupListService.cs
  23. 0 257
      TEAMModelOS.SDK/Models/Service/StuListService.cs
  24. 88 0
      TEAMModelOS.SDK/Models/Service/Third/ScApisService.cs
  25. 65 0
      TEAMModelOS.SDK/Models/Service/Third/ThirdApisService.cs
  26. 77 0
      TEAMModelOS.SDK/Models/Service/Third/ThirdService.cs
  27. 0 627
      TEAMModelOS.SDK/Models/Service/TriggerStuActivity.cs
  28. 3 9
      TEAMModelOS/ClientApp/src/api/ability.js
  29. 55 0
      TEAMModelOS/ClientApp/src/api/common.js
  30. 0 16
      TEAMModelOS/ClientApp/src/api/courseMgmt.js
  31. 3 1
      TEAMModelOS/ClientApp/src/api/index.js
  32. 4 0
      TEAMModelOS/ClientApp/src/api/jyzx.js
  33. 3 7
      TEAMModelOS/ClientApp/src/api/learnActivity.js
  34. 1 23
      TEAMModelOS/ClientApp/src/api/schoolSetting.js
  35. 1 5
      TEAMModelOS/ClientApp/src/api/schoolUser.js
  36. 0 10
      TEAMModelOS/ClientApp/src/api/studentWeb.js
  37. 6 1
      TEAMModelOS/ClientApp/src/common/AbilityUpload.vue
  38. 1 0
      TEAMModelOS/ClientApp/src/common/BaseAreaList.vue
  39. 29 62
      TEAMModelOS/ClientApp/src/common/BaseClassSelect.vue
  40. 47 1
      TEAMModelOS/ClientApp/src/common/BaseClassSelectPri.vue
  41. 2 2
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  42. 130 0
      TEAMModelOS/ClientApp/src/common/PrivateTargetMultiple.vue
  43. 156 0
      TEAMModelOS/ClientApp/src/common/PrivateTargetSingle.vue
  44. 148 0
      TEAMModelOS/ClientApp/src/common/SchoolTarget.vue
  45. 2 2
      TEAMModelOS/ClientApp/src/components/homework/BaseHwForm.vue
  46. 5 5
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue
  47. 12 6
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  48. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.less
  49. 1 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue
  50. 0 42
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.css
  51. 0 19
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.vue
  52. 11 9
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/KeyPointPerformChart.vue
  53. 6 4
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/RecognizePerformChart.vue
  54. 0 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue
  55. 0 412
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseContent.vue
  56. 0 535
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseList.vue
  57. 25 46
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseListView.vue
  58. 1 1
      TEAMModelOS/ClientApp/src/components/syllabus/DragTree.vue
  59. 8 7
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  60. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/courseManage.js
  61. 14 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js
  62. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/jyzx.js
  63. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/teachermgmt.js
  64. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/courseManage.js
  65. 14 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/cusMgt.js
  66. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/jyzx.js
  67. 2 2
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/survey.js
  68. 5 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js
  69. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/courseManage.js
  70. 15 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js
  71. 1 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/jyzx.js
  72. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/teachermgmt.js
  73. 4 10
      TEAMModelOS/ClientApp/src/router/routes.js
  74. 2 1
      TEAMModelOS/ClientApp/src/store/module/answerSheet.js
  75. 44 1
      TEAMModelOS/ClientApp/src/utils/editorTools.js
  76. 2 0
      TEAMModelOS/ClientApp/src/utils/evTools.js
  77. 15 15
      TEAMModelOS/ClientApp/src/utils/html2pdf.js
  78. 0 76
      TEAMModelOS/ClientApp/src/utils/mockAnswer.js
  79. 115 79
      TEAMModelOS/ClientApp/src/utils/public.js
  80. 7 1
      TEAMModelOS/ClientApp/src/utils/sheetConfig.js
  81. 38 58
      TEAMModelOS/ClientApp/src/view/ability/Ability.vue
  82. 36 0
      TEAMModelOS/ClientApp/src/view/ability/GroupReview.less
  83. 416 0
      TEAMModelOS/ClientApp/src/view/ability/GroupReview.vue
  84. 1 1
      TEAMModelOS/ClientApp/src/view/ability/Review.vue
  85. 13 8
      TEAMModelOS/ClientApp/src/view/abilityMgmt/Index.vue
  86. 17 1
      TEAMModelOS/ClientApp/src/view/areaSetting/AreaSetting.vue
  87. 3 3
      TEAMModelOS/ClientApp/src/view/areatrain/TrainMgt.less
  88. 7 8
      TEAMModelOS/ClientApp/src/view/classmgt/ClassStudent.vue
  89. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue
  90. 3 1
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  91. 19 19
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  92. 65 12
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue
  93. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/DownloadPaper.vue
  94. 1 0
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less
  95. 36 14
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  96. 57 3
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue
  97. 4 4
      TEAMModelOS/ClientApp/src/view/homepage/MinTable.vue
  98. 1 1
      TEAMModelOS/ClientApp/src/view/homework/ManageHomeWork.vue
  99. 498 405
      TEAMModelOS/ClientApp/src/view/jyzx/application.vue
  100. 0 0
      TEAMModelOS/ClientApp/src/view/jyzx/offline.vue

+ 7 - 6
TEAMModeBI/Controllers/BIHome/StudyStatisController.cs

@@ -1,4 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -173,9 +173,9 @@ namespace TEAMModeBI.Controllers.BIHome
                     {
                         classVideos.Add(item);
                     }
-                    List<TchList> tchLists = new List<TchList>();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TchList>(queryText: $"select value(c) from c  ",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"TchList-{schoolitem.id}") }))
+                    List<GroupList> tchLists = new List<GroupList>();
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: $"select value(c) from c where c.type='research'  ",
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{schoolitem.id}") }))
                     {
                         groups.Add(item.name);
                         tchLists.Add(item);
@@ -187,7 +187,8 @@ namespace TEAMModeBI.Controllers.BIHome
                         ids.Add("default");
                     }
 
-                    (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{schoolitem.id}");
+                    (List<RMember> tmdInfos, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, ids, $"{school}");
+                    // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
                     //总人数
                     int teacherCount1 = tmdInfos.Count;
 
@@ -440,7 +441,7 @@ namespace TEAMModeBI.Controllers.BIHome
                         {
                             ok50TimeCount += 1;
                         }
-                        var classes = classInfos.Where(y => y.tmdInfos.Select(z => z.id).Contains(tmd.id)).ToList();
+                        var classes = classInfos.Where(y => y.members.Select(z => z.id).Contains(tmd.id)).ToList();
 
                         //表示有订阅,或者有线下活动参与的,或者有课堂实录视频上传的
                         if (subs.Count > 0 || schoolScoreTime > 0 || isJoinVideo)

+ 29 - 22
TEAMModelFunction/ActivityHttpTrigger.cs

@@ -72,8 +72,10 @@ namespace TEAMModelFunction
                     {
                         if (!string.IsNullOrEmpty(sc.stulist))
                         {
-                            (List<TmdInfo> tmdids, List<StuInfo> students, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string>() { sc.stulist }, course.school);
-                            foreach (var addStu in students)
+                            (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, new List<string>() { sc.stulist }, course.school);
+                            var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tchList.FindAll(x => x.type == 1);
+                            foreach (var addStu in addStudentsCls)
                             {
                                 var stuCourse = new StuCourse
                                 {
@@ -89,7 +91,7 @@ namespace TEAMModelFunction
                                 };
                                 await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stuCourse, new PartitionKey(stuCourse.code));
                             }
-                            foreach (var addTmd in tmdids)
+                            foreach (var addTmd in addTmdidsCls)
                             {
                                 var tmdCourse = new StuCourse
                                 {
@@ -153,12 +155,14 @@ namespace TEAMModelFunction
                     {
                         sub.Add(subject.id);
                     }
-                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, info.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, info.school);
+                    var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                     List<StuActivity> stuActivities = new List<StuActivity>();
                     List<StuActivity> tmdActivities = new List<StuActivity>();
-                    if (tmdids.IsNotEmpty())
+                    if (addTmdidsCls.IsNotEmpty())
                     {
-                        tmdids.ForEach(x => {
+                        addTmdidsCls.ForEach(x => {
                             tmdActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -182,9 +186,9 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    if (studentss.IsNotEmpty())
+                    if (addStudentsCls.IsNotEmpty())
                     {
-                        studentss.ForEach(x => {
+                        addStudentsCls.ForEach(x => {
                             stuActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -207,7 +211,7 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities,null);
+                    await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities,null);
                 }
             }
             return new OkObjectResult(new { });
@@ -253,13 +257,14 @@ namespace TEAMModelFunction
                     {
                         continue;
                     }
-
-                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, info.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, info.school);
+                    var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                     List<StuActivity> stuActivities = new List<StuActivity>();
                     List<StuActivity> tmdActivities = new List<StuActivity>();
-                    if (tmdids.IsNotEmpty())
+                    if (addTmdidsCls.IsNotEmpty())
                     {
-                        tmdids.ForEach(x => {
+                        addTmdidsCls.ForEach(x => {
                             tmdActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -283,9 +288,9 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    if (studentss.IsNotEmpty())
+                    if (addStudentsCls.IsNotEmpty())
                     {
-                        studentss.ForEach(x => {
+                        addStudentsCls.ForEach(x => {
                             stuActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -308,7 +313,7 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
+                    await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
                 }
             }
             return new OkObjectResult(new { });
@@ -354,12 +359,14 @@ namespace TEAMModelFunction
                     {
                         continue;
                     }
-                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, info.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, info.school);
+                    var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                     List<StuActivity> stuActivities = new List<StuActivity>();
                     List<StuActivity> tmdActivities = new List<StuActivity>();
-                    if (tmdids.IsNotEmpty())
+                    if (addTmdidsCls.IsNotEmpty())
                     {
-                        tmdids.ForEach(x => {
+                        addTmdidsCls.ForEach(x => {
                             tmdActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -383,9 +390,9 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    if (studentss.IsNotEmpty())
+                    if (addStudentsCls.IsNotEmpty())
                     {
-                        studentss.ForEach(x => {
+                        addStudentsCls.ForEach(x => {
                             stuActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
@@ -408,7 +415,7 @@ namespace TEAMModelFunction
                             });
                         });
                     }
-                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
+                    await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
                 }
             }
             return new OkObjectResult(new { });

+ 14 - 6
TEAMModelFunction/CourseServiceBus.cs

@@ -47,7 +47,9 @@ namespace TEAMModelFunction
                 }
                 foreach (var cls in courseChange.addClass)
                 {
-                    (List<TmdInfo> addTmdidsCls, List<StuInfo> addStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { cls }, courseChange.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, new List<string> { cls }, courseChange.school);
+                    var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                     foreach (var stu in addStudentsCls)
                     {
                         try
@@ -116,16 +118,18 @@ namespace TEAMModelFunction
 
                 foreach (var list in courseChange.addList)
                 {
-                    (List<TmdInfo> addTmdidsCls, List<StuInfo> addStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { list }, courseChange.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, new List<string> { list }, courseChange.school);
+                    var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                     foreach (var stu in addStudentsCls)
                     {
                         try
                         {
-                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{stu.schoolId}-{stu.id}"));
+                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{stu.code}-{stu.id}"));
                             if (!stuCourse.Value.stulist.Contains(list))
                             {
                                 stuCourse.Value.stulist.Add(list);
-                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{stu.schoolId}-{stu.id}"));
+                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{stu.code}-{stu.id}"));
                             }
                         }
                         catch (CosmosException ex)
@@ -186,7 +190,9 @@ namespace TEAMModelFunction
 
                 foreach (var delCls in courseChange.delClass)
                 {
-                    (List<TmdInfo> delTmdidsCls, List<StuInfo> delStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { delCls }, courseChange.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, new List<string> { delCls }, courseChange.school);
+                    var delStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var delTmdidsCls = tchList.FindAll(x => x.type == 1);
                     foreach (var stu in delStudentsCls)
                     {
                         try
@@ -244,7 +250,9 @@ namespace TEAMModelFunction
                 }
                 foreach (var delList in courseChange.delList)
                 {
-                    (List<TmdInfo> delTmdidsCls, List<StuInfo> delStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { delList }, courseChange.school);
+                    (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, new List<string> { delList }, courseChange.school);
+                    var delStudentsCls = tchList.FindAll(x => x.type == 2);
+                    var delTmdidsCls = tchList.FindAll(x => x.type == 1);
                     foreach (var stu in delStudentsCls)
                     {
                         try

+ 6 - 47
TEAMModelFunction/MonitorServicesBus.cs

@@ -355,47 +355,6 @@ namespace TEAMModelFunction
         ///// </data>
         /// <param name="msg"></param>
         /// <returns></returns>
-        [FunctionName("StuList")]
-        public async Task StuList([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "stulist", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
-        {
-            var client = _azureCosmos.GetCosmosClient();
-            try
-            {
-              
-                var jsonMsg = JsonDocument.Parse(msg);
-                ListChange stuListChange = msg.ToObject<ListChange>();
-                //名单变动修改学生课程关联信息
-                //await StuListService.FixStuCourse(client, stuListChange);
-                //Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
-                //名单变动修改学生问卷关联信息
-                await StuListService.FixActivity(client, _dingDing, stuListChange, "Survey");
-                //名单变动修改学生投票关联信息
-                await StuListService.FixActivity(client, _dingDing, stuListChange, "Vote");
-                //名单变动修改学生评测关联信息
-                await StuListService.FixActivity(client, _dingDing, stuListChange, "Exam");
-                //TODO学习活动
-                //await FixActivity(client, stuListChange, "Learn");
-                //TODO作业活动
-                await StuListService.FixActivity(client,_dingDing, stuListChange, "Homework");
-
-                if (stuListChange.type==null||!stuListChange.type.Equals("research")) {
-                    //课程名单变动修改学生课程关联信息
-                    await StuListService.FixStuCourse(client, _dingDing, stuListChange);
-                }
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListServiceBus-StuList\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.成都开发測試群組);
-            }
-        }
-        /// <summary>
-        /// 完善课程变更,StuListChange,  originCode是学校编码 则表示名单是学校自定义名单,如果是tmdid则表示醍摩豆的私有名单,scope=school,private。
-        /// </summary>
-        /// <data msg>
-        /// CourseChange
-        ///// </data>
-        /// <param name="msg"></param>
-        /// <returns></returns>
         [FunctionName("GroupChange")]
         public async Task GroupChange([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "group-change", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
         {
@@ -408,25 +367,25 @@ namespace TEAMModelFunction
                 //await StuListService.FixStuCourse(client, stuListChange);
                 //Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
                 //名单变动修改学生问卷关联信息
-                await GroupListService.FixActivity(client, _dingDing, groupChange, "Survey");
+                await ActivityService.FixActivity(client, _dingDing, groupChange, "Survey");
                 //名单变动修改学生投票关联信息
-                await GroupListService.FixActivity(client, _dingDing, groupChange, "Vote");
+                await ActivityService.FixActivity(client, _dingDing, groupChange, "Vote");
                 //名单变动修改学生评测关联信息
-                await GroupListService.FixActivity(client, _dingDing, groupChange, "Exam");
+                await ActivityService.FixActivity(client, _dingDing, groupChange, "Exam");
                 //TODO学习活动
                 //await FixActivity(client, stuListChange, "Learn");
                 //名单变动修改学生作业活动信息
-                await GroupListService.FixActivity(client, _dingDing, groupChange, "Homework");
+                await ActivityService.FixActivity(client, _dingDing, groupChange, "Homework");
 
                 if (groupChange.type == null || !groupChange.type.Equals("research"))
                 {
                     //课程名单变动修改学生课程关联信息
-                    await GroupListService.FixStuCourse(client, _dingDing, groupChange);
+                    await ActivityService.FixStuCourse(client, _dingDing, groupChange);
                 }
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListServiceBus-StuList\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupChange-GroupChange\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.成都开发測試群組);
             }
         }
         [FunctionName("ItemCond")]

+ 122 - 0
TEAMModelFunction/ScsApisHttpTrigger.cs

@@ -0,0 +1,122 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using TEAMModelOS.SDK.DI;
+using Azure.Cosmos;
+using System.Text.Json;
+using System.Collections.Generic;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using System.Linq;
+using TEAMModelOS.Services.Common;
+using TEAMModelOS.SDK.Models.Service;
+using HTEXLib.COMM.Helpers;
+
+
+namespace TEAMModelFunction
+{
+    public class ScsApisHttpTrigger
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly DingDing _dingDing;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly AzureRedisFactory _azureRedis;
+        private readonly ThirdApisService _thirdApisService;
+        public static string Code { get; set; }
+        public static Dictionary<string, object> parameterMap = null;
+        public ScsApisHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, ThirdApisService thirdApisService
+             , AzureRedisFactory azureRedis)
+        {
+            _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+            _azureStorage = azureStorage;
+            _azureRedis = azureRedis;
+            _thirdApisService = thirdApisService;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
+        [FunctionName("GetDiagnosisListByProject_V2")]
+        public async Task<IActionResult> GetDiagnosisListByProject_V2([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log) {
+            List<string> abilityNos = null;
+            string data = await new StreamReader(req.Body).ReadToEndAsync();
+            JsonElement accessConfig=  data.ToObject<JsonElement>().GetProperty("accessConfig");
+            JsonElement pxid = data.ToObject<JsonElement>().GetProperty("pxid");
+            ScAccessConfig config = $"{accessConfig}".ToObject<ScAccessConfig>();
+            Code = "GetDiagnosisListByProject_V2";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", config.trainComID);
+            //parameterMap.Add("ProjectID", "22");
+            //parameterMap.Add("ProjectItemID", "22");
+            parameterMap.Add("PXID", pxid);
+            ScsResult result = new ScsResult { code = Code, title = "5.3.1.3通过项目编号获取学员测评能力项V2" };
+            try
+            {
+                result = await _thirdApisService.Post(config.url, Code, config.passKey, config.privateKey, parameterMap);
+                if (result.result)
+                {
+                    List<ScDiagnosis> diagnoses = result.content.ToObject<List<ScDiagnosis>>();
+                    if (diagnoses != null)
+                    {
+                        abilityNos = diagnoses.Select(x => x.DiagnosisDicNum).ToList();
+                    }
+                }
+                return new  OkObjectResult(new { data= abilityNos .ToJsonString()});
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"IES5.ScApisService:getDiagnosisListByProject_V2\n{ex.Message}{ex.StackTrace}\n{result.ToJsonString()}", GroupNames.成都开发測試群組);
+                return new OkObjectResult(abilityNos);
+            }
+        }
+        /// <summary>
+        /// 5.3.1.11获取跳转学员信息,用于sso单点,后端验证。
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
+        [FunctionName("GetSingleTeacherByProject")]
+        public async Task<IActionResult> GetSingleTeacherByProject([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
+        {
+            string teacher=null;
+            string data = await new StreamReader(req.Body).ReadToEndAsync();
+            JsonElement accessConfig = data.ToObject<JsonElement>().GetProperty("accessConfig");
+            JsonElement pxid = data.ToObject<JsonElement>().GetProperty("pxid");
+            JsonElement tid = data.ToObject<JsonElement>().GetProperty("tid");
+            ScAccessConfig config = $"{accessConfig}".ToObject<ScAccessConfig>();
+            Code = "GetSingleTeacherByProject";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", config.trainComID);
+            parameterMap.Add("Pxid", $"{pxid}");
+            parameterMap.Add("Tid", $"{tid}");
+            ScsResult result = new ScsResult { code = Code, title = "5.3.1.11获取跳转学员信息,用于sso单点,后端验证。" };
+            try
+            {
+                ///{“result”:true,”reason”:null,”content”:”{“PXID”:””,”TID”:””,”TeacherName”:””,”ProjectTitle”:””,”ProjectItemTitle”:””,”CityName”:””,
+                ///”DisName”:””,”SchoolName”:””,”Sex”:””,”PXXK”:””,”PXXD”:””,”TeacherXK”:””,”TeacherXD”:””,”Email”:””}”,”pagecount”:1}
+                result = await _thirdApisService.Post(config.url, Code, config.passKey, config.privateKey, parameterMap);
+                if (result.result)
+                {
+                      teacher = result.content;
+                }
+                return new OkObjectResult(new {data= teacher });
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"IES5.ScApisService:GetSingleTeacherByProject\n{ex.Message}{ex.StackTrace}\n{result.ToJsonString()}", GroupNames.成都开发測試群組);
+                return new OkObjectResult(teacher);
+            }
+        }
+    }
+}

+ 2 - 0
TEAMModelFunction/Startup.cs

@@ -7,6 +7,7 @@ using System.Configuration;
 using System.IO;
 using System.Reflection;
 using System.Text;
+using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 
 [assembly: FunctionsStartup(typeof(TEAMModelFunction.Startup))]
@@ -18,6 +19,7 @@ namespace TEAMModelFunction
         { 
             builder.Services.AddHttpClient();
             builder.Services.AddHttpClient<DingDing>();
+            builder.Services.AddHttpClient<ThirdApisService>();
             builder.Services.AddAzureServiceBus(Environment.GetEnvironmentVariable("Azure:ServiceBus:ConnectionString"));
             builder.Services.AddAzureStorage(Environment.GetEnvironmentVariable("Azure:Storage:ConnectionString"));
             builder.Services.AddAzureCosmos(Environment.GetEnvironmentVariable("Azure:Cosmos:ConnectionString"));

+ 15 - 20
TEAMModelFunction/TriggerExam.cs

@@ -102,12 +102,14 @@ namespace TEAMModelFunction
                             try
                             {
                                 List<string> classes = ExamService.getClasses(info.classes, info.stuLists);
-                                (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, info.school);
+                                (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, info.school);
+                                var addStudentsCls = tchList.FindAll(x => x.type == 2);
+                                var addTmdidsCls = tchList.FindAll(x => x.type == 1);
                                 List<StuActivity> stuActivities = new List<StuActivity>();
                                 List<StuActivity> tmdActivities = new List<StuActivity>();
-                                if (tmdids.IsNotEmpty())
+                                if (addTmdidsCls.IsNotEmpty())
                                 {
-                                    tmdids.ForEach(x =>
+                                    addTmdidsCls.ForEach(x =>
                                     {
                                         tmdActivities.Add(new StuActivity
                                         {
@@ -133,9 +135,9 @@ namespace TEAMModelFunction
                                         });
                                     });
                                 }
-                                if (studentss.IsNotEmpty())
+                                if (addStudentsCls.IsNotEmpty())
                                 {
-                                    studentss.ForEach(x =>
+                                    addStudentsCls.ForEach(x =>
                                     {
                                         stuActivities.Add(new StuActivity
                                         {
@@ -160,7 +162,7 @@ namespace TEAMModelFunction
                                         });
                                     });
                                 }
-                                await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
+                                await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
                                 //向学生或醍摩豆账号发起通知
                                 #region
                                 //Notice notice = new Notice()
@@ -276,43 +278,36 @@ namespace TEAMModelFunction
                                             }
                                             if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
                                             {
-                                                var stuResponse = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList"));
+                                                var stuResponse = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"GroupList"));
                                                 if (stuResponse.Status == 200)
                                                 {
                                                     using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
-                                                    StuList stuList = json.ToObject<StuList>();
+                                                    GroupList stuList = json.ToObject<GroupList>();
                                                     //result.info.id = stuList.id;
                                                     result.info.name = stuList.name;
                                                     //处理发布对象为自选名单(个人)
 
-                                                    foreach (Students stus in stuList.students)
+                                                    foreach (Member stus in stuList.members)
                                                     {
 
                                                         if (!ids.Contains(stus.id))
                                                         {
                                                             ids.Add(stus.id);
                                                         }
-                                                    }
-                                                    if (stuList.tmids.Count > 0)
-                                                    {
-                                                        foreach (string tid in stuList.tmids)
-                                                        {
-                                                            ids.Add(tid);
-                                                        }
-                                                    }
+                                                    }                                           
                                                 }
                                             }
                                             else
                                             {
-                                                var stuResponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList-{info.school}"));
+                                                var stuResponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"GroupList-{info.school}"));
                                                 if (stuResponse.Status == 200)
                                                 {
                                                     using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
-                                                    StuList stuList = json.ToObject<StuList>();
+                                                    GroupList stuList = json.ToObject<GroupList>();
                                                     //result.info.id = stuList.id;
                                                     result.info.name = stuList.name;
                                                     //处理发布对象为自选名单(校本)
-                                                    foreach (Students stus in stuList.students)
+                                                    foreach (Member stus in stuList.members)
                                                     {
                                                         if (!ids.Contains(stus.id))
                                                         {

+ 4 - 2
TEAMModelFunction/TriggerExamLite.cs

@@ -70,7 +70,9 @@ namespace TEAMModelFunction
                             }
                             break;
                         case "going":
-                            (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, lite.tchLists, lite.school);
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, lite.tchLists, lite.school);
+                            // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
+                            //(List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, lite.tchLists, lite.school);
                             List<StuActivity> tchActivities = new List<StuActivity>();
 
                             if (tchList.IsNotEmpty())
@@ -99,7 +101,7 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, null, null, tchActivities);
+                            await ActivityService.SaveStuActivity(client, _dingDing, null, null, tchActivities);
                             var messageWorkEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                             messageWorkEnd.ApplicationProperties.Add("name", "ExamLite");
                             if (changeRecords.Count > 0)

+ 11 - 8
TEAMModelFunction/TriggerHomework.cs

@@ -72,13 +72,15 @@ namespace TEAMModelFunction
                             break;
                         case "going":
                             List<string> classes = ExamService.getClasses(work.classes, work.stuLists);
-                            (List<TmdInfo> tmdids, List<StuInfo> students, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, work.school);
+                            (List<RMember> tmdids, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, work.school);
+                            var addStudentsCls = tmdids.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tmdids.FindAll(x => x.type == 1);
                             List<StuActivity> stuActivities = new List<StuActivity>();
                             List<StuActivity> tmdActivities = new List<StuActivity>();
                             List<StuActivity> tchActivities = new List<StuActivity>();
-                            if (tmdids.IsNotEmpty())
+                            if (addTmdidsCls.IsNotEmpty())
                             {
-                                tmdids.ForEach(x =>
+                                addTmdidsCls.ForEach(x =>
                                 {
                                     tmdActivities.Add(new StuActivity
                                     {
@@ -102,9 +104,9 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            if (students.IsNotEmpty())
+                            if (addStudentsCls.IsNotEmpty())
                             {
-                                students.ForEach(x =>
+                                addStudentsCls.ForEach(x =>
                                 {
                                     stuActivities.Add(new StuActivity
                                     {
@@ -128,8 +130,9 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-
-                            (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, work.tchLists, work.school);
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, work.tchLists, work.school);
+                            // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
+                           // (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, work.tchLists, work.school);
                             if (tchList.IsNotEmpty())
                             {
                                 tchList.ForEach(x =>
@@ -156,7 +159,7 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+                            await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
 
                             var messageWorkEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                             messageWorkEnd.ApplicationProperties.Add("name", "Homework");

+ 4 - 2
TEAMModelFunction/TriggerStudy.cs

@@ -70,7 +70,9 @@ namespace TEAMModelFunction
                             }
                             break;
                         case "going":
-                            (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, study.tchLists, study.school);
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, study.tchLists, study.school);
+                            // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
+                            //(List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, study.tchLists, study.school);
                             List<StuActivity> tchActivities = new List<StuActivity>();
 
                             if (tchList.IsNotEmpty())
@@ -99,7 +101,7 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, null, null, tchActivities);
+                            await ActivityService.SaveStuActivity(client, _dingDing, null, null, tchActivities);
                             var messageWorkEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                             messageWorkEnd.ApplicationProperties.Add("name", "Study");
                             if (changeRecords.Count > 0)

+ 11 - 8
TEAMModelFunction/TriggerSurvey.cs

@@ -80,16 +80,18 @@ namespace TEAMModelFunction
                             break;
                         case "going":
                             List<string> classes = ExamService.getClasses(survey.classes, survey.stuLists);
-                            (List<TmdInfo> tmdids, List<StuInfo> students, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, survey.school);
+                            (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, survey.school);
+                            var addStudentsCls = tmdIds.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tmdIds.FindAll(x => x.type == 1);
 #if DEBUG
                             await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}写入学生表作为活动列表!", GroupNames.成都开发測試群組);
 #endif
                             List<StuActivity> stuActivities = new List<StuActivity>();
                             List<StuActivity> tmdActivities = new List<StuActivity>();
                             List<StuActivity> tchActivities = new List<StuActivity>();
-                            if (tmdids.IsNotEmpty())
+                            if (addTmdidsCls.IsNotEmpty())
                             {
-                                tmdids.ForEach(x => {
+                                addTmdidsCls.ForEach(x => {
                                     tmdActivities.Add(new StuActivity
                                     {
                                         pk = "Activity",
@@ -112,9 +114,9 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            if (students.IsNotEmpty())
+                            if (addStudentsCls.IsNotEmpty())
                             {
-                                students.ForEach(x => {
+                                addStudentsCls.ForEach(x => {
                                     stuActivities.Add(new StuActivity
                                     {
                                         pk = "Activity",
@@ -137,8 +139,9 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-
-                            (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, survey.tchLists, survey.school);
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, survey.tchLists, survey.school);
+                            // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
+                            //(List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, survey.tchLists, survey.school);
                             if (tchList.IsNotEmpty())
                             {
                                tchList.ForEach(x => {
@@ -164,7 +167,7 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+                            await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
                             //向学生或醍摩豆账号发起通知
                             #region
                             //Notice notice = new Notice()

+ 9 - 8
TEAMModelFunction/TriggerVote.cs

@@ -80,16 +80,18 @@ namespace TEAMModelFunction
                             break;
                         case "going":
                             List<string> classes = ExamService.getClasses(vote.classes, vote.stuLists);
-                            (List<TmdInfo> tmdids, List<StuInfo> students, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, classes, vote.school);
+                            (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, vote.school);
+                            var addStudentsCls = tmdIds.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tmdIds.FindAll(x => x.type == 1);
                             //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动" +
                             //    $"{tmdids.ToJsonString()}\n" +
                             //    $"{students.ToJsonString()}\n" +
                             //    $"{classLists.ToJsonString()}\n" +
                             //    $"{classes.ToJsonString()}\n", GroupNames.成都开发測試群組);
                             List<string> tmds = new List<string>();
-                            if (tmdids.IsNotEmpty())
+                            if (addTmdidsCls.IsNotEmpty())
                             {
-                                tmds.AddRange(tmdids.Select(x => x.id).ToList());
+                                tmds.AddRange(addTmdidsCls.Select(x => x.id).ToList());
                             }
                             List<StuActivity> stuActivities = new List<StuActivity>();
                             List<StuActivity> tmdActivities = new List<StuActivity>();
@@ -119,9 +121,9 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                            if (students.IsNotEmpty())
+                            if (addStudentsCls.IsNotEmpty())
                             {
-                                students.ForEach(x => {
+                                addStudentsCls.ForEach(x => {
                                     stuActivities.Add(new StuActivity
                                     {
                                         pk = "Activity",
@@ -144,8 +146,7 @@ namespace TEAMModelFunction
                                     });
                                 });
                             }
-                           
-                            (List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, vote.tchLists, vote.school);
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetStutmdidListids(client, _dingDing, vote.tchLists, vote.school);
                             if (tchList.IsNotEmpty())
                             {
                                 tchList.ForEach(x => {
@@ -174,7 +175,7 @@ namespace TEAMModelFunction
                             await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动,:教研组活动:" +
                              
                                $"{tchActivities.ToJsonString()}\n", GroupNames.成都开发測試群組);
-                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+                            await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
                             //向学生或醍摩豆账号发起通知
                             #region
                             //Notice notice = new Notice()

+ 82 - 0
TEAMModelOS.SDK/DI/HttpTrigger/HttpTrigger.cs

@@ -0,0 +1,82 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Net.Http;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+using System.Net.Http.Json;
+using System.Text.Json;
+using System.IO;
+using TEAMModelOS.SDK.Extension;
+using System.Net;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class HttpTrigger
+    {
+        private readonly HttpClient _httpClient;
+
+        public HttpTrigger(HttpClient httpClient)
+        {
+            _httpClient = httpClient;
+        }
+        // <summary>
+        /// 请求信息
+        /// </summary>
+        /// <param name="robotUrl">釘釘Robot發送Url</param>
+        /// <param name="secret">加簽密鑰</param>
+        /// <param name="msg">發送訊息</param>
+        /// <returns></returns>
+        public async Task<(int status,string json)> RequestHttpTrigger(object data, string location,string url)
+        {
+            var keys = HttpTriggerUrl.HttpTrigger地址.GetDescriptionText().Split(',');
+            string domain = "";
+            if (location.Equals("China-Dep"))
+            {
+                domain = keys[0];
+            }
+            else if (location.Equals("China-Test"))
+            {
+                domain = keys[1];
+            }
+            else if (location.Equals("China"))
+            {
+                domain = keys[2];
+            }
+            else if (location.Equals("Global-Dep"))
+            {
+                domain = keys[4];
+            }
+            else if (location.Equals("Global-Test"))
+            {
+                domain = keys[4];
+            }
+            else if (location.Equals("Global"))
+            {
+                domain = keys[5];
+            }
+            string link = domain.Contains("localhost") ? $"http://{domain}/api/{url}" : $"https://{domain}/api/{url}";
+            HttpResponseMessage responseMessage =await _httpClient.PostAsJsonAsync(link, data);
+            if (responseMessage.StatusCode == HttpStatusCode.OK)
+            {
+                string Content= await responseMessage.Content.ReadAsStringAsync();
+                Content.ToObject<JsonElement>().TryGetProperty("data", out JsonElement content);
+                return (200, $"{content}");
+            }
+            else
+            {
+                string Content = await responseMessage.Content?.ReadAsStringAsync();
+                return (500, Content);
+            }
+        }
+    }
+    public enum HttpTriggerUrl
+    {
+        [Description("localhost:7071,teammodelosfunction-test.chinacloudsites.cn,teammodelosfunction.chinacloudsites.cn,teammodelosfunction.chinacloudsites.cn,teammodelosfunction.chinacloudsites.cn")]
+        HttpTrigger地址,
+
+    }
+}

+ 2 - 3
TEAMModelOS/Controllers/Third/Helpers/AESHelper.cs

@@ -1,11 +1,10 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Security.Cryptography;
 using System.Text;
 using System.Threading.Tasks;
-
-namespace TEAMModelOS.Controllers
+namespace TEAMModelOS.SDK
 {
     public class AESHelper
     {

+ 16 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Bloblog.cs

@@ -22,4 +22,20 @@ namespace TEAMModelOS.SDK.Models
         public string type { get; set; }
 
     }
+    public class BlobInfo : CosmosEntity
+    {
+        public string name { get; set; }
+        public string url { get; set; }
+        public string md5 { get; set; }
+        public long time { get; set; }
+        public long size { get; set; }
+        public List<string> periodId { get; set; } = new List<string>() { "" };
+        public List<string> subjectId { get; set; } = new List<string>() { "" };
+        public List<string> gradeId { get; set; } = new List<string>() { "" };
+        /// <summary>
+        /// audio 音频,video 视频 ,doc文档,image图片,other 其他,res教材,thum缩略图,avatar 头像
+        /// </summary>
+        public string type { get; set; }
+
+    }
 }

+ 134 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/GroupList.cs

@@ -33,9 +33,70 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public int scount { get; set; }
         public List<Member> members { get; set; } = new List<Member>();
+        public string leader { get; set; }
+    }
+    public class RGroupList
+    {
+        public string id { get; set; }
+        public string code { get; set; }
+        public string pk { get; set; }
+        public int? ttl { get; set; } = -1;
+        public RGroupList()
+        {
+            pk = "GroupList";
+        }
+        public string name { get; set; }
+        //标记该名单唯一code
+        public string no { get; set; }
+        public string periodId { get; set; }
+        //课程id,需要标记则标记
+        //public string courseId { get; set; }
+        public string scope { get; set; }
+        public string school { get; set; }
+        public string creatorId { get; set; }
+        /// <summary>
+        ///教学班teach ,行政班(学生搜寻classId动态返回)class ,教研组research,学科组(学科搜寻动态返回)subject,好友friend,管理manage,群组group等
+        /// </summary>
+        public string type { get; set; } = "teach";
+        public int year { get; set; }
+        /// <summary>
+        /// 醍摩豆id成员数量
+        /// </summary>
+        public int tcount { get; set; }
+        /// <summary>
+        /// 校内账号成员数量
+        /// </summary>
+        public int scount { get; set; }
+        public List<RMember> members { get; set; } = new List<RMember>();
+        public string leader { get; set; }
+        
+    }
 
+    public class  Member
+    {
+        /// <summary>
+        /// 账号id
+        /// </summary>
+        public string id { get; set; }
+        //学生所在的学校
+        public string code { get; set; }
+        /// <summary>
+        ///类型 1 tmdid,2 student
+        /// </summary>
+        public int type { get; set; }
+        /// <summary>
+        ///座号
+        /// </summary>
+        public string no { get; set; }
+        /// <summary>
+        /// IRS WebIRS编号。
+        /// </summary>
+        public string irs { get; set; }
+        public string tag { get; set; }
+        public string groupId { get; set; }
+        public string groupName { get; set; }
     }
-    public class Member
+    public class RMember
     {
         /// <summary>
         /// 账号id
@@ -64,5 +125,77 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         public string irs { get; set; }
         public string tag { get; set; }
+        /// <summary>
+        /// 行政班
+        /// </summary>
+        public string classId { get; set; }
+        /// <summary>
+        /// 名单分组id
+        /// </summary>
+        public string groupId { get; set; }
+        /// <summary>
+        /// 名单分组名称
+        /// </summary>
+        public string groupName { get; set; }
+
+    }
+    public class GroupListDto
+    {
+        public string pk { get; set; }
+        public string id { get; set; }
+        public string code { get; set; }
+        public string name { get; set; }
+        //标记该名单唯一code
+        public string no { get; set; }
+        public string periodId { get; set; }
+        //课程id,需要标记则标记
+        //public string courseId { get; set; }
+        public string scope { get; set; }
+        public string school { get; set; }
+        public string creatorId { get; set; }
+        /// <summary>
+        ///教学班teach ,行政班(学生搜寻classId动态返回)class ,教研组research,学科组(学科搜寻动态返回)subject,好友friend,管理manage,群组group等
+        /// </summary>
+        public string type { get; set; } = "teach";
+        public int year { get; set; }
+        /// <summary>
+        /// 醍摩豆id成员数量
+        /// </summary>
+        public int tcount { get; set; }
+        /// <summary>
+        /// 校内账号成员数量
+        /// </summary>
+        public int scount { get; set; }
+        public string leader { get; set; }
+    }
+    public class CourseGroupList
+    {
+        public string scope { get; set; }
+        public string subject { get; set; }
+        public string period { get; set; }
+        public string name { get; set; }
+        public string id { get; set; }
+        public List<GroupListDto> groups { get; set; } = new List<GroupListDto>();
+    }
+    public class TeachCourse
+    {
+        public string scope { get; set; }
+
+        public IdName subject { get; set; }
+        public IdName period { get; set; }
+        public string name { get; set; }
+        public string id { get; set; }
+        public TeachSchedule schedule { get; set; }
+    }
+    public class TeachSchedule
+    {
+        public string classId { get; set; }
+        public string stulist { get; set; }
+        public string teacherId { get; set; }
+    }
+    public class IdName
+    {
+        public string id { get; set; }
+        public string name { get; set; }
     }
 }

+ 10 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Homework.cs

@@ -97,7 +97,17 @@ namespace TEAMModelOS.SDK.Models
         public int? status { get; set; } = 0;
         public long? size { get; set; } = 0;
         public string areaId { get; set; }
+        /// <summary>
+        /// 是否允许补交。 
+        /// </summary>
         public bool allowSupply { get; set; }
+        /// <summary>
+        /// 是否允许组长提交。1允许,0不允许。
+        /// </summary>
+        public int leaderSubmit { get; set; }
+        /// <summary>
+        /// 是否允许互评
+        /// </summary>
         public bool allowComment { get; set; }
         public List<string> extLimit { get; set; } = new List<string>();
         public List<Attachment> attachments { get; set; } = new List<Attachment>();

+ 4 - 0
TEAMModelOS.SDK/Models/Cosmos/School/AreaSetting.cs

@@ -54,5 +54,9 @@ namespace TEAMModelOS.SDK.Models
         /// 压缩包类型
         /// </summary>
         public List<string> gzip { get; set; } = new List<string>();
+        /// <summary>
+        /// 接入配置
+        /// </summary>
+        public string accessConfig { get; set; }
     }
 }

+ 1 - 1
TEAMModelOS.SDK/Models/Cosmos/School/SchoolTeacher.cs

@@ -12,7 +12,7 @@ namespace TEAMModelOS.SDK.Models
         public int size { get; set; }
         public string job { get; set; }
         public List<string> roles { get; set; } = new List<string>();
-        public List<string> permissions { get; set; }
+        public List<string> permissions { get; set; } = new List<string>();
         public string status { get; set; }
         public long createTime { get; set; }
         public string groupId { get; set; }

+ 2 - 1
TEAMModelOS.SDK/Models/Cosmos/Student/Student.cs

@@ -17,7 +17,8 @@ namespace TEAMModelOS.SDK.Models
         public string salt { get; set; }
         public int year { get; set; }
         //座位号
-        public string no { get; set; }
+        public string no { get; set; }   //座位号
+        public string irs { get; set; }
         //绑定班级Id
         public string classId { get; set; }
         //分组信息

+ 380 - 0
TEAMModelOS.SDK/Models/Service/ActivityService.cs

@@ -0,0 +1,380 @@
+using Azure;
+using Azure.Cosmos;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Service;
+using HTEXLib.COMM.Helpers;
+
+namespace TEAMModelOS.SDK
+{
+    public class ActivityService
+    {
+        public static async Task FixActivity(CosmosClient client, DingDing _dingDing, GroupChange groupChange, string type)
+        {
+            try
+            {
+                var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c  where  c.pk='{type}' " +
+                    $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}'))or ( array_contains(c.tchLists,'{groupChange.listid}')))";
+                //$"and A1 in('{groupChange.listid}') ";
+                List<MQActivity> datas = new List<MQActivity>();
+                if (groupChange.scope.Equals("school", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.school))
+                {
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.school}") }))
+                    {
+                        datas.Add(item);
+                    }
+                    ///还要处理该学校每个老师发布的班级的
+                    List<SchoolTeacher> teachers = new List<SchoolTeacher>();
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<SchoolTeacher>(queryText: $"SELECT c.id, c.name FROM c",
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{groupChange.school}") }))
+                    {
+                        teachers.Add(item);
+                    }
+                    foreach (var techer in teachers)
+                    {
+                        var queryTech = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c " +
+                            $" where c.school='{groupChange.school}'   and   c.pk='{type}'" +
+                            $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}')))";
+                        //  $" and A1 in('{groupChange.listid}') ";
+                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: queryTech,
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{techer.id}") }))
+                        {
+                            datas.Add(item);
+                        }
+                    }
+                }
+                if (groupChange.scope.Equals("private", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.creatorId))
+                {
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.creatorId}") }))
+                    {
+                        datas.Add(item);
+                    }
+                }
+                long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                foreach (MQActivity activity in datas)
+                {
+                    //已经完结的不再允许加入,还未开始的。
+                    if (activity.progress.Equals("finish") || activity.progress.Equals("pending"))
+                    {
+                        continue;
+                    }
+                    List<string> classes = ExamService.getClasses(activity.classes, activity.stuLists);
+                    //stujoin新加入名单的
+                    foreach (Member member in groupChange.stujoin)
+                    {
+                        var stucourse = new StuActivity
+                        {
+                            id = activity.id,
+                            scode = activity.code,
+                            name = activity.name,
+                            code = $"Activity-{member.code.Replace("Base-", "")}-{member.id}",
+                            scope = activity.scope,
+                            school = activity.school,
+                            creatorId = activity.creatorId,
+                            pk = "Activity",
+                            type = type,
+                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
+                            startTime = activity.startTime,
+                            endTime = activity.endTime,
+                            blob = activity.blob,
+                            owner = activity.owner,
+                            createTime = nowtime,
+                            taskStatus = -1,
+                            classIds = classes
+                        };
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                    }
+
+                    //tmdjoin新加入的
+                    foreach (Member member in groupChange.tmdjoin)
+                    {
+                        var stucourse = new StuActivity
+                        {
+                            id = activity.id,
+                            scode = activity.code,
+                            name = activity.name,
+                            code = $"Activity-{member.id}",
+                            scope = activity.scope,
+                            school = activity.school,
+                            creatorId = activity.creatorId,
+                            pk = "Activity",
+                            type = type,
+                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
+                            startTime = activity.startTime,
+                            endTime = activity.endTime,
+                            blob = activity.blob,
+                            owner = activity.owner,
+                            createTime = nowtime,
+                            taskStatus = -1,
+                            classIds = classes
+                        };
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                    }
+                    //tchjoin新加入的
+                    foreach (Member member in groupChange.tchjoin)
+                    {
+                        var stucourse = new StuActivity
+                        {
+                            id = activity.id,
+                            scode = activity.code,
+                            name = activity.name,
+                            code = $"Activity-{member.id}",
+                            scope = activity.scope,
+                            school = activity.school,
+                            creatorId = activity.creatorId,
+                            pk = "Activity",
+                            type = type,
+                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
+                            startTime = activity.startTime,
+                            endTime = activity.endTime,
+                            blob = activity.blob,
+                            owner = activity.owner,
+                            createTime = nowtime,
+                            taskStatus = -1,
+                            classIds = classes
+                        };
+                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                    }
+                    foreach (Member member in groupChange.stuleave)
+                    {
+                        try
+                        {
+
+                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.code.Replace("Base-", "")}-{member.id}"));
+                        }
+                        catch (CosmosException)
+                        {
+                            continue;
+                            // 继续执行 删除失败
+                        }
+                    }
+                    foreach (Member member in groupChange.tmdleave)
+                    {
+                        try
+                        {
+
+                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
+                        }
+                        catch (CosmosException)
+                        {
+                            continue;
+                            // 继续执行 删除失败
+                        }
+                    }
+                    foreach (Member member in groupChange.tchleave)
+                    {
+                        try
+                        {
+                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
+                        }
+                        catch (CosmosException)
+                        {
+                            continue;
+                            // 继续执行 删除失败
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixActivity\n{ex.Message}{ex.StackTrace}{groupChange.ToJsonString()}{type}", GroupNames.醍摩豆服務運維群組);
+            }
+        }
+        public static async Task FixStuCourse(CosmosClient client, DingDing _dingDing, GroupChange groupChange)
+        {
+            //1.查找学校或教师的课程是否包含该名单的课程。
+            var query = $"select distinct c.code,c.id,c.no,c.name,c.scope, c.creatorId,c.school from c join A0 in c.schedule where A0.stulist = '{groupChange.listid}'";
+            List<Course> courses = new List<Course>();
+            if (groupChange.scope.Equals("school") && !string.IsNullOrEmpty(groupChange.school))
+            {
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.school}") }))
+                {
+                    courses.Add(item);
+                }
+            }
+            if (groupChange.scope.Equals("private") && !string.IsNullOrEmpty(groupChange.creatorId))
+            {
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.creatorId}") }))
+                {
+                    courses.Add(item);
+                }
+            }
+            long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 需要处理的课程\n{courses.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
+            foreach (var course in courses)
+            {
+                //学生新加入名单的
+                foreach (Member member in groupChange.stujoin)
+                {
+                    var stucourse = new StuCourse
+                    {
+                        id = course.id,
+                        scode = course.code,
+                        name = course.name,
+                        code = $"StuCourse-{member.code.Replace("Base-", "")}-{member.id}",
+                        scope = course.scope,
+                        school = course.school,
+                        creatorId = course.creatorId,
+                        pk = "StuCourse",
+                        stulist = new List<string> { groupChange.listid },
+                        createTime = nowtime
+                    };
+                    // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }
+                //tmd新加入的
+                foreach (Member member in groupChange.tmdjoin)
+                {
+                    var stucourse = new StuCourse
+                    {
+                        id = course.id,
+                        scode = course.code,
+                        name = course.name,
+                        code = $"StuCourse-{member.id}",
+                        scope = course.scope,
+                        school = course.school,
+                        creatorId = course.creatorId,
+                        pk = "StuCourse",
+                        stulist = new List<string> { groupChange.listid },
+                        createTime = nowtime
+                    };
+                    // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }
+                //移除名单的。 在点击相关的课程,再去二次校验是否存在,不存在则再去删除。
+                foreach (var delStu in groupChange.stuleave)
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delStu.code.Replace("Base-", "")}-{delStu.id}"));
+                }
+                foreach (var delTmd in groupChange.tmdleave)
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delTmd}"));
+                }
+            }
+        }
+        public static async Task<string> SaveStuActivity(CosmosClient client, DingDing _dingDing, List<StuActivity> stuActivities, List<StuActivity> tmdActivities, List<StuActivity> tchActivities)
+        {
+            try
+            {
+                if (stuActivities.IsNotEmpty())
+                {
+                    foreach (var x in stuActivities)
+                    {
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(x, new PartitionKey(x.code));
+                    }
+                }
+                if (tmdActivities.IsNotEmpty())
+                {
+                    foreach (var x in tmdActivities)
+                    {
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(x, new PartitionKey(x.code));
+                    }
+                }
+                if (tchActivities.IsNotEmpty())
+                {
+                    foreach (var x in tchActivities)
+                    {
+                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(x, new PartitionKey(x.code));
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-SaveStuActivity\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+            }
+            return "";
+        }
+        public static async Task RefreshStuActivity(CosmosClient client, DingDing _dingDing, string id, string code)
+        {
+            MQActivity activity = null;
+            try
+            {
+                var aactivity = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync(id, new Azure.Cosmos.PartitionKey(code));
+                using var da = await JsonDocument.ParseAsync(aactivity.ContentStream);
+                activity = da.ToObject<MQActivity>();
+            }
+            catch (CosmosException)
+            {
+                activity = null;
+            }
+            if (activity != null)
+            {
+                List<string> classes = ExamService.getClasses(activity.classes, activity.stuLists);
+                (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(client, _dingDing, classes, activity.school);
+                var students = tmdIds.FindAll(x => x.type == 2);
+                var tmdids = tmdIds.FindAll(x => x.type == 1);
+                if (tmdids.IsNotEmpty())
+                {
+                    foreach (RMember tmdid in tmdids)
+                    {
+                        var stucourse = new StuActivity
+                        {
+                            id = activity.id,
+                            scode = activity.code,
+                            name = activity.name,
+                            code = $"Activity-{tmdid.id}",
+                            source = activity.source,
+                            scope = activity.scope,
+                            school = activity.school,
+                            creatorId = activity.creatorId,
+                            pk = "Activity",
+                            type = activity.pk,
+                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
+                            startTime = activity.startTime,
+                            endTime = activity.endTime,
+                            blob = activity.blob,
+                            owner = activity.owner,
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                            taskStatus = -1,
+                            classIds = classes
+                        };
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                    }
+                }
+                if (students.IsNotEmpty())
+                {
+                    foreach (RMember student in students)
+                    {
+                        var stucourse = new StuActivity
+                        {
+                            id = activity.id,
+                            scode = activity.code,
+                            name = activity.name,
+                            code = $"Activity-{activity.school}-{student.id}",
+                            scope = activity.scope,
+                            source = activity.source,
+                            school = activity.school,
+                            creatorId = activity.creatorId,
+                            pk = "Activity",
+                            type = activity.pk,
+                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
+                            startTime = activity.startTime,
+                            endTime = activity.endTime,
+                            blob = activity.blob,
+                            owner = activity.owner,
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                            taskStatus = -1,
+                            classIds = classes
+                        };
+                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                    }
+                }
+            }
+        }
+    }
+}

+ 272 - 358
TEAMModelOS.SDK/Models/Service/GroupListService.cs

@@ -12,8 +12,9 @@ using System.Text.Json;
 using TEAMModelOS.Models;
 using Azure.Messaging.ServiceBus;
 using Microsoft.Extensions.Configuration;
+using TEAMModelOS.SDK.Models.Service;
 
-namespace TEAMModelOS.SDK.Models.Service
+namespace TEAMModelOS.SDK.Models
 {
     public class GroupListService
     {
@@ -59,7 +60,7 @@ namespace TEAMModelOS.SDK.Models.Service
                     else
                     {
                         status = 0;
-                        stuList.members.Add(new Member { id = userid, name = name, no = no, picture = picture, type = type });
+                        stuList.members.Add(new Member { id = userid,  no = no,type = type });
                     }
                 }
                 else if (type == 2)
@@ -73,7 +74,7 @@ namespace TEAMModelOS.SDK.Models.Service
                     else
                     {
                         status = 0;
-                        stuList.members.Add(new Member { id = userid, code = school, name = name, no = no, picture = picture, type = type });
+                        stuList.members.Add(new Member { id = userid, code = school,  no = no, type = type });
                     }
                 }
             }
@@ -173,23 +174,25 @@ namespace TEAMModelOS.SDK.Models.Service
                     else
                     {
                         //离开的
-                        var tmdids = oldList.members.FindAll(x => x.type == 1);
-                        if (tmdids.IsNotEmpty())
-                        {
-                            if (list.type.Equals("research"))
+                        if (oldList != null) {
+                            var tmdids = oldList.members.FindAll(x => x.type == 1);
+                            if (tmdids.IsNotEmpty())
                             {
-                                change.tchleave.AddRange(tmdids);
+                                if (list.type.Equals("research"))
+                                {
+                                    change.tchleave.AddRange(tmdids);
+                                }
+                                else
+                                {
+                                    change.tmdleave.AddRange(tmdids);
+                                }
                             }
-                            else
+                            var stuids = oldList.members.FindAll(x => x.type == 2);
+                            if (stuids.IsNotEmpty())
                             {
-                                change.tmdleave.AddRange(tmdids);
+                                change.stuleave.AddRange(stuids);
                             }
                         }
-                        var stuids = oldList.members.FindAll(x => x.type == 2);
-                        if (stuids.IsNotEmpty())
-                        {
-                            change.stuleave.AddRange(stuids);
-                        }
                     }
                 }
                 if (change.tmdjoin.Count != 0 || change.tmdleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0
@@ -273,16 +276,100 @@ namespace TEAMModelOS.SDK.Models.Service
             }
             return list;
         }
-        public static async Task<List<GroupList>> GetStutmdidListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school)
+        public static async Task<List<GroupListDto> > GetGroupListListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school,string SummarySql) {
+            List<GroupListDto> groupLists = null;
+            if (classes.Count == 1 && classes.First().Equals("default") && !string.IsNullOrEmpty(school))
+            {
+                //默认的教研组
+
+                GroupListDto groupList = new GroupListDto
+                {
+                    id = "default",
+                    name = "default",
+                    code = $"GroupList-{school}",
+                    school = school,
+                    scope = "school",
+                    type = "research",
+                };
+                groupLists = new List<GroupListDto> { groupList };
+            }
+            else
+            {
+                Dictionary<string, List<GroupListDto>> groups = new Dictionary<string, List<GroupListDto>>();
+                //List<Student> students = new List<Student>();
+                string sql = string.Join(",", classes.Select(x => $"'{x}'"));
+                if (!string.IsNullOrEmpty(school))
+                {
+                    List<GroupListDto> schoolList = new List<GroupListDto>();
+
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupListDto>(queryText: $"select {SummarySql} from c where c.id in ({sql})",
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
+                    {
+                        schoolList.Add(item);
+                    }
+                    if (schoolList.IsNotEmpty())
+                    {
+                        groups.Add("School", schoolList);
+                    }
+                    //取差集,减少二次搜寻
+                    classes = classes.Except(schoolList.Select(y => y.id)).ToList();
+                    if (classes.IsNotEmpty())
+                    {
+                        string insql = string.Join(",", classes.Select(x => $"'{x}'"));
+                        //搜寻没有关联学生的行政班
+                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupListDto>(queryText: $"select   c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
+                                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
+                        {
+                            ///行政班(学生搜寻classId动态返回)class
+                            GroupListDto group = new GroupListDto
+                            {
+                                id = item.id,
+                                code = $"GroupList-{school}",
+                                name = item.name,
+                                periodId = item.periodId,
+                                scope = "school",
+                                school = school,
+                                type = "class",
+                                year = item.year,
+                                leader= item.leader,
+                                no= item.no,
+                                pk= "GroupList",
+                            };
+                            groupLists.Add(group);
+                        }
+                        //取差集,减少二次搜寻
+                        classes = classes.Except(groupLists.Select(y => y.id)).ToList();
+                    }
+                }
+                if (classes.IsNotEmpty())
+                {
+                    List<GroupListDto> privateList = new List<GroupListDto>();
+                    sql = string.Join(",", classes.Select(x => $"'{x}'"));
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupListDto>(queryText: $"select {SummarySql} from c where c.id in ({sql})",
+                           requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
+                    {
+                        privateList.Add(item);
+                    }
+                    if (privateList.IsNotEmpty())
+                    {
+                        groups.Add("Teacher", privateList);
+                    }
+                }
+                groupLists = groups.SelectMany(x => x.Value).ToList();
+            }
+            return groupLists;
+        }
+        public static async Task<(List<RMember>, List<RGroupList> groups)> GetStutmdidListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school)
         {
-            List<GroupList> groupLists = null;
+            List<RMember> members = new List<RMember>();
+            List<RGroupList> groupLists = new List<RGroupList>();
             if (classes.Count == 1 && classes.First().Equals("default") && !string.IsNullOrEmpty(school))
             {
                 //默认的教研组
-                List<Member> members = new List<Member>();
+                members = new List<RMember>();
                 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdInfo>(queryText: $"SELECT  value(c) FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
                 {
-                    Member member = new Member
+                    RMember member = new RMember
                     {
                         id = item.id,
                         name = item.name,
@@ -291,7 +378,7 @@ namespace TEAMModelOS.SDK.Models.Service
                     };
                     members.Add(member);
                 }
-                GroupList groupList = new GroupList
+                RGroupList groupList = new RGroupList
                 {
                     id = "default",
                     name = "default",
@@ -301,18 +388,18 @@ namespace TEAMModelOS.SDK.Models.Service
                     type = "research",
                     members = members
                 };
-                groupLists = new List<GroupList> { groupList };
+                groupLists = new List<RGroupList> { groupList };
             }
             else
             {
-                Dictionary<string, List<GroupList>> groups = new Dictionary<string, List<GroupList>>();
+                Dictionary<string, List<RGroupList>> groups = new Dictionary<string, List<RGroupList>>();
                 List<Student> students = new List<Student>();
                 string sql = string.Join(",", classes.Select(x => $"'{x}'"));
                 if (!string.IsNullOrEmpty(school))
                 {
-                    List<GroupList> schoolList = new List<GroupList>();
+                    List<RGroupList> schoolList = new List<RGroupList>();
 
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: $"select value(c) from c where c.id in ({sql})",
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<RGroupList>(queryText: $"select value(c) from c where c.id in ({sql})",
                             requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") }))
                     {
                         schoolList.Add(item);
@@ -334,12 +421,43 @@ namespace TEAMModelOS.SDK.Models.Service
                         //取差集,减少二次搜寻
                         classes = classes.Except(students.Select(y => y.classId)).ToList();
                     }
+                    if (classes.IsNotEmpty()) {
+                        string insql = string.Join(",", classes.Select(x => $"'{x}'"));
+                        //搜寻没有关联学生的行政班
+                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School")
+                            .GetItemQueryIterator<RGroupList>(queryText: $"select  c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
+                                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
+                        {
+                            ///行政班(学生搜寻classId动态返回)class
+                            List<RMember> smembers = new List<RMember>();
+                            RGroupList group = new RGroupList
+                            {
+                                id = item.id,
+                                code = $"GroupList-{school}",
+                                name = item.name,
+                                periodId = item.periodId,
+                                scope = "school",
+                                school = school,
+                                type = "class",
+                                year = item.year,
+                                members = smembers,
+                                scount = smembers.Count,
+                                pk= "GroupList",
+                                leader=item.leader,
+                                no=item.no,
+                            };
+                            groupLists.Add(group);
+                        }
+                        //取差集,减少二次搜寻
+                        classes = classes.Except(groupLists.Select(y => y.id)).ToList();
+                    }
+                   
                 }
                 if (classes.IsNotEmpty())
                 {
-                    List<GroupList> privateList = new List<GroupList>();
+                    List<RGroupList> privateList = new List<RGroupList>();
                     sql = string.Join(",", classes.Select(x => $"'{x}'"));
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupList>(queryText: $"select value(c) from c where c.id in ({sql})",
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<RGroupList>(queryText: $"select value(c) from c where c.id in ({sql})",
                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") }))
                     {
                         privateList.Add(item);
@@ -354,20 +472,37 @@ namespace TEAMModelOS.SDK.Models.Service
                     var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() });
                     foreach (var group in list)
                     {
-                        await GetGroupListMemberInfo(client, group.key, group.list, item.Key);
+                        (List<RGroupList> rgroups, List<RMember> rmembers)  =await GetGroupListMemberInfo(client, group.key, group.list, item.Key,_dingDing);
+                        members.AddRange(rmembers);
                     }
                 }
-                groupLists = groups.SelectMany(x => x.Value).ToList();
+                groupLists .AddRange(groups.SelectMany(x => x.Value).ToList());
                 if (students.IsNotEmpty())
                 {
                     List<string> sqlList = students.Select(x => x.classId).ToList();
                     string insql = string.Join(",", sqlList.Select(x => $"'{x}'"));
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name ,c.periodId  ,c.year from c where c.id in ({insql})",
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").
+                        GetItemQueryIterator<RGroupList>(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})",
                               requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
                     {
                         ///行政班(学生搜寻classId动态返回)class
-                        List<Member> members = students.Where(x => x.classId.Equals(item.id)).Select(y => new Member { id = y.id, code = school, name = y.name, type = 2, picture = y.picture, no = y.no }).ToList();
-                        GroupList group = new GroupList
+                        List<RMember> smembers = students.Where(x => x.classId.Equals(item.id))
+                            .Select(y => new RMember 
+                            {
+                                id = y.id,
+                                code = school, 
+                                name = y.name,
+                                type = 2, 
+                                picture = y.picture,
+                                no = y.no,
+                                classId=y.classId,
+                                groupId=y.groupId,
+                                groupName=y.groupName ,
+                                irs=y.irs,
+                            }).ToList();
+                        members.AddRange(smembers);
+                       
+                        RGroupList group = new RGroupList
                         {
                             id = item.id,
                             code = $"GroupList-{school}",
@@ -377,376 +512,155 @@ namespace TEAMModelOS.SDK.Models.Service
                             school = school,
                             type = "class",
                             year = item.year,
-                            members = members,
-                            scount = members.Count
+                            members = smembers,
+                            scount = smembers.Count,
+                            no=item.no,
+                            leader=item.leader,
+                            pk= "GroupList"
                         };
                         groupLists.Add(group);
                     }
+                    //去重。
+                    members = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
                 }
             }
-            return groupLists;
+            return (members,groupLists);
         }
 
-        public static async Task<(List<GroupList> groups, List<Member> members)> GetGroupListMemberInfo(CosmosClient client, string type, List<GroupList> groups, string groupTbname)
+        public static async Task<(List<RGroupList> groups, List<RMember> members)> GetGroupListMemberInfo(CosmosClient client, string type, List<RGroupList> groups, string groupTbname, DingDing _dingDing)
         {
 
-            var members = groups.SelectMany(y => y.members).ToList();
-            //去重
-            List<Member> tmids = members.FindAll(x => x.type == 1).Where((x, i) => members.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList();
-            List<Member> students = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
-            var stu = students.GroupBy(x => x.code).Select(y => new { key = y.Key, list = y.ToList() });
-            List<Student> studentsData = new List<Student>();
-            if (stu != null)
-            {
-                foreach (var item in stu)
+            try {
+                var members = groups.SelectMany(y => y.members).ToList();
+                //去重
+                List<RMember> tmdids = members.FindAll(x => x.type == 1).Where((x, i) => members.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList();
+                List<RMember> students = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList();
+                var stu = students.GroupBy(x => x.code).Select(y => new { key = y.Key, list = y.ToList() });
+                List<Student> studentsData = new List<Student>();
+                if (stu != null)
                 {
-                    var ids = item.list.Select(x => x.id).ToList();
-                    if (ids.IsNotEmpty())
+                    foreach (var item in stu)
                     {
-                        StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no FROM c ");
-                        string insql = string.Join(",", ids.Select(x => $"'{x}'"));
-                        stuSql.Append($"c.id in ({insql})");
-                        await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: stuSql.ToString(),
-                            requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{item.key}") }))
+                        var ids = item.list.Select(x => x.id).ToList();
+                        if (ids.IsNotEmpty())
                         {
-                            studentsData.Add(student);
+                            StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no,c.irs,c.classId FROM c ");
+                            string insql = string.Join(",", ids.Select(x => $"'{x}'"));
+                            stuSql.Append($"where  c.id in ({insql})");
+                            await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: stuSql.ToString(),
+                                requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{item.key}") }))
+                            {
+                                student.schoolId = item.key;
+                                studentsData.Add(student);
+                            }
                         }
                     }
                 }
-            }
-            List<TmdUser> tmdsData = new List<TmdUser>();
-            if (tmids.IsNotEmpty())
-            {
-                string memberTbname = "";
-                //可能会出现在两种表中
-                if ($"{type}".Equals("teach") || $"{type}".Equals("research") || $"{type}".Equals("group")
-                    || $"{type}".Equals("friend") || $"{type}".Equals("manage") || $"{type}".Equals("subject"))
+                List<TmdUser> tmdsData = new List<TmdUser>();
+                if (tmdids.IsNotEmpty())
                 {
-                    StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
-                    string insql = string.Join(",", tmids.Select(x => $"'{x.id}'"));
-                    tmdidSql.Append($" where  c.id in ({insql})");
-                    memberTbname = "Teacher";
-                    await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
-                            requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                    {
-                        tmdsData.Add(tmd);
-                    }
-                }
-                if ($"{type}".Equals("teach") || $"{type}".Equals("friend") || $"{type}".Equals("group"))
-                {
-                    //取差集,减少二次搜寻
-                    var tmdidexp = tmids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
-                    if (tmdidexp.IsNotEmpty())
+                    string memberTbname = "";
+                    //可能会出现在两种表中
+                    if ($"{type}".Equals("teach") || $"{type}".Equals("research") || $"{type}".Equals("group")
+                        || $"{type}".Equals("friend") || $"{type}".Equals("manage") || $"{type}".Equals("subject"))
                     {
                         StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
-                        string insql = string.Join(",", tmdidexp.Select(x => $"'{x}'"));
+                        string insql = string.Join(",", tmdids.Select(x => $"'{x.id}'"));
                         tmdidSql.Append($" where  c.id in ({insql})");
-
-                        memberTbname = "Student";
+                        memberTbname = "Teacher";
                         await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
                                 requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
                         {
                             tmdsData.Add(tmd);
                         }
                     }
-                }
-                //去重
-                tmdsData = tmdsData.Where((x, i) => tmdsData.FindIndex(n => n.id.Equals(x.id)) == i).ToList();
-            }
-            HashSet<GroupList> changes = new HashSet<GroupList>();
-            var unexist_tmdid = tmids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
-            groups.ForEach(x =>
-            {
-                int item = x.members.RemoveAll(y => unexist_tmdid.Contains(y.id) && y.type == 1);
-                if (item > 0)
-                {
-                    changes.Add(x);
-                }
-            });
-            var unexist_student = students.Select(x => (x.id, x.code)).Except(studentsData.Select(y => (y.id, y.code)), new CompareIdCode()).ToList();
-            groups.ForEach(x =>
-            {
-                int item = x.members.RemoveAll(y => y.type == 2 && unexist_student.Exists(x => x.id.Equals(y.id) && x.code.Equals(y.code)));
-                if (item > 0)
-                {
-                    changes.Add(x);
-                }
-            });
-            if (changes.Count > 0 && !string.IsNullOrEmpty(groupTbname))
-            {
-                foreach (var change in changes)
-                {
-                    change.tcount = change.members.Where(x => x.type == 1).Count();
-                    change.scount = change.members.Where(x => x.type == 2).Count();
-                    await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(change, change.id, new PartitionKey(change.code));
-                }
-            }
-            tmids.ForEach(x =>
-            {
-                var user = tmdsData.Find(y => y.id.Equals(x.id));
-                x.name = user?.name;
-                x.picture = user?.picture;
-            });
-            students.ForEach(x =>
-            {
-                var student = studentsData.Find(y => y.id.Equals(x.id) && y.code.Equals(x.code));
-                x.name = student?.name;
-                x.picture = student?.picture;
-                x.no = student?.no;
-            });
-            var mbs = tmids;
-            mbs.AddRange(students);
-            return (groups, mbs);
-        }
-
-        public static async Task FixActivity(CosmosClient client, DingDing _dingDing, GroupChange groupChange, string type)
-        {
-            try
-            {
-                var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c  where  c.pk='{type}' " +
-                    $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}'))or ( array_contains(c.tchLists,'{groupChange.listid}')))";
-                //$"and A1 in('{groupChange.listid}') ";
-                List<MQActivity> datas = new List<MQActivity>();
-                if (groupChange.scope.Equals("school", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.school))
-                {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.school}") }))
-                    {
-                        datas.Add(item);
-                    }
-                    ///还要处理该学校每个老师发布的班级的
-                    List<SchoolTeacher> teachers = new List<SchoolTeacher>();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<SchoolTeacher>(queryText: $"SELECT c.id, c.name FROM c",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{groupChange.school}") }))
-                    {
-                        teachers.Add(item);
-                    }
-                    foreach (var techer in teachers)
+                    if ($"{type}".Equals("teach") || $"{type}".Equals("friend") || $"{type}".Equals("group"))
                     {
-                        var queryTech = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c " +
-                            $" where c.school='{groupChange.school}'   and   c.pk='{type}'" +
-                            $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}')))";
-                        //  $" and A1 in('{groupChange.listid}') ";
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: queryTech,
-                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{techer.id}") }))
+                        //取差集,减少二次搜寻
+                        var tmdidexp = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
+                        if (tmdidexp.IsNotEmpty())
                         {
-                            datas.Add(item);
+                            StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c ");
+                            string insql = string.Join(",", tmdidexp.Select(x => $"'{x}'"));
+                            tmdidSql.Append($" where  c.id in ({insql})");
+
+                            memberTbname = "Student";
+                            await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(queryText: tmdidSql.ToString(),
+                                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
+                            {
+                                tmdsData.Add(tmd);
+                            }
                         }
                     }
+                    //去重
+                    tmdsData = tmdsData.Where((x, i) => tmdsData.FindIndex(n => n.id.Equals(x.id)) == i).ToList();
                 }
-                if (groupChange.scope.Equals("private", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.creatorId))
+                HashSet<RGroupList> changes = new HashSet<RGroupList>();
+                var unexist_tmdid = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList();
+                groups.ForEach(x =>
                 {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.creatorId}") }))
+                    int item = x.members.RemoveAll(y => unexist_tmdid.Contains(y.id) && y.type == 1);
+                    if (item > 0)
                     {
-                        datas.Add(item);
+                        changes.Add(x);
                     }
-                }
-                long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-                foreach (MQActivity activity in datas)
+                });
+                var unexist_student = students.Select(x => (x.id, x.code)).Except(studentsData.Select(y => (y.id, y.schoolId)), new CompareIdCode()).ToList();
+                groups.ForEach(x =>
                 {
-                    //已经完结的不再允许加入,还未开始的。
-                    if (string.IsNullOrEmpty(activity.progress)|| activity.progress.Equals("finish") || activity.progress.Equals("pending"))
-                    {
-                        continue;
-                    }
-                    List<string> classes = ExamService.getClasses(activity.classes, activity.stuLists);
-                    //stujoin新加入名单的
-                    foreach (Member member in groupChange.stujoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{member.code.Replace("Base-", "")}-{member.id}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = nowtime,
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-
-                    //tmdjoin新加入的
-                    foreach (Member member in groupChange.tmdjoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{member.id}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = nowtime,
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                    //tchjoin新加入的
-                    foreach (Member member in groupChange.tchjoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{member.id}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = nowtime,
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                    foreach (Member member in groupChange.stuleave)
-                    {
-                        try
-                        {
-
-                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.code.Replace("Base-", "")}-{member.id}"));
-                        }
-                        catch (CosmosException)
-                        {
-                            continue;
-                            // 继续执行 删除失败
-                        }
-                    }
-                    foreach (Member member in groupChange.tmdleave)
+                    int item = x.members.RemoveAll(y => y.type == 2 && unexist_student.Exists(x => x.id.Equals(y.id) && x.Item2.Equals(y.code)));
+                    if (item > 0)
                     {
-                        try
-                        {
-
-                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
-                        }
-                        catch (CosmosException)
-                        {
-                            continue;
-                            // 继续执行 删除失败
-                        }
+                        changes.Add(x);
                     }
-                    foreach (Member member in groupChange.tchleave)
-                    {
-                        try
-                        {
-                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
-                        }
-                        catch (CosmosException)
-                        {
-                            continue;
-                            // 继续执行 删除失败
-                        }
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n{ex.Message}{ex.StackTrace}{groupChange.ToJsonString()}{type}", GroupNames.醍摩豆服務運維群組);
-            }
-        }
-        public static async Task FixStuCourse(CosmosClient client, DingDing _dingDing, GroupChange groupChange)
-        {
-            //1.查找学校或教师的课程是否包含该名单的课程。
-            var query = $"select distinct c.code,c.id,c.no,c.name,c.scope, c.creatorId,c.school from c join A0 in c.schedule where A0.stulist = '{groupChange.listid}'";
-            List<Course> courses = new List<Course>();
-            if (groupChange.scope.Equals("school") && !string.IsNullOrEmpty(groupChange.school))
-            {
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(queryText: query,
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.school}") }))
+                });
+                tmdids.ForEach(x =>
                 {
-                    courses.Add(item);
-                }
-            }
-            if (groupChange.scope.Equals("private") && !string.IsNullOrEmpty(groupChange.creatorId))
-            {
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Course>(queryText: query,
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.creatorId}") }))
+                    var user = tmdsData.Find(y => y.id.Equals(x.id));
+                    x.name = user?.name;
+                    x.picture = user?.picture;
+                });
+                students.ForEach(x =>
                 {
-                    courses.Add(item);
-                }
-            }
-            long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-            // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 需要处理的课程\n{courses.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
-            foreach (var course in courses)
-            {
-                //学生新加入名单的
-                foreach (Member member in groupChange.stujoin)
+                    var student = studentsData.Find(y => y.id.Equals(x.id) && y.schoolId.Equals(x.code));
+                    x.name = student?.name;
+                    x.picture = student?.picture;
+                    x.classId = student?.classId;
+                });
+                var mbs = tmdids;
+                mbs.AddRange(students);
+                if (changes.Count > 0 && !string.IsNullOrEmpty(groupTbname))
                 {
-                    var stucourse = new StuCourse
+                    foreach (var change in changes)
                     {
-                        id = course.id,
-                        scode = course.code,
-                        name = course.name,
-                        code = $"StuCourse-{member.code.Replace("Base-", "")}-{member.id}",
-                        scope = course.scope,
-                        school = course.school,
-                        creatorId = course.creatorId,
-                        pk = "StuCourse",
-                        stulist = new List<string> { groupChange.listid },
-                        createTime = nowtime
-                    };
-                    // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                }
-                //tmd新加入的
-                foreach (Member member in groupChange.tmdjoin)
-                {
-                    var stucourse = new StuCourse
-                    {
-                        id = course.id,
-                        scode = course.code,
-                        name = course.name,
-                        code = $"StuCourse-{member.id}",
-                        scope = course.scope,
-                        school = course.school,
-                        creatorId = course.creatorId,
-                        pk = "StuCourse",
-                        stulist = new List<string> { groupChange.listid },
-                        createTime = nowtime
-                    };
-                    // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                }
-                //移除名单的。 在点击相关的课程,再去二次校验是否存在,不存在则再去删除。
-                foreach (var delStu in groupChange.stuleave)
-                {
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delStu.code.Replace("Base-", "")}-{delStu.id}"));
-                }
-                foreach (var delTmd in groupChange.tmdleave)
-                {
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delTmd}"));
+                        change.tcount = change.members.Where(x => x.type == 1).Count();
+                        change.scount = change.members.Where(x => x.type == 2).Count();
+                        GroupList group= change.ToJsonString().ToObject<GroupList>();
+                        await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(group, group.id, new PartitionKey(group.code));
+                    }
                 }
+                groups.ForEach(x => x.members.ForEach(y=> {
+                    if (y.type == 1) {
+                        var tmd =tmdids.Find(t => t.id.Equals(y.id));
+                        y.name = tmd?.name;
+                        y.picture = tmd?.picture;
+                    }
+                    if (y.type == 2)
+                    {
+                        var student = students.Find(t => t.id.Equals(y.id)&& t.code.Equals(y.code));
+                        y.name = student?.name;
+                        y.picture = student?.picture;
+                        y.classId = student?.classId;
+                    }
+                }));
+                return (groups, mbs);
+            } catch (Exception ex) {
+                await _dingDing.SendBotMsg($"OS,GetGroupListMemberInfo()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
             }
+            return (null, null);
         }
+
+        
     }
     public class CompareIdCode : IEqualityComparer<(string id, string code)>
     {

+ 0 - 257
TEAMModelOS.SDK/Models/Service/StuListService.cs

@@ -1,257 +0,0 @@
-using Azure.Cosmos;
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.SDK.Extension;
-using TEAMModelOS.SDK;
-using TEAMModelOS.SDK.Models;
-using TEAMModelOS.SDK.Models.Cosmos.Common;
-using TEAMModelOS.SDK.Models.Service;
-using HTEXLib.COMM.Helpers;
-
-namespace TEAMModelFunction
-{
-    public class StuListService
-    {
-        public static async Task FixActivity(CosmosClient client,DingDing _dingDing, ListChange stuListChange, string type)
-        {
-            
-            try
-            {
-                var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c  where  c.pk='{type}' " +
-                    $" and (( array_contains(c.classes,'{stuListChange.listid}')) or ( array_contains(c.stuLists,'{stuListChange.listid}'))or ( array_contains(c.tchLists,'{stuListChange.listid}')))";
-                    //$"and A1 in('{stuListChange.listid}') ";
-                List<MQActivity> datas = new List<MQActivity>();
-                if (stuListChange.scope.Equals("school", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(stuListChange.school)) {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
-                       requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{stuListChange.school}") }))
-                    {
-                        datas.Add(item);
-                    }
-                    ///还要处理该学校每个老师发布的班级的
-                    List<SchoolTeacher> teachers = new List<SchoolTeacher>();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<SchoolTeacher>(queryText: $"SELECT c.id, c.name FROM c",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{stuListChange.school}") }))
-                    {
-                        teachers.Add(item);
-                    }
-                    foreach (var techer in teachers) {
-                        var queryTech = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c " +
-                            $" where c.school='{stuListChange.school}'   and   c.pk='{type}'" +
-                            $" and (( array_contains(c.classes,'{stuListChange.listid}')) or ( array_contains(c.stuLists,'{stuListChange.listid}')))";
-                      //  $" and A1 in('{stuListChange.listid}') ";
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: queryTech,
-                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{techer.id}") }))
-                        {
-                            datas.Add(item);
-                        }
-                    }
-                }
-                if (stuListChange.scope.Equals("private", StringComparison.OrdinalIgnoreCase)&&!string.IsNullOrEmpty(stuListChange.creatorId))
-                {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{stuListChange.creatorId}") }))
-                    {
-                        datas.Add(item);
-                    }
-                }
-              //  await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n名单发生变更:涉及活动类型变更的 \n{datas.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                foreach (MQActivity activity in datas)
-                {
-                    //已经完结的不再允许加入
-                    if (string.IsNullOrEmpty(activity.progress)|| activity.progress.Equals("finish") || activity.progress.Equals("pending"))
-                    {
-                        continue;
-                    }
-                    List<string> classes = ExamService.getClasses(activity.classes, activity.stuLists);
-                    //学生新加入名单的
-                    foreach (Students students in stuListChange.stujoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{students.code.Replace("Base-","")}-{students.id}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                     //   await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n名单发生变更 新建活动中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                    
-                    //tmd新加入的
-                    foreach (string tmdid in stuListChange.tmdjoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{tmdid}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                            taskStatus = -1,
-                            classIds = classes
-                        }; 
-                      //  await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n名单发生变更 新建活动中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                    //tmd新加入的
-                    foreach (string tch in stuListChange.tchjoin)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{tch}",
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = type,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        //  await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n名单发生变更 新建活动中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                    foreach (Students students in stuListChange.stuleave)
-                    {
-                        try
-                        {
-
-                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{students.code.Replace("Base-", "")}-{students.id}"));
-                        }
-                        catch (CosmosException ex)
-                        {
-                            //仅处理未写入的数据。
-                        }
-                    }
-                    foreach (string tmdid in stuListChange.tmdhleave)
-                    {
-                        try
-                        {
-
-                            await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{tmdid}"));
-                        }
-                        catch(CosmosException ex )
-                        {
-                            //仅处理未写入的数据。
-                        }
-                    }
-                }
-            }
-            catch(Exception ex ) {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixActivity\n{ex.Message}{ex.StackTrace}{stuListChange.ToJsonString()}{type}", GroupNames.醍摩豆服務運維群組);
-            }
-        }
-
-        public static async Task FixStuCourse(CosmosClient client,DingDing  _dingDing, ListChange stuListChange)
-        {
-            //1.查找学校或教师的课程是否包含该名单的课程。
-            var query = $"select distinct c.code,c.id,c.no,c.name,c.scope, c.creatorId,c.school from c join A0 in c.schedule where A0.stulist = '{stuListChange.listid}'";
-            List<Course> courses = new List<Course>();
-            if (stuListChange.scope.Equals("school") && !string.IsNullOrEmpty(stuListChange.school))
-            {
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(queryText: query,
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{stuListChange.school}") }))
-                {
-                    courses.Add(item);
-                }
-            }
-            if (stuListChange.scope.Equals("private") && !string.IsNullOrEmpty(stuListChange.creatorId))
-            {
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Course>(queryText: query,
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{stuListChange.creatorId}") }))
-                {
-                    courses.Add(item);
-                }
-            }
-           // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 需要处理的课程\n{courses.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
-            foreach (var course in courses)
-            {
-                //学生新加入名单的
-                foreach (Students students in stuListChange.stujoin)
-                {
-                    var stucourse = new StuCourse
-                    {
-                        id = course.id,
-                        scode = course.code,
-                        name = course.name,
-                        code = $"StuCourse-{students.code.Replace("Base-", "")}-{students.id}",
-                        scope = course.scope,
-                        school = course.school,
-                        creatorId = course.creatorId,
-                        pk = "StuCourse",
-                        stulist = new List<string> { stuListChange.listid },
-                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
-                    };
-                   // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                }
-                //tmd新加入的
-                foreach (string tmdid in stuListChange.tmdjoin)
-                {
-                    var stucourse = new StuCourse
-                    {
-                        id = course.id,
-                        scode = course.code,
-                        name = course.name,
-                        code = $"StuCourse-{tmdid}",
-                        scope = course.scope,
-                        school = course.school,
-                        creatorId = course.creatorId,
-                        pk = "StuCourse",
-                        stulist= new List<string> { stuListChange .listid},
-                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
-                    };
-                   // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                }
-                //移除名单的。 在点击相关的课程,再去二次校验是否存在,不存在则再去删除。
-                foreach (var delStu in stuListChange.stuleave)
-                {
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delStu.code.Replace("Base-", "")}-{delStu.id}"));
-                }
-                foreach (var delTmd in stuListChange.tmdhleave)
-                {
-                    await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delTmd}"));
-                }
-            }
-        }
-
-    }
-}

+ 88 - 0
TEAMModelOS.SDK/Models/Service/Third/ScApisService.cs

@@ -0,0 +1,88 @@
+using Azure.Cosmos;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+
+namespace TEAMModelOS.SDK
+{
+    public  static class ScApisService
+    {
+        public static string Code { get; set; }
+        public static Dictionary<string, object> parameterMap = null;
+        public static async Task<List<string>> GetDiagnosisListByProject_V2(ScConfig scconfig, ThirdApisService _thirdApisService) {
+            ScAccessConfig config = scconfig.accessConfig.ToObject<ScAccessConfig>();
+            List<string> abilityNos = null;
+            Code = "GetDiagnosisListByProject_V2";
+            parameterMap = new Dictionary<string, object>();
+            parameterMap.Add("TrainComID", config.trainComID);
+            //parameterMap.Add("ProjectID", "22");
+            //parameterMap.Add("ProjectItemID", "22");
+            parameterMap.Add("PXID", scconfig.pxid);
+            ScsResult result = new ScsResult {code=Code,title= "5.3.1.3通过项目编号获取学员测评能力项V2" };
+
+            try {
+                result = await _thirdApisService.Post(config.url, Code, config.passKey, config.privateKey, parameterMap);
+                if (result.result)
+                {
+                    List<ScDiagnosis> diagnoses = result.content.ToObject<List<ScDiagnosis>>();
+                    if (diagnoses != null)
+                    {
+                        abilityNos = diagnoses.Select(x => x.DiagnosisDicNum).ToList();
+                    }
+                }
+                return abilityNos;
+            } catch (Exception ex) {
+                //await dingDing.SendBotMsg($"IES5.ScApisService:getDiagnosisListByProject_V2\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
+                return abilityNos;
+            }
+        }
+    }
+    public class ScConfig
+    {
+        public string accessConfig { get; set; }
+        public string pxid { get; set; }
+    }
+    public class ScDiagnosis
+    {
+        public string diagnosisName { get; set; }
+        public string DiagnosisDicNum { get; set; }
+        public int ID { get; set; }
+    }
+    public class ScTeacher
+    {
+        public int PXID { get; set; }
+        public int TID { get; set; }
+        public string TeacherName { get; set; }
+        public int SchoolID { get; set; }
+        public string SchoolName { get; set; }
+        public int ProjectID { get; set; }
+        public int ProjectItemID { get; set; }
+        public string ProjectTitle { get; set; }
+        public string ProjectItemTitle { get; set; }
+        public string CityID { get; set; }
+        public string DistrictID { get; set; }
+        public string CityName { get; set; }
+        public string DisName { get; set; }
+        public string Account { get; set; }
+    }
+    public class ScAccessConfig
+    {
+        public string passKey { get; set; }
+        public string trainComID { get; set; }
+        public string privateKey { get; set; }
+        public string url { get; set; }
+    }
+    public class ScsResult
+    {
+        public bool result { get; set; }
+        public string reason { get; set; }
+        public string content { get; set; }
+        public string code { get; set; }
+        public string title { get; set; }
+    }
+}

+ 65 - 0
TEAMModelOS.SDK/Models/Service/Third/ThirdApisService.cs

@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Http.Json;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Extension;
+
+namespace TEAMModelOS.SDK
+{
+    public class ThirdApisService
+    {
+       
+        private readonly HttpClient _httpClient;
+        public ThirdApisService(HttpClient httpClient)
+        {
+            _httpClient = httpClient;
+        }
+        public async   Task<ScsResult> Post(string url, string Code, string PassKey,string privateKey, Dictionary<string ,object> data)
+        {
+
+            try {
+                string Content = AESHelper.AESEncrypt(data.ToJsonString(), privateKey);
+                string paramStr = "Code={0}&PassKey={1}&Content={2}";
+                string sendMsg = string.Format(paramStr, Code, PassKey, Content);
+                #region 签名 Signature
+                SortedDictionary<string, string> signatureDC = new SortedDictionary<string, string>();
+                var timeSpan = (DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0));
+                signatureDC["t"] = timeSpan.TotalMilliseconds.ToString();
+                signatureDC["Code"] = Code;
+                signatureDC["PassKey"] = PassKey;
+                string signatureStr = signatureDC.ToJsonString();
+                string signature = AESHelper.AESEncrypt(signatureStr, privateKey);
+                #endregion
+                string result = "";
+                _httpClient.DefaultRequestHeaders.Add("Signature", signature);
+                using (var request = new HttpRequestMessage())
+                {
+                    request.Method = new HttpMethod("POST");
+                    request.RequestUri = new Uri(url);
+                    request.Content = new StringContent(sendMsg);
+                    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
+                    var response = await _httpClient.SendAsync(request);
+                    result = await response.Content.ReadAsStringAsync();
+                }
+                ScsResult scsResult = result.ToObject<ScsResult>();
+                if (scsResult.result)
+                {
+                    scsResult.content = AESHelper.AESDecrypt(scsResult.content, privateKey);
+
+                }
+                return scsResult;
+            } catch (Exception ex ) {
+                throw new Exception(ex.StackTrace);
+            }
+            
+        }
+
+    }
+   
+}

+ 77 - 0
TEAMModelOS.SDK/Models/Service/Third/ThirdService.cs

@@ -0,0 +1,77 @@
+using Azure.Cosmos;
+using HTEXLib.COMM.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+
+namespace TEAMModelOS.SDK.Models
+{
+    public static class ThirdService
+    {
+        public static async Task<(string accessConfig, Area area, AreaSetting setting)> GetAccessConfig(CosmosClient client,string standard) {
+            Area area = null;
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Normal").
+                   GetItemQueryIterator<Area>($"select value(c) from c where c.standard='{standard}'", requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base-Area") }))
+            {
+                area = item;
+                break;
+            }
+            AreaSetting setting = null;
+            if (area != null)
+            {
+                try
+                {
+                    setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<AreaSetting>(area.id, new PartitionKey("AreaSetting"));
+                }
+                catch (CosmosException)
+                {
+                    setting = null;
+                }
+            }
+            if (setting == null||  string.IsNullOrEmpty(setting.accessConfig))
+            {
+                return (null,null,null);
+            }
+            else {
+                return (setting.accessConfig,area,setting);
+            }
+        }
+        public static async Task<List<Ability>> GetDiagnosisList(CosmosClient client, string standard,DingDing dingDing,  AreaSetting setting, HttpTrigger httpTrigger, HashSet<string> pxids, TEAMModelOS.Models.Option _option) {
+            List<string> abilityNos = new List<string>() ;
+            var config= setting.accessConfig.ToObject<JsonElement>();
+            config.TryGetProperty("config", out JsonElement _config);
+            if ($"{_config}".Equals("scsyxpt"))
+            {
+                foreach (var pxid in pxids) {
+                    Dictionary<string, object> dict = new Dictionary<string, object>() { { "accessConfig", setting.accessConfig },{ "pxid",pxid } };
+                    (int status, string json) = await httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetDiagnosisListByProject_V2");
+                    if (status == 200)
+                    {
+                        List<string> nos = json.ToObject<List<string>>();
+                        if (nos.IsNotEmpty()) {
+                            abilityNos.AddRange(nos);
+                        }
+                    }
+                }
+            }
+            //获取能力点
+            List<Ability> abilities = null;
+            if (abilityNos.IsNotEmpty()) {
+                abilities = new List<Ability>();
+                StringBuilder sql = new StringBuilder($"select value(c) from c where c.no in ({string.Join(",", abilityNos.Select(x => $"'{x}'"))})");
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Normal")
+                         .GetItemQueryIterator<Ability>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") }))
+                {
+                    abilities.Add(item);
+                }
+            }
+            return abilities;
+        }
+       
+    }
+}

+ 0 - 627
TEAMModelOS.SDK/Models/Service/TriggerStuActivity.cs

@@ -1,627 +0,0 @@
-using Azure;
-using Azure.Cosmos;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.SDK.Extension;
-using TEAMModelOS.SDK;
-using TEAMModelOS.SDK.Models;
-using TEAMModelOS.SDK.Models.Cosmos.Common;
-using TEAMModelOS.SDK.Models.Service;
-using HTEXLib.COMM.Helpers;
-
-namespace TEAMModelOS.SDK
-{
-    public class TriggerStuActivity
-    {
-        public static async Task RefreshStuActivity(CosmosClient client, DingDing _dingDing, string id, string code)
-        {
-            MQActivity activity = null;
-            try
-            {
-                var aactivity = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync(id, new Azure.Cosmos.PartitionKey(code));
-                using var da = await JsonDocument.ParseAsync(aactivity.ContentStream);
-                activity = da.ToObject<MQActivity>();
-            }
-            catch (CosmosException )
-            {
-                activity=null;
-            }
-            if (activity != null)
-            {
-                List<string> classes = ExamService.getClasses(activity.classes, activity.stuLists);
-                (List<TmdInfo> tmdids, List<StuInfo> students,List<ClassListInfo> classLists) = await GetStuList(client, _dingDing, classes, activity.school);
-                if (tmdids.IsNotEmpty())
-                {
-                    foreach (TmdInfo tmdid in tmdids)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{tmdid.id}",
-                            source = activity.source,
-                            scope = activity.scope,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = activity.pk,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                }
-                if (students.IsNotEmpty())
-                {
-                    foreach (StuInfo student in students)
-                    {
-                        var stucourse = new StuActivity
-                        {
-                            id = activity.id,
-                            scode = activity.code,
-                            name = activity.name,
-                            code = $"Activity-{activity.school}-{student.id}",
-                            scope = activity.scope,
-                            source = activity.source,
-                            school = activity.school,
-                            creatorId = activity.creatorId,
-                            pk = "Activity",
-                            type = activity.pk,
-                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
-                            startTime = activity.startTime,
-                            endTime = activity.endTime,
-                            blob = activity.blob,
-                            owner = activity.owner,
-                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
-                            taskStatus = -1,
-                            classIds = classes
-                        };
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
-                    }
-                }
-            }
-        }
-
-        public static async Task<string> SaveStuActivity(CosmosClient client, DingDing _dingDing, List<StuActivity> stuActivities,List<StuActivity> tmdActivities, List<StuActivity>  tchActivities) {
-            try {
-                if (stuActivities.IsNotEmpty())
-                {
-                    foreach (var x in stuActivities)
-                    {
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(x, new PartitionKey(x.code));
-                    }
-                }
-                if (tmdActivities.IsNotEmpty())
-                {
-                    foreach (var x in tmdActivities)
-                    {
-                        await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(x, new PartitionKey(x.code));
-                    }
-                }
-                if (tchActivities.IsNotEmpty())
-                {
-                    foreach (var x in tchActivities)
-                    {
-                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(x, new PartitionKey(x.code));
-                    }
-                }
-            } catch (Exception ex) {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-SaveStuActivity\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-            }
-            return ""; 
-        }
-        /// <summary>
-        /// 获取行政班接口
-        /// </summary>
-        /// <param name="client"></param>
-        /// <param name="_dingDing"></param>
-        /// <param name="classes"></param>
-        /// <param name="school"></param>
-        /// <returns></returns>
-        public static async Task<List<ClassInfo>> GetClassInfo(CosmosClient client, DingDing _dingDing, List<string> classes, string school)
-        {
-            try {
-                List<ClassInfo> classInfos = new List<ClassInfo>();
-                if (classes.IsNotEmpty()) {
-                    List<string> sqlList = new List<string>();
-                    classes.ForEach(x => { sqlList.Add($" '{x}' "); });
-                    string sql = string.Join(" , ", sqlList);
-                    if (!string.IsNullOrEmpty(school))
-                    {
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name ,c.periodId,c.year from c where c.id in ({sql})",
-                           requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
-                        {
-
-                            classInfos.Add(item);
-                        }
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name from c where c.id in ({sql})",
-                          requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{school}") }))
-                        {
-                            //item.from = "SchStuList";
-                            classInfos.Add(item);
-                        }
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name from c where c.id in ({sql})",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"TchList-{school}") }))
-                        {
-                            //item.from = "SchStuList";
-                            classInfos.Add(item);
-                        }
-                    }
-                    List<StuList> tchLists = new List<StuList>();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<ClassInfo>(queryText: $"select c.id,c.name from c where c.id in ({sql})",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
-                    {
-                       // item.from = "TchStuList";
-                        classInfos.Add(item);
-                    }
-                    classInfos = classInfos.GroupBy(c => c.id).Select(s => s.First()).ToList();
-                }
-                return classInfos;
-            } catch (Exception ex) {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-GetClassInfo\n{ex.Message}\n{ex.StackTrace}\n class{classes.ToJsonString()},{school}", GroupNames.醍摩豆服務運維群組);
-                throw new Exception(ex.Message, ex);
-            }
-        }
-        public static async Task<(List<TmdInfo> tmdinfos, List<StuInfo> students, List<ClassListInfo> classInfo)> GetStuListInStu(CosmosClient client, DingDing _dingDing, List<string> claes, string school)
-        {
-            try
-            {
-                List<string> classes = new List<string>();
-                foreach (string ss in claes)
-                {
-                    classes.Add(ss);
-                }
-                List<TmdInfo> tmdinfos = new List<TmdInfo>();
-                List<Students> studentss = new List<Students>();
-                List<string> tmdids = new List<string>();
-                List<StuInfo> stuInfos = new List<StuInfo>();
-                if (!classes.IsNotEmpty()) { return (tmdinfos, new List<StuInfo>(), null); }
-                List<string> sqlList = new List<string>();
-                classes.ForEach(x => { sqlList.Add($" '{x}' "); });
-                string sql = string.Join(" , ", sqlList);
-                List<StuList> schList = new List<StuList>();
-                List<Student> students = new List<Student>();
-                if (!string.IsNullOrEmpty(school))
-                {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({sql})",
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{school}") }))
-                    {
-                        schList.Add(item);
-                    }
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId in ({sql})",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{school}") }))
-                    {
-                        students.Add(item);
-                    }
-                }
-                List<StuList> tchLists = new List<StuList>();
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({sql})",
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
-                {
-                    tchLists.Add(item);
-                }
-
-                foreach (var x in schList)
-                {
-                    if (x.students.IsNotEmpty())
-                    {
-                        studentss.AddRange(x.students);
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        tmdids.AddRange(x.tmids);
-                    }
-                   
-                    classes.Remove(x.id);
-                }
-                foreach (var x in tchLists)
-                {
-                    if (x.students.IsNotEmpty())
-                    {
-                        studentss.AddRange(x.students);
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        tmdids.AddRange(x.tmids);
-                    }
-                    classes.Remove(x.id);
-                }
-
-                if (tmdids.IsNotEmpty())
-                {
-                    List<TmdInfo> infos = new List<TmdInfo>();
-                    List<string> inids = new List<string>();
-                    tmdids.ForEach(x => { inids.Add($"'{x}'"); });
-                    var insql = string.Join(",", inids);
-                    var queryslt = $"SELECT  value(c) FROM c where c.id in ({insql})";
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<TmdInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                    {
-                        infos.Add(item);
-                        tmdids.Remove(item.id);
-                    }
-                    if (tmdids.IsNotEmpty()) {
-                        inids = new List<string>();
-                        tmdids.ForEach(x => { inids.Add($"'{x}'"); });
-                        insql = string.Join(",", inids);
-                        queryslt = $"SELECT  value(c) FROM c where c.id in ({insql})";
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<TmdInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                        {
-                            infos.Add(item);
-                        }
-                    }
-                    tmdinfos.AddRange(infos);
-                }
-                if (studentss.IsNotEmpty())
-                {
-                    var stuGroups = studentss.GroupBy(x => x.code).ToList().Select(x => new { key = x.Key, list = x.ToList() }) ;
-                    foreach (var gp in stuGroups) {
-                        List<string> inidstus = new List<string>();
-                        gp.list.Select(x => x.id).ToList().ForEach(x => { inidstus.Add($"'{x}'"); });
-                        PartitionKey partitionKey = new PartitionKey($"Base-{gp.key.Replace("Base-", "")}");
-                        var insqlstu = string.Join(",", inidstus);
-                        var querystu = $"SELECT  c.id,c.code,c.name,c.picture,c.classId,c.groupId,c.groupName,c.year,c.schoolId FROM c where c.id in ({insqlstu})";
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuInfo>(queryText: querystu, requestOptions: new QueryRequestOptions() { PartitionKey= partitionKey }))
-                        {
-                            stuInfos.Add(item);
-                        }
-                    }
-                }
-                students.ForEach(x =>
-                {
-                    if (!stuInfos.Select(y => y.classId).ToList().Contains(x.id))
-                    {
-                        stuInfos.Add(new StuInfo { id = x.id, code = x.code, schoolId = x.schoolId, classId = x.classId, name = x.name, picture = x.picture, year = x.year,groupId = x.groupId,groupName=x.groupName,no=x.no });
-                    }
-                });
-                List<ClassListInfo> classInfo = new List<ClassListInfo>();
-                schList.ForEach(x => {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    if (x.students.IsNotEmpty())
-                    {
-                        x.students.ForEach(y => {
-                            var stuinfo = stuInfos.Where(z => z.id.Equals(y.id)).FirstOrDefault();
-                            if (stuinfo != null)
-                            {
-                                classListInfo.stuInfos.Add(stuinfo);
-                            }
-                        });
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        x.tmids.ForEach(y => {
-                            var tmdinfo = tmdinfos.Where(z => z.id.Equals(y)).FirstOrDefault();
-                            if (tmdinfo != null)
-                            {
-                                classListInfo.tmdInfos.Add(tmdinfo);
-                            }
-                        });
-                    }
-                    classInfo.Add(classListInfo);
-                });
-                tchLists.ForEach(x => {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    if (x.students.IsNotEmpty())
-                    {
-                        x.students.ForEach(y => {
-                            var stuinfo = stuInfos.Where(z => z.id.Equals(y.id)).FirstOrDefault();
-                            if (stuinfo != null)
-                            {
-                                classListInfo.stuInfos.Add(stuinfo);
-                            }
-                        });
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        x.tmids.ForEach(y => {
-                            var tmdinfo = tmdinfos.Where(z => z.id.Equals(y)).FirstOrDefault();
-                            if (tmdinfo != null)
-                            {
-                                classListInfo.tmdInfos.Add(tmdinfo);
-                            }
-                        });
-                    }
-                    classInfo.Add(classListInfo);
-                });
-
-
-                //var classeids= students.GroupBy(x => x.classId).Select(x => x.Key).ToList();
-                List<ClassInfo> classInfos = await GetClassInfo(client, _dingDing, classes, school);
-                classInfos.ForEach(x =>
-                {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    var list = students.Where(y => y.classId .Equals(x.id)).ToList();
-                    list.ForEach(z => { classListInfo.stuInfos.Add(new StuInfo { id = z.id, code = z.code, schoolId = z.schoolId, classId = z.classId, name = z.name, picture = z.picture, year = z.year,groupId=z.groupId,groupName=z.groupName,no=z.no }); });
-                    classInfo.Add(classListInfo);
-                });
-
-                return (tmdinfos, stuInfos, classInfo);
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-GetStuList\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-            }
-            return (null, null, null);
-        }
-        public static async Task<(List<TmdInfo> tmdinfos, List<ClassListInfo> classInfo)> GetTchList(CosmosClient client, DingDing _dingDing, List<string> claes, string school)
-        {
-            try
-            {
-                List<TmdInfo> tmdinfos = new List<TmdInfo>();
-                List<ClassListInfo> classInfo = new List<ClassListInfo>();
-                if (claes.Count == 1 && claes.First().Equals("default"))
-                {
-                    List<TmdInfo> infos = new List<TmdInfo>();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdInfo>(queryText: $"SELECT  value(c) FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
-                    {
-                        infos.Add(item);
-                    }
-                    tmdinfos.AddRange(infos);
-                    classInfo.Add(new ClassListInfo { id = "default",name= "default", tmdInfos = infos });
-                }
-                else {
-                    List<string> classes = new List<string>();
-                    foreach (string ss in claes)
-                    {
-                        classes.Add(ss);
-                    }
-
-                    List<string> tmdids = new List<string>();
-                    List<StuInfo> stuInfos = new List<StuInfo>();
-                    if (!classes.IsNotEmpty()) { return (tmdinfos, null); }
-                    List<string> sqlList = new List<string>();
-                    classes.ForEach(x => { sqlList.Add($" '{x}' "); });
-                    string sql = string.Join(" , ", sqlList);
-                    List<TchList> tchLists = new List<TchList>();
-
-                    if (!string.IsNullOrEmpty(school))
-                    {
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TchList>(queryText: $"select value(c) from c where c.id in ({sql})",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"TchList-{school}") }))
-                        {
-                            tchLists.Add(item);
-                        }
-
-                    }
-                    foreach (var x in tchLists)
-                    {
-
-                        if (x.teachers.IsNotEmpty())
-                        {
-                            tmdids.AddRange(x.teachers);
-                        }
-                        classes.Remove(x.id);
-                    }
-
-                    if (tmdids.IsNotEmpty())
-                    {
-                        List<TmdInfo> infos = new List<TmdInfo>();
-                        List<string> inids = new List<string>();
-                        tmdids.ForEach(x => { inids.Add($"'{x}'"); });
-                        var insql = string.Join(",", inids);
-                        var queryslt = $"SELECT  value(c) FROM c where c.id in ({insql})";
-                        //合并代码/
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<TmdInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                        {
-                            infos.Add(item);
-                        }
-                        tmdinfos.AddRange(infos);
-                    }
-                    tchLists.ForEach(x => {
-                        ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                        if (x.teachers.IsNotEmpty())
-                        {
-                            x.teachers.ForEach(y => {
-                                var tmdinfo = tmdinfos.Where(z => z.id.Equals(y)).FirstOrDefault();
-                                if (tmdinfo != null)
-                                {
-                                    classListInfo.tmdInfos.Add(tmdinfo);
-                                }
-                            });
-                        }
-                        classInfo.Add(classListInfo);
-                    });
-                }
-                return (tmdinfos,  classInfo);
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-GetStuList\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-            }
-            return (null,  null);
-        }
-        public static async Task<(List<TmdInfo> tmdinfos, List<StuInfo> students, List<ClassListInfo> classInfo)> GetStuList(CosmosClient client, DingDing _dingDing, List<string> claes, string school)
-        {
-            try
-            {
-                List<string> classes = new List<string>();
-                foreach (string ss in claes)
-                {
-                    classes.Add(ss);
-                }
-                List<TmdInfo> tmdinfos = new List<TmdInfo>();
-                List<Students> studentss = new List<Students>();
-                List<string> tmdids = new List<string>();
-                List<StuInfo> stuInfos = new List<StuInfo>();
-                if (!classes.IsNotEmpty()) { return (tmdinfos, new List<StuInfo>(), null); }
-                List<string> sqlList = new List<string>();
-                classes.ForEach(x => { sqlList.Add($" '{x}' "); });
-                string sql = string.Join(" , ", sqlList);
-                List<StuList> schList = new List<StuList>();
-                List<Student> students = new List<Student>();
-                if (!string.IsNullOrEmpty(school))
-                {
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({sql})",
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{school}") }))
-                    {
-                        schList.Add(item);
-                    }
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select value(c) from c where c.classId in ({sql})",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{school}") }))
-                    {
-                        students.Add(item);
-                    }
-                }
-                List<StuList> tchLists = new List<StuList>();
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({sql})",
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
-                {
-                    tchLists.Add(item);
-                }
-
-                foreach (var x in schList)
-                {
-                    if (x.students.IsNotEmpty())
-                    {
-                        studentss.AddRange(x.students);
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        tmdids.AddRange(x.tmids);
-                    }
-                    classes.Remove(x.id);
-                }
-                foreach (var x in tchLists)
-                {
-                    if (x.students.IsNotEmpty())
-                    {
-                        studentss.AddRange(x.students);
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        tmdids.AddRange(x.tmids);
-                    }
-                    classes.Remove(x.id);
-                }
-
-                if (tmdids.IsNotEmpty())
-                {
-                    List<TmdInfo> infos = new List<TmdInfo>();
-                    List<string> inids = new List<string>();
-                    tmdids.ForEach(x => { inids.Add($"'{x}'"); });
-                    var insql = string.Join(",", inids);
-                    var queryslt = $"SELECT  value(c) FROM c where c.id in ({insql})";
-                    //合并代码/
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<TmdInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
-                    {
-                        infos.Add(item);
-                    }
-                    tmdinfos.AddRange(infos);
-                }
-                if (studentss.IsNotEmpty())
-                {
-                    List<string> inidstus = new List<string>();
-                    foreach (Students stu in studentss)
-                    {
-                        var querystu = $"SELECT  c.id,c.code,c.name,c.picture,c.classId,c.year,c.schoolId FROM c where c.id = '{stu.id}'";
-                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuInfo>(queryText: querystu, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{stu.code}") }))
-                        {
-                            stuInfos.Add(item);
-                        }
-                    }
-                    /*studentss.Select(x => x.id).ToList().ForEach(x => { inidstus.Add($"'{x}'"); });
-                    var insqlstu = string.Join(",", inidstus);
-                    var querystu = $"SELECT  c.id,c.code,c.name,c.picture,c.classId,c.year,c.schoolId FROM c where c.id in ({insqlstu})";
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuInfo>(queryText: querystu, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{school}") }))
-                    {
-                        stuInfos.Add(item);
-                    }*/
-                }
-                students.ForEach(x =>
-                {
-                    if (!stuInfos.Select(y => y.classId).ToList().Contains(x.id))
-                    {
-                        stuInfos.Add(new StuInfo { id = x.id, code = x.code, schoolId = x.schoolId, classId = x.classId, name = x.name, picture = x.picture, year = x.year, groupId = x.groupId, groupName = x.groupName, no = x.no });
-                    }
-                });
-                List<ClassListInfo> classInfo = new List<ClassListInfo>();
-                schList.ForEach(x => {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    if (x.students.IsNotEmpty())
-                    {
-                        x.students.ForEach(y => {
-                            var stuinfo = stuInfos.Where(z => z.id.Equals(y.id)).FirstOrDefault();
-                            if (stuinfo != null)
-                            {
-                                classListInfo.stuInfos.Add(stuinfo);
-                            }
-                        });
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        x.tmids.ForEach(y => {
-                            var tmdinfo = tmdinfos.Where(z => z.id.Equals(y)).FirstOrDefault();
-                            if (tmdinfo != null)
-                            {
-                                classListInfo.tmdInfos.Add(tmdinfo);
-                            }
-                        });
-                    }
-                    classInfo.Add(classListInfo);
-                });
-                tchLists.ForEach(x => {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    if (x.students.IsNotEmpty())
-                    {
-                        x.students.ForEach(y => {
-                            var stuinfo = stuInfos.Where(z => z.id.Equals(y.id)).FirstOrDefault();
-                            if (stuinfo != null)
-                            {
-                                classListInfo.stuInfos.Add(stuinfo);
-                            }
-                        });
-                    }
-                    if (x.tmids.IsNotEmpty())
-                    {
-                        x.tmids.ForEach(y => {
-                            var tmdinfo = tmdinfos.Where(z => z.id.Equals(y)).FirstOrDefault();
-                            if (tmdinfo != null)
-                            {
-                                classListInfo.tmdInfos.Add(tmdinfo);
-                            }
-                        });
-                    }
-                    classInfo.Add(classListInfo);
-                });
-
-
-                //var classeids= students.GroupBy(x => x.classId).Select(x => x.Key).ToList();
-                List<ClassInfo> classInfos = await GetClassInfo(client, _dingDing, classes, school);
-                classInfos.ForEach(x =>
-                {
-                    ClassListInfo classListInfo = new ClassListInfo { id = x.id, name = x.name };
-                    var list = students.Where(y => y.classId.Equals(x.id)).ToList();
-                    list.ForEach(z => { classListInfo.stuInfos.Add(new StuInfo { id = z.id, code = z.code, schoolId = z.schoolId, classId = z.classId, name = z.name, picture = z.picture, year = z.year, groupId = z.groupId, groupName = z.groupName, no = z.no }); });
-                    classInfo.Add(classListInfo);
-                });
-
-                return (tmdinfos, stuInfos, classInfo);
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-OS,TriggerStuActivity-GetStuList\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-            }
-            return (null, null, null);
-        }
-    }
-    public class ClassListInfo
-    {
-        public string id { get; set; }
-        public string name { get; set; }
-        // public string from { get; set; }
-        public List<StuInfo> stuInfos { get; set; } = new List<StuInfo>();
-        public List<TmdInfo> tmdInfos { get; set; } = new List<TmdInfo>();
-    }
-}

+ 3 - 9
TEAMModelOS/ClientApp/src/api/ability.js

@@ -90,19 +90,13 @@ export default {
 	saveWork:function (data) {
 		return post('/common/work/save', data)
 	},
-	deleteWork:function (data) {
-		return post('/common/work/delete', data)
-	},
-	getWorkList:function (data) {
-		return post('/common/work/find', data)
-	},
 	getWorkSummary:function (data) {
 		return post('/common/work/find-summary', data)
 	},
 	//数据统计API
-	FindTotalData: function (data) {
-		return post('/research/ability/get-subs-statistics', data)
-	},
+	//FindTotalData: function (data) {
+	//	return post('/research/get-subs-statistics', data)
+	//},
 	//校本研修审核学时
 	AuditStudy: function (data) {
 		return post('/common/study/audit', data)

+ 55 - 0
TEAMModelOS/ClientApp/src/api/common.js

@@ -0,0 +1,55 @@
+import { post } from '@/api/http'
+export default {
+    /*
+     *查询名单列表
+     */
+     getGroupList: function (data) {
+        return post('/grouplist/get-grouplists', data)
+    },
+    /*
+     *查询名单详细信息
+     */
+     getGroupInfo: function (data) {
+        return post('/grouplist/get-grouplist-idcode', data)
+    },
+    /*
+     *保存更新名单信息
+     */
+     upsertGroupInfo: function (data) {
+        return post('/grouplist/upsert-grouplist', data)
+    },
+    /*
+     *根据条件查询名单列表和成员信息
+     */
+     getGroupListInfo: function (data) {
+        return post('/grouplist/get-grouplists-members', data)
+    },
+    /*
+     *根据名单id查询名单详细信息
+     */
+     getGroupListByIds: function (data) {
+        return post('/grouplist/get-members-listids', data)
+    },
+    /*
+     *查询活动发布对象
+     */
+     getActivityTarget: function (data) {
+        return post('/grouplist/get-activity-grouplist', data)
+    },
+    /*
+     *删除名单
+     */
+     deleteGroupList: function (data) {
+        return post('/grouplist/delete-grouplist', data)
+    },
+    /*
+     *查询行政班名单学生完整信息
+     */
+     getClassStudent: function (data) {
+        return post('/grouplist/get-classstudents-idcode', data)
+    },
+	/* 查询组长信息 */
+	getGroupLeaderTags: function (data) {
+        return post('/grouplist/get-grouplist-tags', data)
+    },
+}

+ 0 - 16
TEAMModelOS/ClientApp/src/api/courseMgmt.js

@@ -70,22 +70,10 @@ export default {
     upsertNotice: function (data) {
         return post('/school/course/upsert-notice', data)
     },
-    //查询stulist
-    findStulist: function (data) {
-        return post('/stulist/find-list', data)
-    },
-    //添加或修改stulist
-    upsertStulist: function (data) {
-        return post('/stulist/upsert-list', data)
-    },
     //根据学生id换取详细信息
     findStuSummary: function (data) {
         return post('/student/get-summary-student', data)
     },
-    //根据stulist ids换取详细信息
-    findListSummary: function (data) {
-        return post('/stulist/get-summary-list', data)
-    },
     //查询课程安排数据
     findCusByRoom: function (data) {
         return post('/school/course/find-course-by-room', data)
@@ -94,10 +82,6 @@ export default {
     findTchAc: function (data) {
         return post('/teacher/comment/tch-activity', data)
     },
-    //删除自定义名单
-    delStuList: function (data) {
-        return post('/stulist/delete-list', data)
-    },
     // 加入课程
     qrCodeJoinList: function (data) {
         return post('/stulist/scan-code-join-list', data)

+ 3 - 1
TEAMModelOS/ClientApp/src/api/index.js

@@ -33,7 +33,8 @@ import service from './service'
 import notice from './notice'
 import ability from './ability';
 import jyzx from './jyzx'
-import train from './train';
+import train from './train'
+import common from './common'
 
 export default {
     accessToken,
@@ -69,6 +70,7 @@ export default {
 	 jyzx,
 	ability,
 	train,
+    common,
     // 获取登录跳转链接
     getLoginLink: function (data) {
         return post('api/login/login', data)

+ 4 - 0
TEAMModelOS/ClientApp/src/api/jyzx.js

@@ -129,4 +129,8 @@ export default {
 	getReplyContent: function (data) {
 		return post('/research/ability/get-reply-info',data)
 	},
+    // 查询校本研修的作业
+    getJyzxHomework: function (data) {
+        return post('/common/homework/find-id', data)
+    }
 }

+ 3 - 7
TEAMModelOS/ClientApp/src/api/learnActivity.js

@@ -33,13 +33,13 @@ export default {
     /*
      *查询评测
      */
-    FindExamInfo: function (data) {
+    FindExamList: function (data) {
         return post('/common/exam/find', data)
     },
     /*
      *查询单个评测
      */
-    FindExamInfos: function (data) {
+    FindExamInfo: function (data) {
         return post('/common/exam/find-summary', data)
     },
     /*
@@ -242,7 +242,7 @@ export default {
         return post('/common/vote/find-record', data)
     },
     getClassNameByIds: function (data) {
-        return post('/common/get-class-info', data)
+        return post('/grouplist/get-grouplist-listids', data)
     },
     /*
     * 保存评测学生作答数据(分数)
@@ -322,10 +322,6 @@ export default {
     ActivityCount: function (data) {
         return post('/teacher/comment/tch-activity-count', data)
     },
-	//查询教研组名单
-	findResearchList: function (data) {
-	    return post('/tchlist/find-list-members', data)
-	},
     //查看阅卷进度
     findMarkProgress: function (data) {
 	    return post('/common/exam/analysis-scoring', data)

+ 1 - 23
TEAMModelOS/ClientApp/src/api/schoolSetting.js

@@ -46,16 +46,6 @@ export default {
         return post('/teacher/init/join-school', data)
     },
 
-    //获取教室关联的学生
-    getClassroomStudent: function (data) {
-        return post('/school/classroom/find-student', data)
-    },
-	
-	/* 根据班级ID查询所有的学生名单 */
-	getStusByClassId: function (data) {
-        return post('/school/classroom/find-students', data)
-    },
-
     //保存分组信息
     upsertGroup: function (data) {
         return post('/school/classroom/upsert-group', data)
@@ -87,17 +77,5 @@ export default {
     //转让管理员身份
     TransferAdminRole:function (data) {
         return post('/teacher/init/set-teacher-info', data)
-    },
-    // 查询教研组
-    FindTchGroup:function (data) {
-        return post('/tchlist/get-research-list', data)
-    },
-    // 创建或修改教研组
-    UpsertTchGroup:function (data) {
-        return post('/tchlist/upsert-list', data)
-    },
-    // 删除教研组
-    DelTchGroup:function (data) {
-        return post('/tchlist/delete-list', data)
-    },
+    }
 }

+ 1 - 5
TEAMModelOS/ClientApp/src/api/schoolUser.js

@@ -25,9 +25,5 @@ export default {
     },
     getUserFromCoreId: function (data) {
         return post('/school/teacher/get-coreuser', data)
-    },
-    // 查询教研组
-    getResearchGroup: function (data) {
-        return post('/tchlist/get-research-list', data)
-    },
+    }
 }

+ 0 - 10
TEAMModelOS/ClientApp/src/api/studentWeb.js

@@ -244,16 +244,6 @@ export default {
         return post("/student/get-school-info", data)
     },
 
-    // 获取教室关联的学生(教师端接口)
-    getClassroomStudent: function (data) {
-        return post('/school/classroom/find-students', data)
-    },
-
-    // 根据stulist ids换取详细信息(教师端接口)
-    findListSummary: function (data) {
-        return post('/stulist/get-summary-list', data)
-    },
-
     // 根据学生id换取详细信息(教师端接口)
     findStuSummary: function (data) {
         return post('/student/get-summary-student', data)

+ 6 - 1
TEAMModelOS/ClientApp/src/common/AbilityUpload.vue

@@ -86,11 +86,16 @@
 					1024 / 1024).toFixed(1) + 'M' : (bytes / 1024 / 1024 / 1024).toFixed(1) + 'G'
 			},
 
-			onBeforeUpload(file) {
+			async onBeforeUpload(file) {
 				console.log(this.$GLOBAL.NotSupport);
 				console.log(this.acceptTypes);
 				console.log(file);
 				console.log(file.type);
+				// 如果上传的是视频文件 则需要获取视频的时长信息
+				if(file.type === 'video/mp4'){
+					file.duration = await this.$tools.getVideoDuration(file)
+					console.log(file.duration);
+				}
 				let nameType = file.name.split('.')[file.name.split('.').length - 1]
 				if (this.maxSize > 0 && file.size > this.maxSize) {
 					this.$Message.warning(this.$t('ability.sizeTip') + this.getSizeByBytes(this.maxSize) + '!');

+ 1 - 0
TEAMModelOS/ClientApp/src/common/BaseAreaList.vue

@@ -57,6 +57,7 @@
 				sessionStorage.setItem('areaId',this.areaList[this.curAreaIndex].areaId)
 				sessionStorage.setItem('areaName',this.areaList[this.curAreaIndex].name)
 				sessionStorage.setItem('standard',this.areaList[this.curAreaIndex].standard)
+				sessionStorage.setItem('areaAccess',this.areaList[this.curAreaIndex].access)
 				this.$EventBus.$emit('onGlobalLoading', true)
 				this.$EventBus.$emit('onSwitchArea')
 				setTimeout(() => {

+ 29 - 62
TEAMModelOS/ClientApp/src/common/BaseClassSelect.vue

@@ -45,23 +45,15 @@
 				preCheckList:[],
 				prePeriodId:'',
 				preCheckType:'',
-				privateClassType:'school'
+				privateClassType:'school',
+				schoolClasses:[],
+				teachClasses:[]
 			};
 		},
 		created() {
-			this.findStuList()
-			this.findResearchList()
+			this.getTargetList()
 		},
 		methods: {
-			/* 查找学校检验组信息 */
-			findResearchList(){
-				this.$api.schoolUser.getResearchGroup({
-					code:this.$store.state.userInfo.schoolCode,
-					scope:'school'
-				}).then(res => {
-					this.groupList = res.tchLists
-				})
-			},
 			/* 选择教研组发生变化 */
 			onGroupChange(){
 				this.$emit('onChange', this.groupArr)
@@ -72,40 +64,11 @@
 				this.groupArr = []
 				this.targetType = val
 			},
-			changeLabel(val) {
-			  // 是否与上次的类型相同
-			  let changeFlag = false
-			  let changeItem = null
-			  if (this.shareScopeEnd.length == 0) {
-				this.defaultArr = val
-			  } else {
-				// 与原数组比对
-				this.defaultArr.forEach((item) => {
-				  if (item[0] !== this.shareScopeEnd[0][0]) { // 一级标签不同
-					changeFlag = true
-					changeItem = item
-				  } else if (item[1] != this.shareScopeEnd[0][1]) { // 一级标签相同但是二级标签不同
-					changeFlag = true
-					changeItem = item
-				  } else if ((!item[2] && this.shareScopeEnd[0][2]) || (item[2] && !this.shareScopeEnd[0][2])) {
-					changeFlag = true
-					changeItem = item
-				  }
-				})
-			  }
-			  if (changeFlag) {
-				this.defaultArr = []
-				this.defaultArr.push(changeItem)
-			  }
-			  console.log(this.defaultArr)
-			  this.shareScopeEnd = this.defaultArr
-			},
-
 			getClassesDataByPeriodId(id) {
 				let data = []
 				if (this.$store.state.user.schoolProfile) {
 					let curPd = this.$store.state.user.schoolProfile.school_base.period.find(i => i.id === id)
-					let schoolClasses = this.$store.state.user.schoolProfile.school_classes
+					let schoolClasses = this.schoolClasses
 					data = [{
 							id: 'class',
 							name: this.$t('stuAccount.adminClass'),
@@ -146,7 +109,7 @@
 						})
 					}
 					// 填充教学班数据
-					let curStuList = this.stuList.filter(item => {
+					let curStuList = this.teachClasses.filter(item => {
 					    return item.periodId == curPd.id
 					})
 					data[1].children.push(...curStuList)
@@ -158,6 +121,23 @@
 			        this.selectBefore = this._.cloneDeep(this.defaultArr)
 			    }
 			},
+			getTargetList() {
+			    let params = {
+			        tmdid: this.$store.state.userInfo.TEAMModelId,
+			        schoolId: this.$store.state.userInfo.schoolCode,
+			        opt: 'manage'
+			    }
+			    this.$api.common.getActivityTarget(params).then(
+			        res => {
+			            this.schoolClasses = res.groupLists.filter(i => i.type === 'class')
+			            this.teachClasses = res.groupLists.filter(i => i.type === 'teach')
+						this.groupList = res.groupLists.filter(i => i.type === 'research')
+			        },
+			        err => {
+			            this.$Messag.error('查询发布对象失败')
+			        }
+			    )
+			},
 			treeChange(data) {
 				console.log(data)
 				if(!data.length){
@@ -172,11 +152,11 @@
 				if(obj.length && xArr.length){
 					// 如果切换了学段 则要全部置空 再将最新选择的作为结果
 					let curCheckNodePeriod = obj.find(i => i.data.id === xArr[0]).data.periodId
-					if(curCheckNodePeriod !== this.prePeriodId){
-						this.$refs.demoCascader.panel.activePath = [];
-						this.prePeriodId = curCheckNodePeriod
-						this.defaultArr = xArr
-					}
+					// if(curCheckNodePeriod !== this.prePeriodId){
+					// 	this.$refs.demoCascader.panel.activePath = [];
+					// 	this.prePeriodId = curCheckNodePeriod
+					// 	this.defaultArr = xArr
+					// }
 				}
 				if(xArr.length){
 					curCheckType = this.classList.includes(xArr[0]) ? 'class' : 'stuList'
@@ -192,20 +172,6 @@
 				this.preCheckList = this.defaultArr
 				this.$emit('onChange', this.defaultArr)
 			},
-			findStuList() {
-			    let params = {
-			        code: this.$store.state.userInfo.schoolCode,
-			        scope: 'school'
-			    }
-			    this.$api.courseMgmt.findStulist(params).then(
-			        res => {
-			            this.stuList = res.stuList
-			        },
-			        err => {
-			            this.$Message.error('API error')
-			        }
-			    )
-			},
 		},
 		mounted() {
 			this.$EventBus.$off('onCreateVote')
@@ -223,6 +189,7 @@
 							children: this.getClassesDataByPeriodId(i.id)
 						}
 					})
+					console.log(periodList)
 					return periodList
 				} else {
 					return []

+ 47 - 1
TEAMModelOS/ClientApp/src/common/BaseClassSelectPri.vue

@@ -51,6 +51,7 @@ export default {
     },
     methods: {
         treeChange(data) {
+			console.error(data)
 			if(this.evaluationInfo.scope === 'school'){
 				if(!data.length){
 					this.$refs.demoCascader.panel.activePath = [];
@@ -104,6 +105,51 @@ export default {
 			})
 			console.log(this.classList)
 			console.log(this.stuList)
+		},
+		getTargetList() {
+		    let params = {
+		        tmdid: this.$store.state.userInfo.TEAMModelId,
+		        schoolId: this.$store.state.userInfo.schoolCode,
+		        opt: 'teach'
+		    }
+		    this.$api.common.getActivityTarget(params).then(
+		        res => {
+		            this.privateList = res.groupLists.filter(i => i.scope === 'private')
+		            this.schoolList = res.groupLists.filter(i => i.scope === 'school')
+					if(this.privateList.length){
+						this.privateList.forEach(i => {
+							i.children = i.groups
+						})
+					}
+					if(this.schoolList.length){
+						this.schoolList.forEach(i => {
+							i.children = [
+								{
+									id: 'class',
+									name: this.$t('stuAccount.adminClass'),
+									children: i.groups.filter(j => j.type === 'class')
+								},
+								{
+									id: 'stulist',
+									name: this.$t('stuAccount.teachClass'),
+									children: i.groups.filter(j => j.type === 'teach')
+								}
+							]
+						})
+					}
+					this.classList = []
+					this.schoolList.forEach(i => {
+						this.classList.push(...i.children[0].children.map(j => j.id))
+					})
+					this.stuList = []
+					this.schoolList.forEach(i => {
+						this.stuList.push(...i.children[1].children.map(j => j.id))
+					})
+		        },
+		        err => {
+		            this.$Messag.error('查询发布对象失败')
+		        }
+		    )
 		}
     },
     mounted() {
@@ -113,7 +159,7 @@ export default {
 			this.defaultArr = []
 		})
 		
-		this.getCourseData()
+		this.getTargetList()
     },
     computed: {
 		hasSchool() {

+ 2 - 2
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -395,7 +395,7 @@ export default {
                     },
                     {
                         icon: 'iconfont icon-test',
-                        name: this.$t('system.menu.appAbility'),
+                        name: '小组评分',
                         router: '/home/ability',
                         tag: '',
                         role: 'admin',
@@ -891,7 +891,7 @@ export default {
 html,
 body {
 	 // font-family:"Microsoft YaHei",'微軟正黑體','Microsoft JhengHei UI','Microsoft JhengHei';
-	font-family:'微軟正黑體','Microsoft JhengHei UI','Microsoft JhengHei';
+	// font-family:'微軟正黑體','Microsoft JhengHei UI','Microsoft JhengHei';
 }
 
 .biz-menu .ivu-menu-vertical .ivu-menu-item-group-title {

+ 130 - 0
TEAMModelOS/ClientApp/src/common/PrivateTargetMultiple.vue

@@ -0,0 +1,130 @@
+<template>
+    <!-- 1、挑选名单与课程无关,可以跨课程挑选名单; 2、个人名单、教学班、行政班只能选择其中一种。**使用投票、问卷、作业 -->
+    <div>
+        <RadioGroup v-model="scope" @on-change="scopeChange" style="margin-bottom: 10px;">
+            <Radio label="private">{{ $t('survey.form.privateClass') }}</Radio>
+            <Radio label="school" v-if="hasSchool">{{ $t('survey.form.schoolClass') }}</Radio>
+        </RadioGroup>
+        <el-cascader ref="evtarget" size="small" :options="targetData" :show-all-levels="false" clearable filterable v-model="targets" @visible-change="visibleChange" :props="props" @change="treeChange" style="width:100%;" :popper-class="cascaderClass">
+        </el-cascader>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            scope: 'private',
+            targets: [],
+            allList: [],
+            selectBefore: [],
+            props: {
+                multiple: true,
+                value: 'id',
+                label: 'name'
+            }
+        }
+    },
+    methods: {
+        scopeChange() {
+            this.targets = []
+            this.$emit('on-scope-change', this.scope)
+            this.$emit('on-target-change', this.targets)
+        },
+        visibleChange(status) {
+            if (status) {
+                this.selectBefore = this._.cloneDeep(this.targets)
+            }
+        },
+        treeChange(data) {
+            // 实现教学班和行政班二选一
+            if (this.selectBefore.length && this.scope === 'school') {
+                let curType = new Set()
+                data.forEach(item => {
+                    curType.add(item[0])
+                })
+                if (curType.size > 1) {
+                    let oldType = this.selectBefore[0][0]
+                    let newData = data.filter(item => {
+                        return item[0] != oldType
+                    })
+                    this.targets = []
+                    this.$refs.evtarget.panel.clearCheckedNodes()
+                    this.$refs.evtarget.panel.activePath = []
+                    this.selectBefore = newData
+                    this.targets = newData
+                }
+            } else {
+                this.selectBefore = data
+            }
+
+            this.$emit('on-target-change', this.targets)
+        },
+        getTargetList() {
+            let params = {
+                tmdid: this.$store.state.userInfo.TEAMModelId,
+                schoolId: this.$store.state.userInfo.schoolCode,
+                opt: 'teach'
+            }
+            this.$api.common.getActivityTarget(params).then(
+                res => {
+                    this.allList = res.groupLists
+                },
+                err => {
+                    this.$Messag.error('查询发布对象失败')
+                }
+            )
+        }
+    },
+    created() {
+        this.getTargetList()
+        this.$emit('on-scope-change', this.scope)
+        this.$emit('on-target-change', this.targets)
+    },
+    computed: {
+        hasSchool() {
+            return this.$store.state.userInfo.hasSchool
+        },
+        cascaderClass() {
+            return this.scope == 'school' ? 'one-hidden-check-box' : ''
+        },
+        targetData() {
+            let nodes = []
+            let curCus = this.allList.filter(item => item.scope === this.scope)
+            if (this.scope === 'school') {
+                let classes = []
+                let lists = []
+                curCus.forEach(item => {
+                    item.groups.forEach(group => {
+                        if (group.type === 'class') {
+                            classes.push(group)
+                        } else if (group.type === 'teach') {
+                            lists.push(group)
+                        }
+                    })
+                })
+                nodes.push({
+                    id: 'class',
+                    name: this.$t('cusMgt.listType1'),
+                    children: classes
+                })
+                nodes.push({
+                    id: 'teach',
+                    name: this.$t('cusMgt.listType2'),
+                    children: lists
+                })
+            } else {
+                let ids = []
+                curCus.forEach(item => {
+                    item.groups.forEach(group => {
+                        if (!ids.includes(group.id)) {
+                            ids.push(group.id)
+                            nodes.push(group)
+                        }
+                    })
+                })
+            }
+            return nodes
+        }
+    }
+}
+</script>

+ 156 - 0
TEAMModelOS/ClientApp/src/common/PrivateTargetSingle.vue

@@ -0,0 +1,156 @@
+<template>
+    <!-- 1、挑选名单与课程相关,只能选择单个课程;2、教学班行政班二选一; **适用评测 -->
+    <div>
+        <RadioGroup v-model="scope" @on-change="scopeChange" style="margin-bottom: 10px;">
+            <Radio label="private">{{ $t('learnActivity.createEv.cusLabel2') }}</Radio>
+            <Radio label="school" v-if="hasSchool">{{ $t('learnActivity.createEv.cusLabel1') }}</Radio>
+        </RadioGroup>
+        <el-cascader ref="evtarget" size="small" :options="targetData" :show-all-levels="false" clearable filterable v-model="targets" @visible-change="visibleChange" :props="props" @change="treeChange" style="width:100%;" :popper-class="cascaderClass">
+        </el-cascader>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            scope: 'private',
+            targets: [],
+            allList: [],
+            selectBefore: [],
+            props: {
+                multiple: true,
+                value: 'id',
+                label: 'name'
+            }
+        }
+    },
+    methods: {
+        scopeChange() {
+            this.targets = []
+            this.$emit('on-scope-change', this.scope)
+            this.$emit('on-target-change', {
+                targets: this.targets,
+                course: null
+            })
+        },
+        visibleChange(status) {
+            if (status) {
+                this.selectBefore = this._.cloneDeep(this.targets)
+            }
+        },
+        treeChange(data) {
+            if (this.selectBefore.length) {
+                // 实现课程单选
+                let curCus = new Set()
+                data.forEach(item => {
+                    curCus.add(item[0])
+                })
+                if (curCus.size > 1) {
+                    let oldCus = this.selectBefore[0][0]
+                    let newData = data.filter(item => {
+                        return item[0] != oldCus
+                    })
+                    this.targets = []
+                    this.$refs.evtarget.panel.clearCheckedNodes()
+                    this.$refs.evtarget.panel.activePath = []
+                    this.selectBefore = newData
+                    this.targets = newData
+                }
+                // 实现教学班和行政班二选一
+                if (this.scope === 'school') {
+                    let curType = new Set()
+                    this.targets.forEach(item => {
+                        curType.add(item[1])
+                    })
+                    if (curType.size > 1) {
+                        let oldType = this.selectBefore[0][1]
+                        let newData = this.targets.filter(item => {
+                            return item[1] != oldType
+                        })
+                        this.targets = []
+                        this.$refs.evtarget.panel.clearCheckedNodes()
+                        this.$refs.evtarget.panel.activePath = []
+                        this.selectBefore = newData
+                        this.targets = newData
+                    }
+                }
+            } else {
+                this.selectBefore = data
+            }
+            let course
+            if (this.targets.length) {
+                course = this.allList.find(item => item.id === this.targets[0][0])
+            }
+            this.$emit('on-target-change', {
+                targets: this.targets,
+                course: course
+            })
+        },
+        getTargetList() {
+            let params = {
+                tmdid: this.$store.state.userInfo.TEAMModelId,
+                schoolId: this.$store.state.userInfo.schoolCode,
+                opt: 'teach'
+            }
+            this.$api.common.getActivityTarget(params).then(
+                res => {
+                    this.allList = res.groupLists
+                },
+                err => {
+                    this.$Messag.error('查询发布对象失败')
+                }
+            )
+        }
+    },
+    created() {
+        this.getTargetList()
+        this.$emit('on-scope-change', this.scope)
+        this.$emit('on-target-change', {
+            targets: this.targets,
+            course: null
+        })
+    },
+    computed: {
+        hasSchool() {
+            return this.$store.state.userInfo.hasSchool
+        },
+        cascaderClass() {
+            return 'one-hidden-check-box'
+            // return this.scope == 'school' ? 'one-hidden-check-box' : ''
+        },
+        targetData() {
+            let nodes = this.allList.filter(item => item.scope === this.scope)
+            if (this.scope === 'school') {
+                nodes.forEach(item => {
+                    let classes = []
+                    let lists = []
+                    item.groups.forEach(group => {
+                        if (group.type === 'class') {
+                            classes.push(group)
+                        } else if (group.type === 'teach') {
+                            lists.push(group)
+                        }
+                    })
+                    item.children = []
+                    item.children.push({
+                        id: 'class',
+                        name: this.$t('cusMgt.listType1'),
+                        children: classes
+                    })
+                    item.children.push({
+                        id: 'teach',
+                        name: this.$t('cusMgt.listType2'),
+                        children: lists
+                    })
+                })
+
+            } else {
+                nodes.forEach(item => {
+                    item.children = item.groups
+                })
+            }
+            return nodes
+        }
+    }
+}
+</script>

+ 148 - 0
TEAMModelOS/ClientApp/src/common/SchoolTarget.vue

@@ -0,0 +1,148 @@
+<template>
+    <!-- 教学班和行政班二选 -->
+    <div>
+        <el-cascader ref="evtarget" size="small" :show-all-levels="false" clearable filterable v-model="targets" :options="csOptions" :props="props" @change="treeChange" style="width:100%;">
+        </el-cascader>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            curPeriod: '',
+            curPdInfo: {},
+            targets: [],
+            selectBefore: [],
+            props: {
+                multiple: true,
+                value: 'id',
+                label: 'name'
+            },
+            allList: []
+        }
+    },
+    methods: {
+        visibleChange(status) {
+            if (status) {
+                this.selectBefore = this._.cloneDeep(this.targets)
+            }
+        },
+        treeChange(data) {
+            // 实现教学班和行政班二选一
+            if (this.selectBefore.length) {
+                let curType = new Set()
+                data.forEach(item => {
+                    curType.add(item[0])
+                })
+                if (curType.size > 1) {
+                    let oldType = this.selectBefore[0][0]
+                    let newData = data.filter(item => {
+                        return item[0] != oldType
+                    })
+                    this.targets = []
+                    this.$refs.evtarget.panel.clearCheckedNodes()
+                    this.$refs.evtarget.panel.activePath = []
+                    this.selectBefore = newData
+                    this.targets = newData
+                }
+            } else {
+                this.selectBefore = data
+            }
+            this.$emit('on-change',this.targets)
+        },
+        getTargetList() {
+            let params = {
+                tmdid: this.$store.state.userInfo.TEAMModelId,
+                schoolId: this.$store.state.userInfo.schoolCode,
+                periodId: this.curPeriod,
+                opt: 'manage'
+            }
+            this.$api.common.getActivityTarget(params).then(
+                res => {
+                    this.allList = res.groupLists
+                },
+                err => {
+                    this.$Messag.error('查询发布对象失败')
+                }
+            )
+        }
+    },
+    created() {
+
+    },
+    computed: {
+        //级联选择年级班级
+        csOptions() {
+            let data = []
+            
+            data = [
+                {
+                    id: 'class',
+                    name: this.$t('cusMgt.listType1'),
+                    children: []
+                },
+                {
+                    id: 'stulist',
+                    name: this.$t('cusMgt.listType2'),
+                    // disabled: true,
+                    children: []
+                }
+            ]
+            //填充行政班数据
+            if (this.curPdInfo.id) {
+                //计算学级逻辑
+                let date = new Date()
+                let curYear = date.getFullYear()
+                let month = date.getMonth() + 1
+                let start = this.curPdInfo.semesters.find(item => {
+                    return item.start == 1
+                })
+                // 根据入学月份确定当前年级和学级的关系
+                if (start && month < start.month) {
+                    curYear--
+                }
+                this.curGrades.forEach((item, index) => {
+                    let dataItem = {
+                        id: index,  //年级使用index
+                        name: `${item}(${curYear - index}${this.$t('unit.gradeYear')})`,
+                        year: curYear - index,
+                        children: []
+                    }
+                    let child = this.allList.filter(classItem => {
+                        return (classItem.year == curYear - index) && classItem.type == 'class'
+                    })
+                    dataItem.children = child.length ? child : undefined
+                    data[0].children.push(dataItem)
+                })
+            }
+            // 填充教学班数据
+            let curStuList = this.allList.filter(item => {
+                return item.type == 'teach'
+            })
+            data[1].children.push(...curStuList)
+            return data
+        },
+        //计算当前学段下面的年级信息
+        curGrades() {
+            if (this.curPdInfo.grades) {
+                return this.curPdInfo.grades
+            } else {
+                return []
+            }
+        },
+    },
+    watch: {
+        '$store.state.user.curPeriod': {
+            deep: true,
+            immediate: true,
+            handler(n, o) {
+                if (n) {
+                    this.curPeriod = n.id
+                    this.curPdInfo = n
+                    this.getTargetList()
+                }
+            }
+        }
+    }
+}
+</script>

+ 2 - 2
TEAMModelOS/ClientApp/src/components/homework/BaseHwForm.vue

@@ -524,11 +524,11 @@
 			getClassNameByIds(ids) {
 				return new Promise((r, j) => {
 					this.$api.learnActivity.getClassNameByIds({
-						classes: ids,
+						ids: ids,
 						school: this.$store.state.userInfo.schoolCode
 					}).then(res => {
 						if (!res.error) {
-							r(res.classInfos)
+							r(res.groups)
 						}
 					}).catch(e => {
 						j(e)

+ 5 - 5
TEAMModelOS/ClientApp/src/components/questionnaire/BaseProgress.vue

@@ -82,7 +82,7 @@
 							type: 'gauge',
 							splitNumber: 0,
 							radius: '30%', //中间装饰环
-							center: ['30%', '30%'],
+							center: ['50%', '45%'],
 							startAngle: 0,
 							endAngle: 359.9999,
 							axisLine: {
@@ -131,7 +131,7 @@
 							},
 							coordinateSystem: 'polar',
 							roundCap: true,
-							barWidth: 20, //大的占比环
+							barWidth: 24, //大的占比环
 							itemStyle: {
 							    normal: {
 							        color: new this.$echarts.graphic.LinearGradient(0, 1, 0, 0, [{
@@ -147,7 +147,7 @@
 						{
 							type: 'pie',
 							name: '内层细圆环',
-							radius: ['50%', '40%'],
+							radius: ['50%', '35%'],
 							// radius: '50%',
 							startAngle: 90,
 							hoverAnimation: false,
@@ -156,10 +156,10 @@
 								normal: {
 									color: new that.$echarts.graphic.LinearGradient(0, 0, 1, 1, [{
 										offset: 0,
-										color: '#dfdfdf'
+										color: '#ffffff'
 									}, {
 										offset: 1,
-										color: '#dfdfdf'
+										color: '#ffffff'
 									}]),
 									shadowBlur: 5,
 									shadowColor: '#66666a',

+ 12 - 6
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue

@@ -228,11 +228,12 @@
 			},
 			/* 查找学校检验组信息 */
 			findResearchList() {
-				this.$api.schoolUser.getResearchGroup({
-					code: this.$store.state.userInfo.schoolCode,
-					scope: 'school'
+				this.$api.common.getActivityTarget({
+					tmdid: this.$store.state.userInfo.TEAMModelId,
+					schoolId: this.$store.state.userInfo.schoolCode,
+					opt: 'manage'
 				}).then(res => {
-					this.groupList = res.tchLists
+					this.groupList = res.groupLists.filter(i => i.type === 'research')
 				})
 			},
 
@@ -421,11 +422,16 @@
 			getClassNameByIds(ids) {
 				return new Promise((r, j) => {
 					this.$api.learnActivity.getClassNameByIds({
-						classes: ids,
+						ids: ids,
 						school: this.$store.state.userInfo.schoolCode
 					}).then(res => {
 						if (!res.error) {
-							r(res.classInfos)
+							// 如果根据名单ID没有匹配到名单数据,则显示默认的“未匹配数据”TAG
+							if(res.groups.length){
+								r(res.groups)
+							}else{
+								r(new Array(ids.length).fill({ name:this.$t('vote.form.noMatchDataTip') }))
+							}
 						}
 					}).catch(e => {
 						j(e)

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.less

@@ -3,7 +3,7 @@
   width: 70%;
   padding: 1% 3%;
   height:100%;
-  padding-bottom: 50px;
+  // padding-bottom: 50px;
   overflow: auto;
   overflow-x: hidden;
 

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue

@@ -64,5 +64,5 @@
 </script>
 
 <style lang="less" scoped>
-@import "EventContentArea.less";
+@import "EventContent.less";
 </style>

+ 0 - 42
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.css

@@ -1,42 +0,0 @@
-.eventContentArea-view {
-  float: right;
-  width: 70%;
-  padding: 1% 3%;
-  height: 100%;
-  padding-bottom: 50px;
-  overflow: auto;
-  overflow-x: hidden;
-}
-.eventContentArea-view .noSelected {
-  text-align: center;
-  top: 35%;
-  right: 30%;
-  position: absolute;
-}
-.eventContentArea-view .noSelected h3 {
-  margin-top: 40%;
-  color: #414141;
-}
-.eventContentArea-view .mybutton {
-  width: 100px;
-  margin-top: 20px;
-}
-.eventContentArea-view img {
-  border-radius: 8px;
-  margin-right: 20px;
-  border: 1px solid rgba(173, 173, 173, 0.233);
-}
-.eventContentArea-view .star {
-  color: #ff7300;
-}
-.eventContentArea-view .slide-fade-enter-active {
-  transition: all 0.3s ease;
-}
-.eventContentArea-view .slide-fade-leave-active {
-  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
-}
-.eventContentArea-view .slide-fade-enter,
-.eventContentArea-view .slide-fade-leave-to {
-  transform: translateY(-5%);
-  opacity: 0;
-}

+ 0 - 19
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentArea.vue

@@ -1,19 +0,0 @@
-<template>
-  <div class="eventContentArea-view">
-    <EventContent></EventContent>
-  </div>
-</template>
-
-<script>
-import EventContent from "./EventContent";
-export default {
-  name: "EventContentArea",
-  components: {
-    EventContent
-  }
-};
-</script>
-
-<style scoped>
-@import "EventContentArea.css";
-</style>

+ 11 - 9
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/KeyPointPerformChart.vue

@@ -110,16 +110,18 @@ export default {
         getknowledge() {
             let kps = []
             let ckps = []
-            this.knowledge.kn.map((item, index) => {
-                kps.push({
-                    value: this.knowledge.kps[index] ? this.knowledge.kps[index].toFixed(2) : 0,
-                    name: item
+            if (this.knowledge.kn) {
+                this.knowledge.kn.map((item, index) => {
+                    kps.push({
+                        value: this.knowledge.kps[index] ? this.knowledge.kps[index].toFixed(2) : 0,
+                        name: item
+                    })
+                    ckps.push({
+                        value: this.knowledge.ckps[index] ? this.knowledge.ckps[index].toFixed(2) : 0,
+                        name: item
+                    })
                 })
-                ckps.push({
-                    value: this.knowledge.ckps[index] ? this.knowledge.ckps[index].toFixed(2) : 0,
-                    name: item
-                })
-            })
+            }
             this.kps = kps
             this.ckps = ckps
         },

+ 6 - 4
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReportCharts/RecognizePerformChart.vue

@@ -94,10 +94,12 @@ export default {
         getFiled() {
             let fps = []
             let cfps = []
-            this.filed.fs.map((item, index) => {
-                fps.push(this.filed.fps[index] ? this.filed.fps[index].toFixed(2) : 0)
-                cfps.push(this.filed.cfps[index] ? this.filed.cfps[index].toFixed(2) : 0)
-            })
+            if (this.filed.fs) {
+                this.filed.fs.map((item, index) => {
+                    fps.push(this.filed.fps[index] ? this.filed.fps[index].toFixed(2) : 0)
+                    cfps.push(this.filed.cfps[index] ? this.filed.cfps[index].toFixed(2) : 0)
+                })
+            }
             this.fps = fps
             this.cfps = cfps
         },

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

@@ -1,7 +1,6 @@
 <template>
     <div class="event-view">
         <EventList :class="{ 'hide-sidebars': getSidebarisOpen == false}"></EventList>
-        <!-- <EventContentArea :class="{'eventContentArea-Span': getSidebarisOpen == false}"></EventContentArea> -->
         <EventContent :class="{'eventContentArea-Span': getSidebarisOpen == false}"></EventContent>
         <!--<CommentList v-if=" $store.getters.getOpenCommentList == true && getSidebarisOpen == false" />-->
     </div>
@@ -10,14 +9,12 @@
 <script>
     import CommentList from "./CommentList.vue";
     import EventList from "./EventList";
-    import EventContentArea from "./EventContentArea.vue";
     import EventContent from "./EventContent.vue";
     import { mapGetters } from 'vuex';
     export default {
         name: "EventView",
         components: {
             EventList,
-            EventContentArea,
             CommentList,
             EventContent,
         },

+ 0 - 412
TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseContent.vue

@@ -1,412 +0,0 @@
-<template>
-    <div>
-        <loading :active.sync="isLoad"
-                 :is-full-page="true"
-                 background-color="#000"
-                 :opacity="0.6">
-            <template slot="default">
-                <svg-icon icon-class="loader" class="loader-icon" />
-            </template>
-        </loading>
-        <div class="course-content"
-            :class="{ courseContentEn: this.$store.getters.getCurrentLaguage == 'en-us' }"
-            v-if="showInfo"
-        >
-            <h2>{{ course.course.name }}</h2>
-            <!-- <h3 class="course-subject">國中/二年級/{{course.courseSubject}}</h3> -->
-            <div @click="changeGroupView()"
-                :class="{ 'group-on': isChangeGroupView }"
-                v-if="name == 'tab3'"
-            >
-                <svg-icon icon-class="group" class="group-btn" />
-            </div>
-
-            <Tabs v-model="name">
-                <!-- 基本资讯 -->
-                <TabPane :label="$t('studentWeb.courseContent.baseInfo')" name="tab1">
-                    <Row :gutter="30">
-                        <i-col :xs="24" :sm="24" :md="8" :lg="8">
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.classID") }}</h4>
-                            <h4 class="basic-data">{{ course.course.no }}</h4>
-
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.classTime") }}</h4>
-                            <h4 class="basic-data">{{ course.classTime }}</h4>
-
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.classroom") }}</h4>
-                            <h4 class="basic-data">{{ course.roomName }}</h4>
-
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.teacher") }}</h4>
-                            <h4 class="basic-data">{{ course.course.teaName }}</h4>
-
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.co-teacher") }}</h4>
-                            <!-- <span class="basic-data"
-                                v-for="(teacher, index) in course.assistantTeachers"
-                                :key="index"
-                            >
-                                {{ teacher }}
-                                <span v-if="index < course.assistantTeachers.length - 1">、</span>
-                            </span> -->
-
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.addedTime") }}</h4>
-                            <h4 class="basic-data">{{ course.courseAddDate }}</h4>
-                        </i-col>
-                        <i-col :xs="24" :sm="24" :md="16" :lg="16">
-                            <h4 class="basic-title">{{ $t("studentWeb.courseContent.courseCode") }}</h4>
-                            <img src="mockqrcode.jpg" width="30%" style='margin-left: -12px'>
-                        </i-col>
-                    </Row>
-                </TabPane>
-                <!-- 课程概述 -->
-                <TabPane :label="$t('studentWeb.courseContent.description')" name="tab2">
-                    {{ course.notice }}
-                    <h3 style="margin-top: 30px; margin-bottom: 10px">{{ $t("studentWeb.courseContent.syllabus") }}</h3>
-                    <Collapse simple>
-                        <Panel name="1">
-                            1. 史蒂夫·乔布斯
-                            <div slot="content">
-                                史蒂夫·乔布斯(Steve
-                                Jobs),1955年2月24日生于美国加利福尼亚州旧金山,美国发明家、企业家、美国苹果公司联合创办人。
-                                <br />
-                                <br />
-                                <Collapse simple>
-                                    <Panel name="1-1">
-                                        iPhone
-                                        <p slot="content">
-                                        iPhone,是美国苹果公司研发的智能手机,它搭载iOS操作系统。第一代iPhone于2007年1月9日由苹果公司前首席执行官史蒂夫·乔布斯发布,并在2007年6月29日正式发售。
-                                        </p>
-                                    </Panel>
-                                    <Panel name="1-2">
-                                        iPad
-                                        <p slot="content">
-                                        iPad是由苹果公司于2010年开始发布的平板电脑系列,定位介于苹果的智能手机iPhone和笔记本电脑产品之间,(屏幕中有4个虚拟程序固定栏)与iPhone布局一样,提供浏览网站、收发电子邮件、观看电子书、播放音频或视频、玩游戏等功能。由英国出生的设计主管乔纳森·伊夫(Jonathan
-                                        Ive)(有些翻译为
-                                        乔纳森·艾维)领导的团队设计的,这个圆滑、超薄的产品反映出了伊夫对德国天才设计师Dieter
-                                        Rams的崇敬之情。
-                                        </p>
-                                    </Panel>
-                                </Collapse>
-                            </div>
-                        </Panel>
-                        <Panel name="2">
-                            2. 斯蒂夫·盖瑞·沃兹尼亚克
-                            <p slot="content">
-                            斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary
-                            Wozniak),美国电脑工程师,曾与史蒂夫·乔布斯合伙创立苹果电脑(今之苹果公司)。斯蒂夫·盖瑞·沃兹尼亚克曾就读于美国科罗拉多大学,后转学入美国著名高等学府加州大学伯克利分校(UC
-                            Berkeley)并获得电机工程及计算机(EECS)本科学位(1987年)。
-                            </p>
-                        </Panel>
-                        <Panel name="3">
-                            3. 乔纳森·伊夫
-                            <p slot="content">
-                            乔纳森·伊夫是一位工业设计师,现任Apple公司设计师兼资深副总裁,英国爵士。他曾参与设计了iPod,iMac,iPhone,iPad等众多苹果产品。除了乔布斯,他是对苹果那些著名的产品最有影响力的人。
-                            </p>
-                        </Panel>
-                    </Collapse>
-                </TabPane>
-                <!-- 同学名单 -->
-                <TabPane :label="$t('studentWeb.courseContent.classmates')" name="tab3">
-                    <div v-show="!isChangeGroupView">
-                        <Table :columns="stuCol" :data="stuList">
-                            <template slot-scope="{ row }" slot="no">
-                                <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                    {{row.no}}
-                                </p>
-                            </template>
-                            <template slot-scope="{ row }" slot="id">
-                                <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                    {{row.id}}
-                                </p>
-                            </template>
-                            <template slot-scope="{ row }" slot="name">
-                                <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                    {{row.name}}
-                                </p>
-                            </template>
-                            <template slot-scope="{ row }" slot="groupName">
-                                <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                    {{row.groupName ? row.groupName : $t("studentWeb.courseContent.noGroup")}}
-                                </p>
-                            </template>
-                        </Table>
-                    </div>
-                    <!--小組模式-->
-                    <div v-show="isChangeGroupView">
-                        <Card class="group-student"
-                            v-for="(group, gIndex) in stuGroup"
-                            :key="gIndex">
-                            <h3 class="group-title" v-if="group.name">
-                                {{ group.name }}
-                            </h3>
-                            <h3 class="group-title" v-else>{{ $t("studentWeb.courseContent.noGroup") }}</h3>
-                            <table>
-                                <tr v-for="(item, index) in group.info"
-                                    :key="`a${index}`"
-                                >
-                                    <td class="student-no" :class="{ 'my-name': item.id == $store.state.userInfo.sub }">
-                                        {{ item.no }}
-                                    </td>
-                                    <td class="student-name" :class="{ 'my-name': item.id == $store.state.userInfo.sub }">
-                                        {{ item.name }}
-                                        <span v-if="item.id == $store.state.userInfo.sub">({{ $t("studentWeb.courseContent.me") }})</span>
-                                    </td>
-                                </tr>
-                            </table>
-                        </Card>
-                    </div>
-                </TabPane>
-                <!-- 醍摩豆 -->
-                <TabPane :label="$t('studentWeb.courseContent.classmates1')" name="tab4" v-if="tmdList.length > 0 || $store.state.userInfo.roles.includes('teacher')">
-                    <Table :columns="tmdCol" :data="tmdList">
-                        <template slot-scope="{ row }" slot="id">
-                            <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                {{row.id}}
-                            </p>
-                        </template>
-                        <template slot-scope="{ row }" slot="name">
-                            <p :class="{'my-name': row.id == $store.state.userInfo.sub}">
-                                {{row.name}}
-                            </p>
-                        </template>
-                    </Table>
-                </TabPane>
-            </Tabs>
-        </div>
-    </div>
-</template>
-
-<script>
-import loading from "vue-loading-overlay";
-import "vue-loading-overlay/dist/vue-loading.css";
-import { mapGetters } from 'vuex';
-export default {
-    name: "courseContent",
-    components: {
-        loading
-    },
-    data(vm) {
-        return {
-            isLoad: false,
-            showInfo: false,
-            isChangeGroupView: false, //控制名单样式
-            name: "tab1",
-            istab3Now: false,
-            week: [{
-                name: "MON",
-                cn: vm.$t("studentWeb.week.mon")
-            }, {
-                name: "TUE",
-                cn: vm.$t("studentWeb.week.tue")
-            }, {
-                name: "WED",
-                cn: vm.$t("studentWeb.week.wed")
-            }, {
-                name: "THU",
-                cn: vm.$t("studentWeb.week.thu")
-            }, {
-                name: "FRI",
-                cn: vm.$t("studentWeb.week.fri")
-            }],
-            stuCol: [
-                {
-                    title: vm.$t("studentWeb.courseContent.seatNo"),
-                    slot: "no",
-                },
-                {
-                    title: vm.$t("studentWeb.courseContent.stuNum"),
-                    slot: "id",
-                },
-                {
-                    title: vm.$t("studentWeb.courseContent.name"),
-                    slot: "name",
-                },
-                {
-                    title: vm.$t("studentWeb.courseContent.group"),
-                    slot: "groupName",
-                }
-            ],
-            tmdCol: [
-                {
-                    title: vm.$t("studentWeb.courseContent.tmdNum"),
-                    slot: "id",
-                },
-                {
-                    title: vm.$t("studentWeb.courseContent.name"),
-                    slot: "name",
-                },
-            ],
-            stuGroup: [], //学生——小组名单
-            stuList: [], //学生——table
-            tmdList: [], //醍摩豆列表
-        };
-    },
-    props: {
-        roomList: {
-            type: Array,
-            default: []
-        },
-        course: {
-            type: Object,
-            default: {}
-        }
-    },
-    mounted () {
-        if(Object.keys(this.course).length) {
-            this.isLoad = true
-            this.isNoInfo = false
-            this.showInfo = true
-            // 处理时间
-            if(this.course.course.timeWeek) {
-                this.week.map(item => {
-                    if(item.name == this.course.course.timeWeek) {
-                        this.course.classTime = item.cn + " " + this.course.time
-                    }
-                })
-            }
-            else {
-                this.course.classTime = this.$t("studentWeb.courseContent.noTime")
-            }
-            this.course.roomName = this.$t("studentWeb.courseContent.noRoom")
-            // 获取教室名称
-            if(this.roomList) {
-                for (let i = 0; i < this.roomList.length; i++) {
-                    if(this.roomList[i].id == this.course.course.room) {
-                        this.course.roomName = this.roomList[i].name
-                        break
-                    }
-                }
-            }
-            // 获取学生名单
-            if(this.course.course.classId != "" && this.course.course.classId) {
-                this.findStuInfor(this.course.course)
-            } else if(this.course.course.stuList != "") {
-                this.findPersonInfo(this.course.course)
-            }
-        }  
-    },
-    methods: {
-        changeGroupView() {
-            this.isChangeGroupView = !this.isChangeGroupView
-        },
-        // 查找学生信息(标准)
-        findStuInfor(course) {
-            this.stuGroup = []
-            this.stuList = []
-            let req = {
-                school_code: course.school,
-                scope: course.scope,
-                ids: [course.classId]
-            }
-            this.$api.studentWeb.getClassroomStudent(req).then(res => {
-                this.stuList = this._.cloneDeep(res.stus[0])
-                this.getGroup(res.stus[0])
-            }).finally(() => {
-                this.isLoad = false
-            })
-        },
-        // 查找学生(个人)
-        findPersonInfo(course) {
-            this.stuGroup = []
-            this.stuList = []
-            this.tmdList = []
-            let reqList = {
-                code: course.scope == 'school' ? course.school : course.creatorId,
-                // code: course.teacherId,
-                ids: [course.stuList],
-                scope: course.scope
-            }
-            this.$api.studentWeb.findListSummary(reqList).then(res => {
-                if(res.stuList.length) {
-                    if(res.stuList[0].students.length) {
-                        this.$api.studentWeb.findStuSummary({
-                            students: res.stuList[0].students,
-                            tmdIds: res.stuList[0].tmids
-                        }).then(res => {
-                            if(res.stus.length) {
-                                this.stuList = this._.cloneDeep(res.stus)
-                                this.tmdList = this._.cloneDeep(res.tmdinfos)
-                                this.getGroup(res.stus)
-                            }
-                        }).finally(() => {
-                            this.isLoad = false
-                        })
-                    } else {
-                        this.isLoad = false
-                    }
-                } else {
-                    this.isLoad = false
-                }
-            })
-        },
-        // 学生分组
-        getGroup(data) {
-            for (let i = 0; i < data.length; i++) {
-                this.stuGroup.push({
-                    id: data[i].groupId,
-                    name: data[i].groupName,
-                    info: [data[i]]
-                })
-                for (let j = i + 1; j < data.length; j++) {
-                    if(data[i].groupId == data[j].groupId) {
-                        this.stuGroup[i].info.push(data[j])
-                        data.splice(j,1)
-                        j--
-                    }
-                }
-            }
-        },
-    },
-    computed: {
-        // 当前的活动
-        ...mapGetters(["getItemTitle"]),
-    },
-    watch: {
-        course: {
-            /* handler(n, o) {
-                console.log('2101010')
-                this.showInfo = false
-                if(Object.keys(n).length) {
-                    this.isLoad = true
-                    this.isNoInfo = false
-                    this.showInfo = true
-                    // 处理时间
-                    if(n.course.timeWeek) {
-                        this.week.map(item => {
-                            if(item.name == n.course.timeWeek) {
-                                n.classTime = item.cn + " " + n.time
-                            }
-                        })
-                    }
-                    else {
-                        n.classTime = this.$t("studentWeb.courseContent.noTime")
-                    }
-                    n.roomName = this.$t("studentWeb.courseContent.noRoom")
-                    // 获取教室名称
-                    if(this.roomList) {
-                        for (let i = 0; i < this.roomList.length; i++) {
-                            if(this.roomList[i].id == n.course.room) {
-                                n.roomName = this.roomList[i].name
-                                break
-                            }
-                        }
-                    }
-                    // 获取学生名单
-                    if(n.course.classId != "" && n.course.classId) {
-                        this.findStuInfor(n.course)
-                    } else if(n.course.stuList != "") {
-                        this.findPersonInfo(n.course)
-                    }
-                }
-                else {
-                    console.log(222222, n);
-                }
-            } */
-        },
-        immediate: true,
-        deep:true
-    }
-}
-</script>
-
-<style scoped>
-@import "~@/assets/student-web/component_styles/course-content.css";
-</style>

+ 0 - 535
TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseList.vue

@@ -1,535 +0,0 @@
-<template>
-    <div>
-        <loading :active.sync="isLoad"
-                 :is-full-page="fullPage"
-                 background-color="#000"
-                 :opacity="opacity">
-            <template slot="default">
-                <svg-icon icon-class="loader" class="loader-icon" />
-            </template>
-        </loading>
-        <div class="course-list"
-            :class="{ courselistEn: this.$store.getters.getCurrentLaguage == 'en-us' }"
-        >
-            <!--課程加入成功-->
-            <div class="warmMessage"
-                v-if=" this.$store.getters.getMycID.coureseMessageOpen == true &&
-                        this.$store.getters.getMycID.addSuccess == true "
-            >
-                <div class="messageCard animate__animated animate__fadeInDown">
-                    <div>
-                        <h3>課程加入成功</h3>
-                        <svg-icon icon-class="addCourseSuc" class="addCourseIcon" />
-
-                        <h3>
-                            <span class="typeMark">{{ this.$store.getters.getMycID.myCourseID[  this.$store.getters.getMycID.myCourseID.length - 1 ] }}</span>
-                            <span>新加課程名稱</span>
-                        </h3>
-                        <p>可於左側課程清單檢視課程簡介</p>
-                    </div>
-                </div>
-            </div>
-
-            <!--課程已經加入-->
-            <div class="warmMessage"
-                v-if="this.$store.getters.getMycID.coureseMessageOpen == true &&
-                    this.$store.getters.getMycID.addSuccess == 'exist'"
-            >
-                <div class="messageCard animate__animated animate__fadeInDown">
-                    <div>
-                        <h3>課程已經加入</h3>
-                        <svg-icon icon-class="addCoursefail" class="addCourseIcon" />
-                        <p>可於左側課程清單檢視該課程簡介</p>
-                    </div>
-                </div>
-            </div>
-
-            <!--課程加入失敗-->
-            <div class="warmMessage"
-                v-if="this.$store.getters.getMycID.coureseMessageOpen == true &&
-                    this.$store.getters.getMycID.addSuccess == false"
-            >
-                <div class="messageCard animate__animated animate__fadeInDown">
-                    <div>
-                        <h3>課程加入失敗</h3>
-                        <svg-icon icon-class="addCoursefail" class="addCourseIcon" />
-                        <p>查無所輸入代碼之課程,或該課程您未獲教師授權參與</p>
-                    </div>
-                </div>
-            </div>
-
-            <div class="list">
-                <ul class="list-block">
-                    <Tabs :value="onlyStu ? (this.$store.getters.getMycID.addSuccess == true ? 'tab2' : 'tab1') : 'tab2' ">
-                        <!-- 表定课程 -->
-                        <TabPane :label="$t('studentWeb.defaultClass')"
-                                name="tab1"
-                                :align="currentView=='table'?'center':'left'"
-                                v-if="onlyStu"
-                        >
-                            <!-- <div class="listViewBtn" @click="changeView('list')" :class="{chooseView:currentView=='list'}">
-                                <svg-icon icon-class="list-text" />
-                            </div>
-                            <div class="tableViewBtn" @click="changeView('table')" :class="{chooseView:currentView=='table'}">
-                                <svg-icon icon-class="table" />
-                            </div> -->
-
-                            <div class="list-table">
-                                <Table :columns="courseTime"
-                                        border
-                                        :data="timeTable"
-                                        v-show="currentView == 'table'"
-                                        :disabled-hover="true"
-                                >
-                                    <!-- 时间 -->
-                                    <template slot-scope="{ row }" slot="time">
-                                        <p class="list-name">{{ row.time }}</p>
-                                        <p>{{ row.label }}</p>
-                                    </template>
-                                    <!-- 周一 -->
-                                    <template slot-scope="{ row }" slot="Mon">
-                                        <div v-for="(item, index) in row.fixList" :key="index">
-                                            <div v-if="item.timeWeek == 'MON'"
-                                                class="table-item"
-                                                @click="clickCell(row, index)"
-                                                :class="{'table-item-selected': selectedCondition(item) }"
-                                            >
-                                                <p class="list-name">{{ item.name}}</p>
-                                                <p>({{ item.teaName}})</p>
-                                            </div>
-                                        </div>
-                                    </template>
-                                    <!-- 周二 -->
-                                    <template slot-scope="{ row }" slot="Tue">
-                                        <div v-for="(item, index) in row.fixList" :key="index">
-                                            <div v-if="item.timeWeek == 'TUE'"
-                                                class="table-item"
-                                                @click="clickCell(row, index)"
-                                                :class="{'table-item-selected': selectedCondition(item) }"
-                                            >
-                                                <p class="list-name">{{ item.name}}</p>
-                                                <p>({{ item.teaName}})</p>
-                                            </div>
-                                        </div>
-                                    </template>
-                                    <!-- 周三 -->
-                                    <template slot-scope="{ row }" slot="Wed">
-                                        <div v-for="(item, index) in row.fixList" :key="index">
-                                            <div v-if="item.timeWeek == 'WED'"
-                                                class="table-item"
-                                                @click="clickCell(row, index)"
-                                                :class="{'table-item-selected': selectedCondition(item) }"
-                                            >
-                                                <p class="list-name">{{ item.name}}</p>
-                                                <p>({{ item.teaName}})</p>
-                                            </div>
-                                        </div>
-                                    </template>
-                                    <!-- 周四 -->
-                                    <template slot-scope="{ row }" slot="Thu">
-                                        <div v-for="(item, index) in row.fixList" :key="index">
-                                            <div v-if="item.timeWeek == 'THU'"
-                                                class="table-item"
-                                                @click="clickCell(row, index)"
-                                                :class="{'table-item-selected': selectedCondition(item) }"
-                                            >
-                                                <p class="list-name">{{ item.name}}</p>
-                                                <p>({{ item.teaName}})</p>
-                                            </div>
-                                        </div>
-                                    </template>
-                                    <!-- 周五 -->
-                                    <template slot-scope="{ row }" slot="Fri">
-                                        <div v-for="(item, index) in row.fixList" :key="index">
-                                            <div v-if="item.timeWeek == 'FRI'"
-                                                class="table-item"
-                                                @click="clickCell(row, index)"
-                                                :class="{'table-item-selected': selectedCondition(item) }"
-                                            >
-                                                <p class="list-name">{{ item.name}}</p>
-                                                <p>({{ item.teaName}})</p>
-                                            </div>
-                                        </div>
-                                    </template>
-                                </Table>
-                            </div>
-
-                            <!-- 表定 -->
-                            <!-- <li class="list-item"
-                                v-for="(item, index) in fixList"
-                                @click="sentSelectedEventTitle(item)"
-                                :class="{ 'list-item-selected': unique == item.unique }"
-                                :key="index"
-                                v-show="currentView == 'list'"
-                            >
-                                <ul>
-                                    <li class="list-item-info">
-                                        <p class="list-item-title">
-                                            <span class="list-item-typeMark">{{ item.no }}</span>
-                                            {{ item.name }}
-                                        </p>
-                                    </li>
-                                </ul>
-                            </li> -->
-                        </TabPane>
-                        <!-- 临时课程 -->
-                        <TabPane :label="$t('studentWeb.tempClass')" name="tab2">
-                        <!--剛加入的課程-->
-                        <!-- <li
-                            class="list-item"
-                            @click="
-                            sentSelectedEventTitle(
-                                courseList[courseList.length - index - 2]
-                            )
-                            "
-                            :class="{
-                            'list-item-selected': selectedCondition(
-                                courseList[courseList.length - index - 2]
-                            ),
-                            }"
-                            v-for="(item,
-                            index) in this.$store.getters.getMycID.myCourseID
-                            .slice()
-                            .reverse()"
-                            :key="`c+${index}`"
-                        >
-                            <ul>
-                            <li class="list-item-info">
-                                <p class="list-item-title">
-                                <span class="list-item-typeMark">{{ item }}</span>
-                                {{ "新加課程名稱" }}
-                                </p>
-                            </li>
-                            </ul>
-                        </li> -->
-                        <!--剛加入的課程-->
-                            <div v-if="personList.length">
-                                <!-- <div v-for="(item, index) in timeTable" :key="index"> -->
-                                    <li
-                                        class="list-item"
-                                        v-for="(person, num) in personList"
-                                        :class="{'list-item-selected': selectedCondition(person)}"
-                                        @click="clickCell(person, num, 'list')"
-                                        :key="`j+${num}`"
-                                    >
-                                        <ul>
-                                            <li class="list-item-info">
-                                                <p class="list-item-title">
-                                                    <span class="list-item-typeMark">{{ person.no }}</span>
-                                                    {{ person.name }}({{ person.teaName }})
-                                                </p>
-                                            </li>
-                                        </ul>
-                                    </li>
-                                <!-- </div> -->
-                            </div>
-                            <div v-else class="list-item-no">
-                                {{ $t('studentWeb.courseContent.noCourse') }}
-                            </div>
-                        </TabPane>
-                    </Tabs>
-                </ul>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-import Loading from "vue-loading-overlay";
-import "vue-loading-overlay/dist/vue-loading.css";
-import { mapGetters, mapState } from 'vuex';
-export default {
-    name: "CourseList",
-    components: {
-        Loading
-    },
-    data() {
-        return {
-            isLoad: false,
-            fullPage: true,
-            opacity: 0.6,
-            currentView: 'table',
-            onlyStu: true, //是不是学生
-            courseTime: [
-                {
-                    title: this.$t("studentWeb.week.time"),
-                    slot: "time",
-                    width: "140"
-                },
-                {
-                    title: this.$t("studentWeb.week.mon"),
-                    slot: "Mon",
-                    width: "115"
-                },
-                {
-                    title: this.$t("studentWeb.week.tue"),
-                    slot: "Tue",
-                    width: "115"
-                },
-                {
-                    title: this.$t("studentWeb.week.wed"),
-                    slot: "Wed",
-                    width: "115"
-                },
-                {
-                    title: this.$t("studentWeb.week.thu"),
-                    slot: "Thu",
-                    width: "115"
-                },
-                {
-                    title: this.$t("studentWeb.week.fri"),
-                    slot: "Fri",
-                    width: "115"
-                },
-                {
-                    title: this.$t("studentWeb.week.sat"),
-                    // slot: "Fri",
-                    width: "100"
-                },
-                {
-                    title: this.$t("studentWeb.week.sun"),
-                    // slot: "Fri",
-                    width: "100"
-                }
-            ],
-            courseList: this.$api.studentWeb.courseList, //moke数据
-            fixList: [], //表定课程
-            personList: [], //临时课程
-            nowClassInfor: {},
-            timeTable: [], //页面所有的课程
-            unique: '',
-        };
-    },
-    props: {
-        period: {
-            type: Array,
-            default: []
-        },
-        teaList: {
-            type: Array,
-            default: []
-        }
-    },
-    created() {
-        this.userInfo.roles.map(item => {
-            if(item == "teacher") {
-                this.onlyStu = false
-            }
-        })
-        this.getClassList()
-    },
-    mounted () {
-        this.selectedCondition(this.getItemTitle)
-    },
-    methods: {
-        getClassList() {
-            this.isLoad = true
-            let param = {
-                userid: this.userInfo.sub,
-                school: this.userInfo.azp
-            }
-            if(this.userInfo.roles.includes("teacher")) {
-                param.userType = "tmdid"
-            } else {
-                param.userType = "schoolid"
-            }
-            this.$api.studentWeb.getClassList(param).then(res => {
-                if(res.courses.length) {
-                    // 表定课程
-                    var fixList = []
-                    // 临时课程
-                    var personList = []
-                    var list = res.courses
-                    list.forEach(item => {
-                        if(item.course) {
-                            item.course.schedule.forEach(sch => {
-                                // 有classId,表定课程
-                                if(sch.classId == item.stuCourse.classId[0]) {
-                                    if(sch.time.length > 0) {
-                                        for (let m = 0; m < sch.time.length; m++) {
-                                            let data = this.getNewCourse("class", item, sch, m)
-                                            fixList.push(data)
-                                        }
-                                    }
-                                    else {
-                                        let datanoTime = this.getNewCourse("class", item, sch)
-                                        fixList.push(datanoTime)
-                                    }
-                                }
-                                // 有stulist,临时课程
-                                else if (sch.stulist) {
-                                    if(sch.time.length) {
-                                        for (let m = 0; m < sch.time.length; m++) {
-                                            let data = this.getNewCourse("person", item, sch, m)
-                                            personList.push(data)
-                                        }
-                                    }
-                                    // 没有时间
-                                    else {
-                                        let data = this.getNewCourse("person", item, sch)
-                                        personList.push(data)
-                                    }
-                                }
-                            })
-                        }
-                    })
-                    this.fixList = fixList
-                    this.personList = personList
-                    this.getClassTime()
-                }
-            }).finally(()=>{
-                this.isLoad = false
-            })
-            
-        },
-        // 课程的相关信息(attribute: "class/person")
-        getNewCourse(attribute, subject, schedule, m) {
-            let data = this._.cloneDeep(subject.course)
-            delete data.schedule
-            data.school = subject.stuCourse.school
-            data.scope = subject.stuCourse.scope
-            data.classId = schedule.classId
-            data.roomId = schedule.room
-            data.teacherId = schedule.teacherId
-            data.notice = schedule.notice
-            data.stuList = schedule.stulist
-            if(m !== undefined) {
-                data.timeId = schedule.time[m].id
-                data.timeWeek = schedule.time[m].week
-                // 拼接得到一个唯一的标识
-                data.unique = attribute + subject.course.no + schedule.time[m].week + schedule.time[m].id + m + Math.floor(Math.random() * 10000)
-            }
-            // 没有时间的情况
-            else {
-                data.timeId = 0
-                data.timeWeek = 0
-                data.unique = attribute + subject.course.no + Math.floor(Math.random() * 100000000)
-            }
-            data.teaName = this.$t('studentWeb.courseContent.noTeacher')
-            // 获取老师名单
-            if(this.teaList.length > 0) {
-                this.teaList.forEach(item => {
-                    if(item.id == data.teacherId) {
-                        data.teaName = item.name
-                    }
-                })
-            }
-            return data
-        },
-        // 处理上课时间
-        getClassTime() {
-            // 学生登陆
-            if(this.onlyStu) {
-                this.timeTable = this.period.find(item => {
-                    return item.id == this.studentProfile.classinfo.periodId
-                }).timetable
-                this.timeTable.forEach(item => {
-                    let newfixlist = []
-                    let notime = [] //没有时间的标准课程
-                    this.fixList.forEach(fix => {
-                        if(fix.timeId == item.id && fix.timeId) {
-                            newfixlist.push(fix)
-                        }
-                        // 没有时间的标准课程
-                        else if (!fix.timeId) {
-                            notime.push(fix)
-                        }
-                    })
-                    item.fixList = newfixlist
-                    item.noTime = notime
-                })
-                // 个人课程
-                this.personList.forEach(per => {
-                    if(per.timeId) {
-                        this.timeTable.forEach(item => {
-                            if(per.timeId == item.id) {
-                                per.time = item.time
-                            }
-                        })
-                    }
-                })
-            }
-            // 醍摩豆登陆
-            else if (this.personList.length) {
-                // 年级id 存在
-                if(this.personList[0].period.id != undefined) {
-                    this.timetable = this.period.find(item => {
-                        return item.id == this.personList[0].period.id
-                    }).timetable
-                    this.timeTable.forEach(item => {
-                        let newpersonList = []
-                        this.personList.forEach(per => {
-                            if(per.timeId == item.id && per.timeId) {
-                                newpersonList.push(per)
-                            } else if (!per.timeId) {
-                                newpersonList.push(per)
-                            }
-                        })
-                        item.personList = newpersonList
-                    })
-                }
-                // 年级id 不存在
-                else {
-                    this.timeTable = [{
-                        personList: []
-                    }]
-                    this.personList.forEach(per => {
-                        this.timeTable[0].personList.push(per)
-                    })
-                }
-            }
-        },
-        // 点击单节课,显示基本信息
-        /* row:timeTable的某一个
-           index:fixList/personList中的当前这一数据的下标
-           type:传'list'就是临时课程,不传就是表定课程
-        */
-        clickCell(row, index, type) {
-            this.nowClassInfor = this._.cloneDeep(row)
-            if(type) {
-                this.nowClassInfor.course = this._.cloneDeep(row)
-            } else {
-                this.nowClassInfor.course = this._.cloneDeep(row.fixList[index])
-            }
-            this.unique = this.nowClassInfor.course.unique
-            this.sentSelectedEventTitle(this.nowClassInfor)
-        },
-        changeView(type) {
-            this.currentView = type
-        },
-        selectedCondition(item) {
-            if(Object.keys(this.getItemTitle).length) {
-                if (this.getItemTitle.course.id == item.id
-                    && this.getItemTitle.course.teacherId == item.teacherId
-                    && this.getItemTitle.course.timeId == item.timeId
-                    && this.getItemTitle.course.timeWeek == item.timeWeek
-                    && this.getItemTitle.course.roomId == item.roomId
-                ) {
-                    console.log(11111);
-                    return true;
-                } else return false;
-            }
-        },
-        // 跳转到当前课程
-        sentSelectedEventTitle: function (item) {
-            // 改變ItemName的狀態 vuex mutations
-            this.$store.commit("ChangeItemName", item);
-            // 螢幕寬度<767px時,直接關掉sidebar
-            if (window.innerWidth <= 991) {
-                this.$store.commit("ToggleSidebar", false);
-            }
-        },
-    },
-    computed: {
-        ...mapState({
-            userInfo: state => state.userInfo,
-            studentProfile: state => state.user.studentProfile
-        }),
-        ...mapGetters(["getItemTitle"])
-    }
-};
-</script>
-
-<style scoped>
-@import "~@/assets/student-web/component_styles/course-list.css";
-</style>

+ 25 - 46
TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseListView.vue

@@ -515,57 +515,35 @@ export default {
             this.isChangeGroupView = !this.isChangeGroupView
         },
         // 查找学生信息(标准)
-        findStuInfor(course) {
+        findStuInfor(course, haveClass) {
             this.stuGroup = []
             this.stuList = []
             let req = {
-                school_code: course.school,
-                scope: course.scope,
-                ids: [course.classId]
+                ids: []
             }
-            this.$api.studentWeb.getClassroomStudent(req).then(res => {
-                if(res.list.length && res.list[0].students.length) {
-                    this.stuList = this._.cloneDeep(res.list[0].students)
-                    this.getGroup(res.list[0].students)
+            // 行政班才传schoolId
+            if(haveClass) {
+                req.ids = [course.classId]
+                req.schoolId = course.school
+            } else {
+                req.ids = [course.stuList]
+            }
+            this.$api.common.getGroupListByIds(req).then(res => {
+                if(res.members.length) {
+                    let arr = this._.cloneDeep(res.members)
+                    // type表示角色类型,1:醍摩豆登陆,2:学生登陆
+                    this.stuList = arr.filter((item) => {
+                        return item.type === 2
+                    })
+                    this.tmdList = arr.filter((item) => {
+                        return item.type === 1
+                    })
+                    this.getGroup(res.members)
                 }
             }).finally(() => {
                 this.isLoad = false
             })
         },
-        // 查找学生(个人)
-        findPersonInfo(course) {
-            this.stuGroup = []
-            this.stuList = []
-            // this.tmdList = []
-            let reqList = {
-                code: course.scope == 'school' ? course.school : course.creatorId,
-                // code: course.teacherId,
-                ids: [course.stuList],
-                scope: course.scope
-            }
-            this.$api.studentWeb.findListSummary(reqList).then(res => {
-                if(res.stuList.length) {
-                    if(res.stuList[0].students.length) {
-                        this.$api.studentWeb.findStuSummary({
-                            students: res.stuList[0].students,
-                            tmdIds: res.stuList[0].tmids
-                        }).then(res => {
-                            if(res.stus.length) {
-                                this.stuList = this._.cloneDeep(res.stus)
-                                this.tmdList = this._.cloneDeep(res.tmdinfos)
-                                this.getGroup(res.stus)
-                            }
-                        }).finally(() => {
-                            this.isLoad = false
-                        })
-                    } else {
-                        this.isLoad = false
-                    }
-                } else {
-                    this.isLoad = false
-                }
-            })
-        },
         // 学生分组
         getGroup(data) {
             for (let i = 0; i < data.length; i++) {
@@ -695,8 +673,9 @@ export default {
         getClassTime() {
             // 学生登陆
             if(this.onlyStu && this.period.length) {
+                let perId = JSON.parse(decodeURIComponent(localStorage.student_profile, "utf-8")).classinfo.periodId
                 this.timeTable = this.period.find(item => {
-                    return item.id == this.studentProfile.classinfo.periodId
+                    return item.id == perId
                 }).timetable
                 this.timeTable.forEach(item => {
                     let newfixlist = []
@@ -778,9 +757,10 @@ export default {
             this.courseNow = this._.cloneDeep(item)
             // 获取学生名单
             if(this.courseNow.classId != "" && this.courseNow.classId) {
-                this.findStuInfor(this.courseNow)
+                this.findStuInfor(this.courseNow, true)
             } else if(this.courseNow.stuList != "") {
-                this.findPersonInfo(this.courseNow)
+                // this.findPersonInfo(this.courseNow)
+                this.findStuInfor(this.courseNow)
             }
             // 螢幕寬度<767px時,直接關掉sidebar
             if (window.innerWidth <= 991) {
@@ -810,7 +790,6 @@ export default {
     computed: {
         ...mapState({
             userInfo: state => state.userInfo,
-            studentProfile: state => state.user.studentProfile
         }),
         ...mapGetters([
             "getCurrentLaguage",

+ 1 - 1
TEAMModelOS/ClientApp/src/components/syllabus/DragTree.vue

@@ -23,7 +23,7 @@
 						<Icon type="ios-remove-circle-outline" style="margin-right: 5px;" size="16" />
 						<span style="color: #9f9f9f;font-size: 12px;margin-right: 20px;"  @click="onIgnoreShare(data)">{{ $t('syllabus.ignoreChapter') }}</span>
 					</span>
-					<span class="custom-tree-tools" v-if="((hasEditAuth(data) || $access.can('admin.*|Syllabus_Edit')) && !inShareView) && !inSchoolAbility">
+					<span class="custom-tree-tools" v-if="((hasEditAuth(data) || $access.can('admin.*|Syllabus_Edit')) && !inShareView && Boolean(editable)) && !inSchoolAbility">
 						<Icon type="md-create" size="16" :title="$t('syllabus.tree.edit')" @click="onEditItem(node,data,$event)" />
 						<Icon type="md-trash" size="16" :title="$t('syllabus.tree.remove')" @click="remove(node,data)" v-if="!isFirstLevel(data) ||  (canDeleteChapter && isFirstLevel(data))"/>
 						<Icon type="md-add" size="16" :title="$t('syllabus.tree.add')" @click="onAddNode(node,data,$event)" />

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

@@ -284,7 +284,7 @@
 			},
 
 			onTargetChange(data) {
-				this.voteForm.classes = this.getCurScope === 'school' ? data : data.map(i => i.split('/')[1])
+				this.voteForm.classes = data
 				this.voteForm.targets = this.getCurScope === 'school' ? [] : data
 			},
 
@@ -697,11 +697,11 @@
 			getClassNameByIds(ids) {
 				return new Promise((r, j) => {
 					this.$api.learnActivity.getClassNameByIds({
-						classes: ids,
+						ids: ids,
 						school: this.$store.state.userInfo.schoolCode
 					}).then(res => {
 						if (!res.error) {
-							r(res.classInfos)
+							r(res.groups)
 						}
 					}).catch(e => {
 						j(e)
@@ -711,11 +711,12 @@
 
 			/* 查找学校检验组信息 */
 			findResearchList() {
-				this.$api.schoolUser.getResearchGroup({
-					code: this.$store.state.userInfo.schoolCode,
-					scope: 'school'
+				this.$api.common.getActivityTarget({
+					tmdid: this.$store.state.userInfo.TEAMModelId,
+					schoolId: this.$store.state.userInfo.schoolCode,
+					opt: 'manage'
 				}).then(res => {
-					this.groupList = res.tchLists
+					this.groupList = res.groupLists.filter(i => i.type === 'research')
 				})
 			},
 		},

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/courseManage.js

@@ -75,6 +75,8 @@ export default {
         studentTableC6: 'Group Name',
         studentTableC7: 'Account/Student ID',
         studentTableC8: 'Type',
+        studentTableC9: 'IRS號碼',
+        studentTableC10: '行政班',
         addClassroomProp1: 'Select Default classroom',
         addClassroomProp2: 'New personal classroom',
         chooseClassroom: 'Please select system classroom',

+ 14 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/cusMgt.js

@@ -147,6 +147,7 @@ export default {
     action:'Operate',
     atLeast:'Keep at least one group',
     checkName:'Please enter the group name and then create the group',
+    groupNameRepeat:'組名重複',
     noStuTips:'No students are available for grouping',
     groupCount:'Minimum number of groups is 1',
     groupTypeTips:'Please set the grouping method',
@@ -196,6 +197,7 @@ export default {
     createList:'Create Self-customized List',
     name:'Name: ',
     nameHolder:'Please enter list name...',
+    nameRepeat:'教學班名稱重複',
     pdHolder:'Please set the school system',
     timeSetTitle:'Schedule Settings',
     job:'Title',
@@ -225,8 +227,20 @@ export default {
     //MgtStuList.vue
     nameList:'Name list',
     remvStu:'Remove Student',
+    editStu:'設置IRS號碼',
     goBack:'Click to go back',
     delListTitle:'Delete Self-customized List',
+    notSet:'未設置',
+    irsTips1:'1、按照名單順序快速設置IRS號碼;',
+    irsTips2:'2、如果學生已經設置IRS號碼將被重置。 ',
+    irsRepeat:'IRS號碼重複',
+    remvContent1:'是否確認從名單移除',
+    remvContent2:'位學生',
+    okText:'是',
+    cancelText:'否',
+    remvTips:'請選擇需要移除的學生',
+    findListInfoErr:'查詢教學班信息失敗',
+    findListErr:'查詢教學班列表失敗',
 
     //TeaTable.vue
     am:'Morning',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/jyzx.js

@@ -112,6 +112,7 @@ export default{
         message4: "请先选择文件!",
         uploadSuccess: '上传成功',
         uploadError: '上传失败',
+        message5: "您无需提交该作业,将由组长一同提交",
     },
     // 应用考核
     application: {

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/en-US/teachermgmt.js

@@ -182,4 +182,9 @@ export default {
     rmvErr:'Failed to remove',
     groupInfoErr:'Failed to search for the group',
     delGroup:'Delete Pedagogical Research Team',
+    leader:'組長:',
+    notSet:'未設置',
+    setLeader:'設置為組長',
+    setOk:'設置成功',
+    setErr:'設置失敗'
 }

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/courseManage.js

@@ -75,6 +75,8 @@ export default {
         studentTableC6: '组名',
         studentTableC7: '账号/学号',
         studentTableC8: '类型',
+        studentTableC9: 'IRS号码',
+        studentTableC10: '行政班',
         addClassroomProp1: '选择预设教室',
         addClassroomProp2: '新建个人教室',
         chooseClassroom: '请选择系统的教室',

+ 14 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/cusMgt.js

@@ -147,6 +147,7 @@ export default {
     action:'操作',
     atLeast:'至少保留一组',
     checkName:'请先输入组名再创建组别',
+    groupNameRepeat:'组名重复',
     noStuTips:'暂无学生可以进行分组',
     groupCount:'分组数量最少为1',
     groupTypeTips:'请设置分组方式',
@@ -196,6 +197,7 @@ export default {
     createList:'创建教学班',
     name:'名称',
     nameHolder:'请输入教学班名称',
+    nameRepeat:'教学班名称重复',
     pdHolder:'请设置学段',
     timeSetTitle:'时段设置',
     job:'职位',
@@ -225,8 +227,20 @@ export default {
     //MgtStuList.vue
     nameList:'名单',
     remvStu:'移除学生',
+    editStu:'设置IRS号码',
     goBack:'返回上级',
     delListTitle:'删除自定义名单',
+    notSet:'未设置',
+    irsTips1:'1、按照名单顺序快速设置IRS号码;',
+    irsTips2:'2、如果学生已经设置IRS号码将被重置。',
+    irsRepeat:'IRS号码重复',
+    remvContent1:'是否确认从名单移除',
+    remvContent2:'位学生',
+    okText:'是',
+    cancelText:'否',
+    remvTips:'请选择需要移除的学生',
+    findListInfoErr:'查询教学班信息失败',
+    findListErr:'查询教学班列表失败',
 
     //TeaTable.vue
     am:'上午',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/jyzx.js

@@ -112,6 +112,7 @@ export default{
         message4: "请先选择文件!",
         uploadSuccess: '上传成功',
         uploadError: '上传失败',
+        message5: "您无需提交该作业,将由组长一同提交",
     },
     // 应用考核
     application: {

+ 2 - 2
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/survey.js

@@ -31,8 +31,8 @@ export default {
 		name:'问卷名称',
 		namePlace:'请输入问卷名称',
 		target:'问卷对象',
-		privateClass:'个人课程',
-		schoolClass:'学校课程',
+		privateClass:'个人班级',
+		schoolClass:'学校班级',
 		targetPlace:'请选择问卷发布对象',
 		noFoundText:'暂未创建班级',
 		time:'起止时间',

+ 5 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/teachermgmt.js

@@ -182,5 +182,9 @@ export default {
     rmvErr:'移除失败',
     groupInfoErr:'教研组查询失败',
     delGroup:'删除教研组',
-
+    leader:'组长:',
+    notSet:'未设置',
+    setLeader:'设置为组长',
+    setOk:'设置成功',
+    setErr:'设置失败'
 }

+ 2 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/courseManage.js

@@ -75,6 +75,8 @@ export default {
         studentTableC6: '組名',
         studentTableC7: '帳號/學號',
         studentTableC8: '類型',
+        studentTableC9: 'IRS號碼',
+        studentTableC10: '行政班',
         addClassroomProp1: '選擇預設教室',
         addClassroomProp2: '新建個人教室',
         chooseClassroom: '請選擇系統的教室',

+ 15 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/cusMgt.js

@@ -147,6 +147,7 @@ export default {
     action: '操作',
     atLeast: '至少保留一組',
     checkName: '請先輸入組名再建立組別',
+    groupNameRepeat:'組名重複',
     noStuTips: '暫無學生可以進行分組',
     groupCount: '分組數量最少為1',
     groupTypeTips: '請設定分組管道',
@@ -196,6 +197,7 @@ export default {
     createList: '新建選課班',
     name: '名稱:',
     nameHolder: '請輸入名單名稱…',
+    nameRepeat:'教學班名稱重複',
     pdHolder:'請設置學段',
     timeSetTitle: '時段設定',
     job: '職位',
@@ -225,8 +227,20 @@ export default {
     //MgtStuList.vue
     nameList: '名單',
     remvStu: '移除學生',
-    goBack: '回上一頁',
+    editStu:'設置IRS號碼',
+    goBack:'返回上級',
     delListTitle:'刪除自定義名單',
+    notSet:'未設置',
+    irsTips1:'1、按照名單順序快速設置IRS號碼;',
+    irsTips2:'2、如果學生已經設置IRS號碼將被重置。 ',
+    irsRepeat:'IRS號碼重複',
+    remvContent1:'是否確認從名單移除',
+    remvContent2:'位學生',
+    okText:'是',
+    cancelText:'否',
+    remvTips:'請選擇需要移除的學生',
+    findListInfoErr:'查詢教學班信息失敗',
+    findListErr:'查詢教學班列表失敗',
 
     //TeaTable.vue
     am: '上午',

+ 1 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/jyzx.js

@@ -112,6 +112,7 @@ export default{
         message4: "請先選擇檔案!",
         uploadSuccess: '上傳成功',
         uploadError: '上傳失敗',
+        message5: "您無需提交該工作,將由組長一同提交",
     },
     // 应用考核
     application: {

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/teachermgmt.js

@@ -182,4 +182,9 @@ export default {
     rmvErr:'移除失敗',
     groupInfoErr:'教研組查詢失敗',
     delGroup:'刪除教研組',
+    leader:'組長:',
+    notSet:'未設置',
+    setLeader:'設置為組長',
+    setOk:'設置成功',
+    setErr:'設置失敗'
 }

+ 4 - 10
TEAMModelOS/ClientApp/src/router/routes.js

@@ -450,7 +450,7 @@ export const routes = [{
 						name: 'schoolBank',
 						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve),
 						meta: {
-							isKeep: true,
+							isKeep: false,
 							activeName: 'schoolBank'
 						},
 					},
@@ -459,7 +459,7 @@ export const routes = [{
 						name: 'personalBank',
 						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve),
 						meta: {
-							isKeep: true,
+							isKeep: false,
 							activeName: 'personalBank'
 						}
 					}
@@ -470,7 +470,7 @@ export const routes = [{
 				name: 'newSchoolPaper',
 				component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve),
 				meta: {
-					isKeep: true,
+					isKeep: false,
 					activeName: 'schoolBank'
 				}
 			},
@@ -479,7 +479,7 @@ export const routes = [{
 				name: 'newPrivatePaper',
 				component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve),
 				meta: {
-					isKeep: true,
+					isKeep: false,
 					activeName: 'personalBank'
 				}
 			},
@@ -647,12 +647,6 @@ export const routes = [{
 					activeName: 'privateEvaluation'
 				}
 			},
-			//管理活动记录页面(暂未使用)
-			{
-				path: 'manageRecord',
-				name: 'manageRecord',
-				component: resolve => require(['@/view/learnactivity/ManageRecord.vue'], resolve)
-			},
 			//管理问卷调查
 			{
 				path: 'manageQuestionnaire',

+ 2 - 1
TEAMModelOS/ClientApp/src/store/module/answerSheet.js

@@ -206,8 +206,9 @@ export default {
 			let curTypeContentArr = state.config.newContents.filter(i => i.type ===  val.type)
 			let newContent = curTypeContentArr[curTypeContentArr.length - 1]
 			newContent.points.push({
-				ans:val.id,
+				ans:val.id + '',
 				row:val.startOrder,
+				name:val.displayName,
 				pos:$tools.getBoxPos(val.x,val.y,val.width,val.height)
 			})
 		},

+ 44 - 1
TEAMModelOS/ClientApp/src/utils/editorTools.js

@@ -44,6 +44,7 @@ export default {
 		this.addVideoUpload(vm,editor)
 		this.addAudio(vm,editor)
 		this.addCanvas(vm,editor)
+		// this.addTextDot(vm,editor)
 		editor.config.pasteFilterStyle = false
 		editor.config.pasteTextHandle = function (pasteStr) {
 			// 对粘贴的文本进行处理,然后返回处理后的结果
@@ -74,7 +75,8 @@ export default {
 			'splitLine',
 			'canvas',
 			'formula',
-			'undo'
+			'undo',
+			'textDot'
 		]
 		isOption && editor.config.menus.splice(editor.config.menus.indexOf('video'),1)
 	},
@@ -439,6 +441,47 @@ export default {
 		editor.config.menus = editor.config.menus.concat(canvasDraw);
 	},
 
+	/* 添加文字下加重点功能 */
+	addTextDot(vm,editor){
+// 获取必要的变量,这些在下文中都会用到
+		const {
+			$,
+			BtnMenu,
+			Panel
+		} = E;
+
+		// 标题菜单的 class ,可作为 DropList 菜单的参考代码
+		class myTextDot extends BtnMenu {
+			constructor(editor) {
+				// 菜单栏中,标题菜单的 DOM 元素
+				// 注意,这里的 $ 不是 jQuery ,是 E.$ (wangEditor 自带的 DOM 操作工具,类似于 jQuery)
+				const $elem = $(
+					'<div class="w-e-menu" style="color:red"><i class="ivu-icon ivu-icon-md-color-palette" style="font-size: 20px;"></i></div>'
+				);
+				super($elem, editor);
+			}
+
+			clickHandler() {
+				console.error(editor.selection.getSelectionText())
+				console.error(editor.selection.isSelectionEmpty())
+				console.error(editor.selection.getSelectionContainerElem().elems[0]);
+			}
+
+			command(value) {}
+
+			// 菜单是否需要激活
+			tryChangeActive() {}
+		}
+
+		// 注册菜单
+		const textDot = "textDot"; // 菜单 key ,各个菜单不能重复
+		editor.menus.extend("textDot", myTextDot);
+
+		// 将菜单加入到 editor.config.menus 中
+		// 也可以通过配置 menus 调整菜单的顺序,参考【配置菜单】部分的文档
+		editor.config.menus = editor.config.menus.concat(textDot);
+	},
+	
 	/* 添加公式编辑器功能 */
 	addFormula(vm,editor){
 		// 获取必要的变量,这些在下文中都会用到

+ 2 - 0
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -117,6 +117,8 @@ export default {
 				subjectName:paper.subjectName,
 				score:paper.score,
 				sheet:paper.sheet || null,
+				typeSummaryInfo:paper.typeSummaryInfo || null,
+				orderTemp:paper.orderTemp || 0
 			}
 			r(paperItem)
 		})

+ 15 - 15
TEAMModelOS/ClientApp/src/utils/html2pdf.js

@@ -3,6 +3,7 @@ import JsPDF from 'jspdf'
 import store from '@/store'
 import domtoimage from './dom_to_image';
 import $tools from './public.js'
+import { PAPER_W, PAPER_H,SVG_BORDER_PROP,STANDARD_PAPER } from './sheetConfig.js'
 export default {
 	install(Vue, options) {
 		Vue.prototype.getPdf = (mode,sheetNo) => {
@@ -18,10 +19,8 @@ export default {
 							img.onload = function() {
 								console.log('height', img.height);
 								console.log('width', img.width);
-								// const a4Height = 841.89
-								// const a4Width = 595.28
-								const a4HeightPx = 1165
-								const a4WidthPx = 826
+								const a4HeightPx = PAPER_H
+								const a4WidthPx = PAPER_W
 								const a4Height = 297
 								const a4Width = 210
 								let contentWidth = img.width
@@ -29,15 +28,14 @@ export default {
 								let pageHeight = contentWidth / a4Width * a4Height
 								let leftHeight = contentHeight
 								let position = 0
-								//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
 								let imgWidth = a4Width
 								let imgHeight = a4Width / contentWidth * contentHeight
-								
 								let mm2px = $tools.getOneMmsPx()
 								let xMarginMM = 15 / mm2px - 0.2
-								let yMarginMM = 40 / mm2px - 0.2
-								let pdfBorderHeight = a4Height - 22.7
-								// console.log(pageData)
+								let yMarginMM = 40 / mm2px
+								// PDF外框绘制时的宽高(以mm单位)
+								let pdfBorderWmm = (SVG_BORDER_PROP.width / (PAPER_W / STANDARD_PAPER.w))  * STANDARD_PAPER.px2mm
+								let pdfBorderHmm = (SVG_BORDER_PROP.height / (PAPER_H / STANDARD_PAPER.h))  * STANDARD_PAPER.px2mm
 								let PDF = null 
 								/* 分割长图 */
 								function segmentationImage(img, width, height) {
@@ -67,22 +65,24 @@ export default {
 										}else{
 											PDF.rect(xMarginMM + index * 10, a4Height - 7, 7, 3);
 										}
-										
 									}
+									PDF.setFont('Times New Roman')
 									if(mode === 'A4'){
 										// 页面外框
-										PDF.rect(xMarginMM, yMarginMM ,a4Width - xMarginMM * 2,pdfBorderHeight)
+										PDF.rect(xMarginMM, yMarginMM,pdfBorderWmm,pdfBorderHmm)
 										// 页码
 										PDF.text(`${curPage} / ${totalPage}`, a4Width / 2 - 5, a4Height - 4,'center')
 										// 答题卡编号
-										PDF.text(`${sheetNo}`, a4Width - 20, a4Height - 4)
+										PDF.setFont("Courier")
+										PDF.text(`${sheetNo}-${curPage}`, a4Width - 24, a4Height - 4)
 									}else{
 										// 页面外框
-										PDF.rect(xMarginMM, yMarginMM ,a4Width * 2 - xMarginMM * 2,pdfBorderHeight);
+										PDF.rect(xMarginMM, yMarginMM , (a4Width - xMarginMM) * 2,pdfBorderHmm);
 										// 页码
 										PDF.text(`${curPage} / ${ totalPage }`, a4Width, a4Height - 4,'center')
 										// 答题卡编号
-										PDF.text(`${sheetNo}`, a4Width * 2 - 20, a4Height - 4)
+										PDF.setFont("Courier")
+										PDF.text(`${sheetNo}-${curPage}`, a4Width * 2 - 24, a4Height - 4)
 									}
 									
 								}
@@ -98,7 +98,7 @@ export default {
 										putOnlyUsedFonts: true
 									})
 									PDF.setFont('Times New Roman')
-									PDF.setFontSize(12);
+									PDF.setFontSize(10);
 									let curPage = 1
 									// 如果是一页的情况
 									if (leftHeight <= pageHeight) {

+ 0 - 76
TEAMModelOS/ClientApp/src/utils/mockAnswer.js

@@ -1,76 +0,0 @@
-/* 
- * 模拟部分活动模块的学生作答数据(作业活动/投票活动/问卷活动等)
- * 获取学生名单 - 自定义作答数据结构 - 保存活动数据
- * 2020-07-20 OnePsycho
- * */
-import apiTools from '@/api'
-var Mock = require('mockjs')
-
-const CLASS_CODE = ["HBCN0101", "HBCN0102"]
-const SCHOOL_CODE = 'HBCN'
-const activityId = '40e3da01-b9c8-4524-a588-fec246eaeb5f'
-const activityType = 'homework'
-let studentList = []
-let resultList = []
-
-async function initMockAnswers(){
-	studentList = await getStudentList()
-	let mockData = doMock(studentList)
-	let resultData = await saveMockData(mockData)
-	console.log(resultData)
-}
-
-
-/* 获取学生清单 */
-function getStudentList(){
-	return new Promise((r,j) => {
-		apiTools.courseMgmt.getClassroomStudent({
-			classroomCode: CLASS_CODE,
-			schoolCode: SCHOOL_CODE
-		}).then(res => {
-			if (!res.error && res.result.data) {
-				r(res.result.data)
-			} else {
-				j(500)
-			}
-		})
-	})
-}
-
-/* 根据活动类型模拟作答数据 */
-function doMock(arr){
-	let result = []
-	arr.forEach(i => {
-		result.push({
-			id:activityId,
-			code:i.code,
-			content:[{
-				answers:Mock.mock('@cparagraph(2)'),
-				resource:[]
-			}],
-			submit:true,
-			submitTime: new Date(Mock.mock('@datetime')).getTime()
-		})
-	})
-	return result
-}
-
-/* 获取学生清单 */
-function saveMockData(list){
-	return new Promise((r,j) => {
-		apiTools.learnActivity.SaveRecords(list).then(res => {
-			if (!res.error && res.result.data) {
-				r(res.result.data)
-			} else {
-				j(500)
-			}
-		})
-	})
-}
-
-
-export default {
-	initMockAnswers
-}
-
-

+ 115 - 79
TEAMModelOS/ClientApp/src/utils/public.js

@@ -1,6 +1,8 @@
 import $api from '@/api'
 import store from '@/store'
-import { app } from '@/boot-app.js'
+import {
+	app
+} from '@/boot-app.js'
 import {
 	Message
 } from 'view-design'
@@ -138,42 +140,43 @@ export default {
 			mousedownStep: 30
 		}
 	},
-	
+
 	/**
 	 * 数字与中文转换
 	 * @param num
 	 */
-	numberConvertToUppercase(num) {
-	    num = Number(num)
-	    var upperCaseNumber = [
-	        app.$t('learnActivity.score.zero'),
-	        app.$t('learnActivity.score.one'),
-	        app.$t('learnActivity.score.two'),
-	        app.$t('learnActivity.score.three'),
-	        app.$t('learnActivity.score.four'),
-	        app.$t('learnActivity.score.five'),
-	        app.$t('learnActivity.score.six'),
-	        app.$t('learnActivity.score.seven'),
-	        app.$t('learnActivity.score.eight'),
-	        app.$t('learnActivity.score.nine'),
-	        app.$t('learnActivity.score.ten'),
-	        app.$t('learnActivity.score.hundred'),
-	        app.$t('learnActivity.score.thousand'),
-	        app.$t('learnActivity.score.tenThd'),
-	        app.$t('learnActivity.score.hMillion')
-	    ]
-	    var length = String(num).length
-	    if (length === 1) {
-	        return upperCaseNumber[num]
-	    } else if (length === 2) {
-	        if (num === 10) {
-	            return upperCaseNumber[num]
-	        } else if (num > 10 && num < 20) {
-	            return app.$t('learnActivity.score.ten') + upperCaseNumber[String(num).charAt(1)]
-	        } else {
-	            return upperCaseNumber[String(num).charAt(0)] + app.$t('learnActivity.score.ten') + upperCaseNumber[String(num).charAt(1)].replace(app.$t('learnActivity.score.zero'), '')
-	        }
-	    }
+	getChineseByNum(num) {
+		num = Number(num)
+		var upperCaseNumber = [
+			app.$t('learnActivity.score.zero'),
+			app.$t('learnActivity.score.one'),
+			app.$t('learnActivity.score.two'),
+			app.$t('learnActivity.score.three'),
+			app.$t('learnActivity.score.four'),
+			app.$t('learnActivity.score.five'),
+			app.$t('learnActivity.score.six'),
+			app.$t('learnActivity.score.seven'),
+			app.$t('learnActivity.score.eight'),
+			app.$t('learnActivity.score.nine'),
+			app.$t('learnActivity.score.ten'),
+			app.$t('learnActivity.score.hundred'),
+			app.$t('learnActivity.score.thousand'),
+			app.$t('learnActivity.score.tenThd'),
+			app.$t('learnActivity.score.hMillion')
+		]
+		var length = String(num).length
+		if (length === 1) {
+			return upperCaseNumber[num]
+		} else if (length === 2) {
+			if (num === 10) {
+				return upperCaseNumber[num]
+			} else if (num > 10 && num < 20) {
+				return app.$t('learnActivity.score.ten') + upperCaseNumber[String(num).charAt(1)]
+			} else {
+				return upperCaseNumber[String(num).charAt(0)] + app.$t('learnActivity.score.ten') + upperCaseNumber[
+					String(num).charAt(1)].replace(app.$t('learnActivity.score.zero'), '')
+			}
+		}
 	},
 
 	// wangEditor菜单配置
@@ -206,17 +209,17 @@ export default {
 		'table', // 表格
 	],
 	// 生成随机UUID工具
-	randomId: function () {
+	randomId: function() {
 		return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
 	},
 	// 生成随机UUID工具
-	guid: function () {
+	guid: function() {
 		return (this.randomId() + this.randomId() + '-' + this.randomId() + '-' + this.randomId() + '-' + this
 			.randomId() +
 			'-' + this.randomId() + this.randomId() + this.randomId())
 	},
 	/* 获取mm与px的转换 */
-	getOneMmsPx (){
+	getOneMmsPx() {
 		// 创建一个1mm宽的元素插入到页面,然后坐等出结果
 		let div = document.createElement("div");
 		div.id = "mm";
@@ -227,41 +230,40 @@ export default {
 		console.log(mm1);
 		return mm1.width;
 	},
-	
+
 	// 根据总分和数量求平均结果
-	doAverage(total,count,step){
+	doAverage(total, count, step) {
 		let oneMaxScore = (Math.floor((total / (count * step))) * step);
 		let maxIndex = Math.floor((total - oneMaxScore * count) / step);
-		let tempArr = new Array(count).fill(oneMaxScore).map((item,index)=>index < maxIndex ? (item + step) : item);
+		let tempArr = new Array(count).fill(oneMaxScore).map((item, index) => index < maxIndex ? (item + step) : item);
 		return tempArr
 	},
-	
-	getBoxPos(x,y,w,h){
-		return [
-			{
-				x:x,
-				y:y
+
+	/* 根据x,y,w,h获取四点坐标 */
+	getBoxPos(x, y, w, h) {
+		return [{
+				x: x,
+				y: y
 			},
 			{
-				x:x+w,
-				y:y
+				x: x + w,
+				y: y
 			},
 			{
-				x:x+w,
-				y:y+h
+				x: x + w,
+				y: y + h
 			},
 			{
-				x:x,
-				y:y+h
+				x: x,
+				y: y + h
 			}
 		]
 	},
-	
-	matchHost(url){
+	/* 匹配URL里面的HOST */
+	matchHost(url) {
 		var pattern = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/
 		return 'https://' + url.match(pattern)[0]
 	},
-
 	// 正则判断是否为标准的URL格式
 	isURL(url) {
 		const strRegex = '^((https|http|ftp)://)?' //(https或http或ftp):// 可有可无
@@ -291,7 +293,6 @@ export default {
 		}
 		return false;
 	},
-
 	// 数据结构转换工具
 	jsonTransform(obj) {
 		let arr = []
@@ -309,7 +310,6 @@ export default {
 		}
 		return arr || null
 	},
-
 	/**
 	 *对Date的扩展,将 Date 转化为指定格式的String
 	 *月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
@@ -334,10 +334,9 @@ export default {
 		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)))
+					k]).substr(('' + o[k]).length)))
 		return fmt
 	},
-
 	/**
 	 * 字节格式转换
 	 * @param {any} bytes
@@ -349,7 +348,6 @@ export default {
 			i = Math.floor(Math.log(bytes) / Math.log(k));
 		return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
 	},
-
 	/* 采用原生Xhr来发送HTTP请求 避免携带token访问blob报错 */
 	getFile(url) {
 		return new Promise((resolve, reject) => {
@@ -357,7 +355,7 @@ export default {
 			var formData = new FormData();
 			xhr.open('get', url); //url填写后台的接口地址,如果是post,在formData append参数(参考原文地址)
 			// xhr.responseType = 'arraybuffer';
-			xhr.onload = function (e) {
+			xhr.onload = function(e) {
 				switch (e.currentTarget.status) {
 					case 200:
 						resolve(e.currentTarget.response)
@@ -377,8 +375,6 @@ export default {
 			xhr.send(formData);
 		})
 	},
-
-
 	/**
 	 * 获取blob授权
 	 * @param {type,data} param
@@ -451,15 +447,13 @@ export default {
 			}
 		})
 	},
-
 	/* 根据登录后的用户信息获取blobHOST域名 */
 	// 现在废弃,改用 getBlobSas() 返回的url
-	getBlobHost(){
+	getBlobHost() {
 		let s = store.state.user.userProfile.blob_uri || store.state.user.studentProfile.blob_uri
 		let pattern = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/
 		return s.split('//')[0] + '//' + s.match(pattern)[0]
 	},
-
 	/**
 	 * 获取个人容器授权
 	 */
@@ -564,7 +558,7 @@ export default {
 
 	/* 获取视频第一帧 */
 	getVideoBase64(url) {
-		return new Promise(function (resolve, reject) {
+		return new Promise(function(resolve, reject) {
 			let dataURL = '';
 			let video = document.createElement("video");
 			video.setAttribute('crossOrigin', 'anonymous'); //处理跨域
@@ -572,7 +566,7 @@ export default {
 			video.setAttribute('preload', 'auto');
 			video.setAttribute('width', 150);
 			video.setAttribute('height', 90);
-			video.addEventListener('loadeddata', function () {
+			video.addEventListener('loadeddata', function() {
 				let canvas = document.createElement("canvas"),
 					width = video.width, //canvas的尺寸和图片一样
 					height = video.height;
@@ -584,7 +578,7 @@ export default {
 				var img = new Image()
 				img.src = require('@/assets/icon/icon_play.png')
 				img.setAttribute('crossOrigin', 'anonymous');
-				img.onload = function () {
+				img.onload = function() {
 					//画图
 					canvas.getContext("2d").drawImage(img, 55, 25, 40, 40);
 					var data = canvas.toDataURL('image/jpeg');
@@ -594,6 +588,18 @@ export default {
 			});
 		})
 	},
+	
+	/* 获取视频文件的持续时长 */
+	getVideoDuration(file) {
+		return new Promise((resolve,reject) => {
+			var vid = document.createElement('video');
+			var fileURL = URL.createObjectURL(file);
+			vid.src = fileURL;
+			vid.addEventListener('loadedmetadata', function() {
+			    resolve(vid.duration);
+			});
+		})
+	},
 
 	/* 上传视频到BLob */
 	async doUploadVideo(vm, file, editor) {
@@ -636,7 +642,8 @@ export default {
 			const fileBlobUrl = fileSas.url
 			// const posterBase64 = await this.getVideoBase64(fileBlobUrl)
 			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>'
+				fileBlobUrl +
+				' class="richText-video" width="300" preload controls="controls"></video><span>&nbsp;</span></span>'
 			editor.change.emit()
 			vm.$EventBus.$emit('noSave', {
 				path: blobFile.blob,
@@ -736,7 +743,7 @@ export default {
 		})
 
 	},
-	isEqual: function (x, y) {
+	isEqual: function(x, y) {
 		// If both x and y are null or undefined and exactly the same 
 		if (x === y) {
 			return true;
@@ -762,7 +769,7 @@ export default {
 					continue;
 				}
 				// Numbers, Strings, Functions, Booleans must be strictly equal 
-				if (typeof (x[p]) !== "object") {
+				if (typeof(x[p]) !== "object") {
 					return false;
 				}
 				// Objects and Arrays must be tested recursively 
@@ -789,8 +796,9 @@ export default {
 				stu.no || '-',
 				val.fScores[subjectIndex].value[index],
 				stu.subjects[subjectIndex].fieldPoint[index],
-				val.fScores[subjectIndex].value[index] == 0 ? 0 : (stu.subjects[subjectIndex].fieldPoint[index] / val.fScores[subjectIndex].value[index])
-					.toFixed(2)
+				val.fScores[subjectIndex].value[index] == 0 ? 0 : (stu.subjects[subjectIndex]
+					.fieldPoint[index] / val.fScores[subjectIndex].value[index])
+				.toFixed(2)
 			])
 		})
 		return result
@@ -799,7 +807,9 @@ export default {
 	getLevelClassPercent(val, subjectIndex, index) {
 		let result = []
 		val.classes.forEach(classItem => {
-			result.push(classItem.subjects[subjectIndex].field.map((score, index) => val.fieldwrong[subjectIndex].value[index][1] == 0 ? 0 : Number(score / val.fieldwrong[subjectIndex].value[index][1]) * 100)[index])
+			result.push(classItem.subjects[subjectIndex].field.map((score, index) => val.fieldwrong[
+				subjectIndex].value[index][1] == 0 ? 0 : Number(score / val.fieldwrong[subjectIndex]
+				.value[index][1]) * 100)[index])
 		})
 		return result
 	},
@@ -811,7 +821,8 @@ export default {
 			stuResult[item] = this.getLevelStuPercent(val, subjectIndex, index)
 			classResult[item] = this.getLevelClassPercent(val, subjectIndex, index)
 		})
-		stuResult.grade = val.fieldAllPer[subjectIndex].value.map((score, index) => (val.fieldwrong[subjectIndex].value[index][1] == 0 ? 0 : Number(score / val.fieldwrong[subjectIndex].value[index][1]).toFixed(2)) * 100)
+		stuResult.grade = val.fieldAllPer[subjectIndex].value.map((score, index) => (val.fieldwrong[subjectIndex].value[
+			index][1] == 0 ? 0 : Number(score / val.fieldwrong[subjectIndex].value[index][1]).toFixed(2)) * 100)
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
 		classResult.className = val.classes.map(i => i.className)
@@ -832,8 +843,9 @@ export default {
 				stu.no || '-',
 				val.kScores[subjectIndex].value[index],
 				stu.subjects[subjectIndex].point[index],
-				val.kScores[subjectIndex].value[index] == 0 ? 0 : (stu.subjects[subjectIndex].point[index] / val.kScores[subjectIndex].value[index])
-					.toFixed(2)
+				val.kScores[subjectIndex].value[index] == 0 ? 0 : (stu.subjects[subjectIndex].point[
+					index] / val.kScores[subjectIndex].value[index])
+				.toFixed(2)
 			])
 		})
 		return result
@@ -843,7 +855,9 @@ export default {
 		let result = []
 		val.classes.forEach(classItem => {
 			// 取当前班级在每个知识点的得分 除以知识点的总分 得到每个班在该知识点的得分率 index=>知识点下标
-			result.push(classItem.subjects[subjectIndex].point.map((score, pointIndex) => val.wrong[subjectIndex].value[pointIndex][1] == 0 ? 0 : Number(score / val.wrong[subjectIndex].value[pointIndex][1]) * 100)[index])
+			result.push(classItem.subjects[subjectIndex].point.map((score, pointIndex) => val.wrong[
+				subjectIndex].value[pointIndex][1] == 0 ? 0 : Number(score / val.wrong[subjectIndex]
+				.value[pointIndex][1]) * 100)[index])
 		})
 		return result
 	},
@@ -856,7 +870,9 @@ export default {
 			classResult[item] = this.getKnowClassPercent(val, subjectIndex, index)
 		})
 		// 取当前年级在每个知识点的得分 除以知识点的总分 得到年级在该知识点的得分率
-		stuResult.grade = val.knowAllper[subjectIndex].value.map((score, index) => val.wrong[subjectIndex].value[index][1] == 0 ? 0 : Number(score / val.wrong[subjectIndex].value[index][1]) * 100)
+		stuResult.grade = val.knowAllper[subjectIndex].value.map((score, index) => val.wrong[subjectIndex].value[index][
+			1
+		] == 0 ? 0 : Number(score / val.wrong[subjectIndex].value[index][1]) * 100)
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
 		classResult.className = val.classes.map(i => i.className)
@@ -867,4 +883,24 @@ export default {
 		return obj
 	},
 
+	getRomanByNum(number) {
+		var Roman = [
+			["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"],
+			["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
+			["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
+			["", "M", "MM", "MMM", "  ", " ", "  ", "   ", "    ", "  "]
+		];
+		// 只能转换 4000 以下的正整数阿拉伯数字
+		function convert(num) {
+			if (isNaN(num)) return num;
+			var ReverseArr = num.toString().split("").reverse();
+			var CorrectArr = [];
+			for (var i = 0; i < ReverseArr.length; i++) {
+				CorrectArr.unshift(Roman[i][ReverseArr[i]]);
+			}
+			return CorrectArr.join("");
+		}
+		return convert(number)
+	}
+
 }

+ 7 - 1
TEAMModelOS/ClientApp/src/utils/sheetConfig.js

@@ -1,7 +1,12 @@
 // const PAPER_W = 794; // 答题卡宽度
 // const PAPER_H = 1124; // 答题卡高度
 const PAPER_W = 826; // 答题卡宽度
-const PAPER_H = 1165; // 答题卡高度
+const PAPER_H = 1168; // 答题卡高度
+const STANDARD_PAPER = {
+	w:794,//标准A4宽度
+	h:1123,//标准A4高度
+	px2mm:0.264583 //1px转换的mm值
+}
 const ANCHORPROP = {
     width: 10, // 锚点宽度
     height: 10, // 锚点高度
@@ -45,6 +50,7 @@ const OBJ_ANCHOR_H_COUNT = 28 // 客观题横向锚点数量
 export {
     PAPER_W,
     PAPER_H,
+	STANDARD_PAPER,
     BLOCK_H,
     ANCHORPROP,
 	SVG_BORDER_MB,

+ 38 - 58
TEAMModelOS/ClientApp/src/view/ability/Ability.vue

@@ -15,9 +15,9 @@
             </div>
             <Table :columns="ablitiesColumn" :data="origin" border :span-method="handleSpan" :loading="tableLoading" ref="table">
                 <template slot-scope="{ row, index }" slot="schoolAppraise">
-                    <span v-show="row.schoolAppraise === 2" style="color: #007700;">{{ $t('ability.good') }}</span>
-                    <span v-show="row.schoolAppraise === 1" style="color: orangered;">{{ $t('ability.normal') }}</span>
-                    <span v-show="row.schoolAppraise === 0" style="color: red;">{{ $t('ability.bad') }}</span>
+                    <span v-show="row.schoolAppraise === 2" style="color: #007700;font-weight: bold;">{{ $t('ability.good') }}</span>
+                    <span v-show="row.schoolAppraise === 1" style="color: #f18d3a;font-weight: bold;">{{ $t('ability.normal') }}</span>
+                    <span v-show="row.schoolAppraise === 0" style="color: red;font-weight: bold;">{{ $t('ability.bad') }}</span>
                     <span v-show="row.schoolAppraise === '-'">-</span>
                 </template>
                 <template slot-scope="{ row, index }" slot="action">
@@ -33,9 +33,9 @@
             </div>
             <Table :columns="appraiseColumns" :data="appraiseArr" border>
                 <template slot-scope="{ row, index }" slot="result">
-                    <span v-show="row.result === $t('ability.good')" style="color: #007700;">{{ $t('ability.good') }}</span>
-                    <span v-show="row.result === $t('ability.normal')" style="color: orangered;">{{ $t('ability.normal') }}</span>
-                    <span v-show="row.result === $t('ability.bad')" style="color: red;">{{ $t('ability.bad') }}</span>
+                    <span v-show="row.result === $t('ability.good')" style="color: #007700;font-weight: bold;">{{ $t('ability.good') }}</span>
+                    <span v-show="row.result === $t('ability.normal')" style="color: #CC7832;font-weight: bold;">{{ $t('ability.normal') }}</span>
+                    <span v-show="row.result === $t('ability.bad')" style="color: red;font-weight: bold;">{{ $t('ability.bad') }}</span>
                 </template>
             </Table>
         </div>
@@ -83,16 +83,11 @@ export default {
                     width: 140
                 },
                 {
-                    title: vm.$t('ability.schoolAppraise'),
+                    title: '小组评结果',
                     slot: 'schoolAppraise',
                     key: 'schoolAppraise',
                     width: 140
                 },
-                {
-                    title: vm.$t('ability.teacherAppraise'),
-                    key: 'teacherAppraise',
-                    width: 140
-                },
                 {
                     title: vm.$t('ability.action'),
                     slot: 'action',
@@ -133,19 +128,6 @@ export default {
         }
     },
     created() {
-        //由DB取得該校所有使用者並放入state.schoolUserList
-        this.$store.dispatch('user/getSchoolTeacher').then(
-            res => {
-                this.handelGroup()
-                if (res.code == 0) {
-                    this.$Message.error('無法取得使用者資料')
-                }
-            },
-            err => {
-                this.$Message.error('user/setSchoolTeacher API error!')
-            }
-        )
-
         this.getAllSubs()
     },
     methods: {
@@ -199,43 +181,15 @@ export default {
                         i.name = i.tmdname
                         i.id = ability.id
                         i.teacherAppraise = this.$t('ability.noSpot')
-                        i.schoolAppraise = i.sub.otherScore.find(i => i.roleType === 'school') ? i.sub.otherScore.find(i => i.roleType === 'school').score : '-'
+                        i.schoolAppraise = i.sub.otherScore.find(i => i.roleType === 'leader') ? i.sub.otherScore.find(i => i.roleType === 'leader').score : '-'
                         this.origin.push(i)
                     }
                 })
                 this.tableLoading = false
                 this.originList = JSON.parse(JSON.stringify(this.origin))
-                console.log(res.groupMembers);
-                console.log(this.origin)
-                console.log(res.groupMembers.map(i => i.sub.uploads))
                 this.doGroup()
             })
         },
-        //转分组模式数据结构
-        handelGroup() {
-            this.teachers.forEach(item => {
-                item.groupName = item.groupName || this.$t('ability.defaultGroup')
-            })
-            let groupRes = this.$jsFn.groupBy(this.teachers, 'groupName')
-            this.groupData.length = 0
-            for (let index in groupRes) {
-                this.groupData.push({
-                    groupName: groupRes[index][0].groupName || this.$t('ability.defaultGroup'),
-                    groupId: groupRes[index][0].groupId,
-                    teachers: groupRes[index]
-                })
-            }
-            this.groupData.sort((a, b) => {
-                return parseInt(a.groupId) - parseInt(b.groupId)
-            })
-            this.groupData.unshift({
-                groupName: this.$t('ability.all'),
-                groupId: '-1',
-                teachers: []
-            })
-            this.groupList = this.groupData
-            console.log('处理分组数据', this.groupData)
-        },
         goAppraiseDetail(data) {
 			let promiseArr = []
 			data.sub.otherScore.forEach(async i => {
@@ -247,7 +201,7 @@ export default {
 				        name: i.tmdname,
 				        result: [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][i.score],
 				        content: result[index] || '-',
-				        type: this.$t('ability.appraiseOther'),
+				        type: '小组评',
 				        time: this.$tools.formatTime(i.time)
 				    }
 				})
@@ -297,7 +251,7 @@ export default {
             }
             this.curData = reviewData
             this.isShowReview = true
-            this.curReviewMode = 'school'
+            this.curReviewMode = 'leader'
         },
         getAllAbilities() {
             return new Promise((r, j) => {
@@ -418,10 +372,36 @@ export default {
         onSearch(val) {
             this.origin = this.originList.filter(i => i.name.indexOf(this.searchVal) > -1)
         },
+		
+		getTeacherGroups() {
+		    let params = {
+		        tmdid: this.$store.state.userInfo.TEAMModelId,
+		        schoolId: this.$store.state.userInfo.schoolCode,
+		        opt: 'manage'
+		    }
+		    this.$api.common.getActivityTarget(params).then(
+		        res => {
+					this.groupList = res.groupLists.filter(i => i.type === 'research').map(i => {
+						return {
+							groupName:i.name,
+							groupId:i.id,
+							teachers:[]
+						}
+					})
+					this.groupList.unshift({
+					    groupName: this.$t('ability.all'),
+					    groupId: '-1',
+					    teachers: []
+					})
+		        },
+		        err => {
+		            this.$Messag.error('查询发布对象失败')
+		        }
+		    )
+		},
     },
     mounted() {
-
-
+		this.getTeacherGroups()
         this.getAllAbilities()
     },
     computed: {

+ 36 - 0
TEAMModelOS/ClientApp/src/view/ability/GroupReview.less

@@ -0,0 +1,36 @@
+.group-review-container {
+		.table-filter {
+			margin: 10px 0;
+
+			.ivu-select {
+				margin-right: 10px;
+			}
+		}
+		
+		.btn-export{
+			float: right;
+			margin-right: 20px;
+			color: #40A8F0;
+			cursor: pointer;
+		}
+
+		.ivu-table {
+			font-size: 14px;
+		}
+		
+		.appraise-detail{
+			padding: 20px;
+			
+			.detail-title{
+				font-size: 20px;
+				font-weight: bold;
+				margin-bottom: 20px;
+				
+				.ivu-icon{
+					font-size: 24px;
+					margin-right: 10px;
+					cursor: pointer;
+				}
+			}
+		}
+	}

+ 416 - 0
TEAMModelOS/ClientApp/src/view/ability/GroupReview.vue

@@ -0,0 +1,416 @@
+<template>
+    <div class="group-review-container">
+        <div v-if="!isShowDetail && !isShowReview">
+            <div class="table-filter light-iview-select light-iview-input">
+                <Select v-model="curAbility" style="width:250px" @on-change="onAbilityFilter">
+                    <Option v-for="(item,index) in abilityList" :value="index" :key="index">{{ item.no }} {{ item.name }}</Option>
+                </Select>
+                <Select v-model="curGroup" style="width:200px" @on-change="onGroupFilter">
+                    <Option v-for="(item,index) in groupList" :value="item.groupName" :key="index">{{ item.groupName }}</Option>
+                </Select>
+                <Input v-special-char v-model="searchVal" suffix="ios-search" :placeholder="$t('ability.place1')" style="width: auto" @on-change="onSearch" />
+                <!-- <span class="btn-export" @click="exportData()">
+                    <Icon type="md-download" /> {{ $t('ability.resultDownload') }}
+                </span> -->
+            </div>
+            <Table :columns="ablitiesColumn" :data="origin" border :span-method="handleSpan" :loading="tableLoading" ref="table">
+                <template slot-scope="{ row, index }" slot="schoolAppraise">
+                    <span v-show="row.schoolAppraise === 2" style="color: #007700;">{{ $t('ability.good') }}</span>
+                    <span v-show="row.schoolAppraise === 1" style="color: orangered;">{{ $t('ability.normal') }}</span>
+                    <span v-show="row.schoolAppraise === 0" style="color: red;">{{ $t('ability.bad') }}</span>
+                    <span v-show="row.schoolAppraise === '-'">-</span>
+                </template>
+                <template slot-scope="{ row, index }" slot="action">
+                    <!-- <Button type="info" size="small" style="margin-right: 5px;font-size: 12px;" @click="goAppraiseDetail(row)">{{ $t('ability.appraiseDetail') }}</Button> -->
+                    <Button type="primary" size="small" style="margin-right: 5px;font-size: 12px;" @click="goReview(row)">{{ $t('ability.appraise') }}</Button>
+                </template>
+            </Table>
+        </div>
+        <div class="animated appraise-detail" v-if="isShowDetail">
+            <div class="detail-title">
+                <Icon type="md-arrow-back" @click="isShowDetail = false" />
+                <span>{{ curData.tmdname }} 【 {{ curData.ability }} 】</span>
+            </div>
+            <Table :columns="appraiseColumns" :data="appraiseArr" border>
+                <template slot-scope="{ row, index }" slot="result">
+                    <span v-show="row.result === $t('ability.good')" style="color: #007700;">{{ $t('ability.good') }}</span>
+                    <span v-show="row.result === $t('ability.normal')" style="color: orangered;">{{ $t('ability.normal') }}</span>
+                    <span v-show="row.result === $t('ability.bad')" style="color: red;">{{ $t('ability.bad') }}</span>
+                </template>
+            </Table>
+        </div>
+        <Review v-if="isShowReview" :mode="curReviewMode" :reviewData="curData" @goBack="goBack"></Review>
+
+    </div>
+</template>
+<script>
+import excel from '@/utils/excel.js'
+import Review from './Review.vue'
+import { mapGetters } from 'vuex'
+export default {
+    components: { Review },
+    data(vm) {
+        return {
+            tableLoading: false,
+            spanb: [],
+            searchVal: '',
+            abilityList: [],
+            groupList: [],
+            origin: [],
+            ablitiesColumn: [
+                {
+                    title: vm.$t('ability.teacherName'),
+                    key: 'tmdname',
+                    width: 140
+                },
+                {
+                    title: vm.$t('ability.abilityName'),
+                    key: 'ability'
+                },
+                {
+                    title: vm.$t('ability.dimension'),
+                    key: 'dimension',
+                    width: 140
+                },
+                {
+                    title: vm.$t('ability.env'),
+                    key: 'env',
+                    width: 180
+                },
+                {
+                    title: vm.$t('ability.groupName'),
+                    key: 'groupName',
+                    width: 140
+                },
+                {
+                    title: '小组评结果',
+                    slot: 'schoolAppraise',
+                    key: 'schoolAppraise',
+                    width: 140
+                },
+                {
+                    title: vm.$t('ability.action'),
+                    slot: 'action',
+                    key: 'action'
+                }
+            ],
+            appraiseColumns: [
+                {
+                    title: vm.$t('ability.name'),
+                    key: 'name'
+                },
+                {
+                    title: vm.$t('ability.type'),
+                    key: 'type'
+                },
+                {
+                    title: vm.$t('ability.result'),
+                    slot: 'result',
+                },
+                {
+                    title: vm.$t('ability.content'),
+                    key: 'content'
+                },
+                {
+                    title: vm.$t('ability.time'),
+                    key: 'time'
+                },
+            ],
+            appraiseArr: [],
+            curAbility: 0,
+            curGroup: vm.$t('ability.all'),
+            isShowDetail: false,
+            isShowReview: false,
+            curData: false,
+            groupData: [],
+            curReviewMode: '',
+            originList: []
+        }
+    },
+    created() {
+        this.getAllSubs()
+    },
+    methods: {
+        goBack() {
+            this.isShowReview = false
+            this.searchVal = ''
+            this.getAllSubs()
+        },
+		/* 根据评论ID查找评论内容 */
+		getAppraiseContentById(id){
+			return new Promise((r,j) => {
+				this.$api.jyzx.getReplyContent({
+					"school": this.$store.state.userInfo.schoolCode,
+				    "replyIds": [id]
+				}).then(res => {
+					r(res.replies.map(i => i.replies.comment)[0])
+				})
+			})
+		},
+        exportData(type) {
+            let downloadData = JSON.parse(JSON.stringify(this.origin))
+            downloadData.forEach(i => {
+                if (i.schoolAppraise !== '-') {
+                    i.schoolAppraise = [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][i.schoolAppraise]
+                }
+            })
+            const params = {
+                title: this.ablitiesColumn.map(i => i.title).slice(0, this.ablitiesColumn.length - 1),
+                key: this.ablitiesColumn.map(i => i.key).slice(0, this.ablitiesColumn.length - 1),
+                data: downloadData,
+                autoWidth: true,
+                filename: this.$t('ability.fileName')
+            }
+            excel.export_array_to_excel(params)
+        },
+        getAllSubs() {
+            this.origin = []
+            this.tableLoading = true
+            this.$api.jyzx.getOtherSubs({
+                "tmdid": this.$store.state.userInfo.TEAMModelId,
+                "school": this.$store.state.userInfo.schoolCode,
+                "all": "1"
+            }).then(res => {
+                res.groupMembers.forEach(i => {
+                    if (i.sub.uploads.length) {
+                        let ability = res.abilities.find(j => j.id === i.sub.abilityId)
+                        i.dimension = this.$GLOBAL.DIMENSIONS().find(j => j.code === res.abilities.find(k => k.id === i.sub.abilityId).dimension).val
+                        i.ability = ability.no + ' ' + ability.name
+                        i.time = i.sub.uploads.length ? this.$tools.formatTime(i.sub.uploads[0].time) : '-'
+                        i.env = ability.env
+                        i.name = i.tmdname
+                        i.id = ability.id
+                        i.teacherAppraise = this.$t('ability.noSpot')
+                        i.schoolAppraise = i.sub.otherScore.find(i => i.roleType === 'leader') ? i.sub.otherScore.find(i => i.roleType === 'leader').score : '-'
+                        this.origin.push(i)
+                    }
+                })
+                this.tableLoading = false
+                this.originList = JSON.parse(JSON.stringify(this.origin))
+                this.doGroup()
+            })
+        },
+        goAppraiseDetail(data) {
+			let promiseArr = []
+			data.sub.otherScore.forEach(async i => {
+				promiseArr.push(this.getAppraiseContentById(i.replyIds[i.replyIds.length - 1]))
+			})
+			Promise.all(promiseArr).then(result => {
+				this.appraiseArr = data.sub.otherScore.map((i,index) => {
+				    return {
+				        name: i.tmdname,
+				        result: [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][i.score],
+				        content: result[index] || '-',
+				        type: this.$t('ability.appraiseOther'),
+				        time: this.$tools.formatTime(i.time)
+				    }
+				})
+				this.appraiseArr.unshift({
+				    name: data.tmdname,
+				    result: [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][data.sub.self],
+				    content: '-',
+				    type: this.$t('ability.appraiseSelf'),
+				    time: this.$tools.formatTime(data.sub.uploads[0].time)
+				})
+				this.curData = data
+				this.isShowDetail = true
+			}).catch(err => {
+				console.log(err)
+				this.appraiseArr = data.sub.otherScore.map(i => {
+				    return {
+				        name: i.tmdname,
+				        result: [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][i.score],
+				        content: i.replyIds[0],
+				        type: this.$t('ability.appraiseOther'),
+				        time: this.$tools.formatTime(i.time)
+				    }
+				})
+				this.appraiseArr.unshift({
+				    name: data.tmdname,
+				    result: [this.$t('ability.bad'),this.$t('ability.normal'),this.$t('ability.good')][data.sub.self],
+				    content: '-',
+				    type: this.$t('ability.appraiseSelf'),
+				    time: this.$tools.formatTime(data.sub.uploads[0].time)
+				})
+				this.curData = data
+				this.isShowDetail = true
+			})
+            
+        },
+        goReview(data) {
+            // if (data.tmdid === this.$store.state.userInfo.TEAMModelId) {
+            //     this.$Message.warning(this.$t('ability.appraiseTip'))
+            //     return
+            // }
+            // this.curData = data
+            // let reviewData = {
+            //     id: data.sub.abilityId,
+            //     uploads: data.sub.uploads,
+            //     targetId: data.tmdid,
+            //     targetName: data.tmdname
+            // }
+            // this.curData = reviewData
+            // this.isShowReview = true
+            // this.curReviewMode = 'leader'
+			this.$emit('doReview',data)
+			
+        },
+        getAllAbilities() {
+            return new Promise((r, j) => {
+                let findParams = {
+                    "scope": "school",
+                    "code": this.$store.state.userInfo.schoolCode,
+                    "dimension": "",
+					"standard":sessionStorage.getItem('standard'),
+                    "status": 1
+                }
+                this.$api.ability.FindVolumes(findParams).then(res => {
+                    if (!res.error) {
+                        res.abilities.unshift({
+                            name: this.$t('ability.allAbilities'),
+                            no: '',
+                            id: ''
+                        })
+                        this.abilityList = res.abilities.filter(i => i.currency !== 2).sort(function(s, t) {
+							var a = s.no.toLowerCase();
+							var b = t.no.toLowerCase();
+							if (a.length === 2) {
+								a = a.slice(0, a.length - 1) + '0' + a.slice(-1)
+							}
+							if (b.length === 2) {
+								b = b.slice(0, b.length - 1) + '0' + b.slice(-1)
+							}
+
+							if (a < b) return -1;
+							if (a > b) return 1;
+							return 0;
+						});
+                    } else {
+                        this.$Message.warning(res.error);
+                    }
+                }).catch(err => {
+                    this.$Message.error(err);
+                })
+            })
+        },
+        handleSpan({
+            row,
+            column,
+            rowIndex,
+            columnIndex
+        }) {
+            if (columnIndex === 0) {
+                if (this.spanb[rowIndex]) {
+                    return {
+                        rowspan: this.spanb[rowIndex],
+                        colspan: 1
+                    }
+                } else {
+                    return {
+                        rowspan: 0,
+                        colspan: 1
+                    }
+                }
+            }
+
+        },
+        doGroup() {
+            let contactDotb = 0;
+            let spanb = [];
+            this.origin.forEach((item, index) => {
+                if (index === 0) {
+                    console.log(spanb)
+                    spanb.push(1)
+                } else {
+                    if (item.name === this.origin[index - 1].name) {
+                        spanb[contactDotb] += 1;
+                        spanb.push(0)
+                    } else {
+                        contactDotb = index
+                        spanb.push(1)
+                    }
+                }
+            })
+            this.spanb = spanb;
+        },
+
+        onAbilityFilter(val) {
+            if (val === 0) {
+                if (this.curGroup === this.$t('ability.all')) {
+                    this.origin = this.originList
+                } else {
+                    this.origin = this.originList.filter(i => i.groupName === this.curGroup)
+                }
+            } else {
+                let curAbilityId = this.abilityList[val].id
+                if (this.curGroup === this.$t('ability.all')) {
+                    this.origin = this.originList.filter(i => i.id === curAbilityId)
+                } else {
+                    this.origin = this.originList.filter(i => i.id === curAbilityId && i.groupName === this.curGroup)
+                }
+            }
+            this.doGroup()
+        },
+
+        onGroupFilter(val) {
+            if (val === this.$t('ability.all')) {
+                if (this.curAbility === 0) {
+                    this.origin = this.originList
+                } else {
+                    let curAbilityId = this.abilityList[this.curAbility].id
+                    this.origin = this.originList.filter(i.id === curAbilityId)
+                }
+            } else {
+                if (this.curAbility === 0) {
+                    this.origin = this.originList.filter(i => i.groupName === val)
+                } else {
+                    let curAbilityId = this.abilityList[this.curAbility].id
+                    this.origin = this.originList.filter(i => i.groupName === val && i.id === curAbilityId)
+                }
+            }
+            this.doGroup()
+        },
+
+        onSearch(val) {
+            this.origin = this.originList.filter(i => i.name.indexOf(this.searchVal) > -1)
+        },
+		
+		getTeacherGroups() {
+		    let params = {
+		        tmdid: this.$store.state.userInfo.TEAMModelId,
+		        schoolId: this.$store.state.userInfo.schoolCode,
+		        opt: 'manage'
+		    }
+		    this.$api.common.getActivityTarget(params).then(
+		        res => {
+					this.groupList = res.groupLists.filter(i => i.type === 'research').map(i => {
+						return {
+							groupName:i.name,
+							groupId:i.id,
+							teachers:[]
+						}
+					})
+					this.groupList.unshift({
+					    groupName: this.$t('ability.all'),
+					    groupId: '-1',
+					    teachers: []
+					})
+		        },
+		        err => {
+		            this.$Messag.error('查询发布对象失败')
+		        }
+		    )
+		},
+    },
+    mounted() {
+		this.getTeacherGroups()
+        this.getAllAbilities()
+    },
+    computed: {
+        ...mapGetters({
+            teachers: 'user/getSchoolUserJoined', // 取得已加入此學校的使用者
+        })
+    },
+}
+</script>
+<style lang="less" src="./GroupReview.less" scoped></style>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/ability/Review.vue

@@ -226,7 +226,7 @@
 						appraiseParams.tmdid = this.data.targetId
 						appraiseParams.opt = "YouRateSomone"
 						appraiseParams.otherScore = {
-							roleType:this.mode === 'school' ? 'school' : 'member',
+							roleType:this.mode === 'leader' ? 'leader' : 'member',
 							tmdid:this.$store.state.userInfo.TEAMModelId,
 							tmdname:this.$store.state.userInfo.name,
 							atTmdname:this.data.targetName,

+ 13 - 8
TEAMModelOS/ClientApp/src/view/abilityMgmt/Index.vue

@@ -24,11 +24,11 @@
 							<Icon type="md-search" :title="$t('syllabus.search')" @click="doSearchVolume"
 								v-if="volumeList.length" />
 							<Icon type="md-settings" title="设置选修/必修/通识" @click="doSetCompulsory"
-								v-if="!inSchoolAbility && volumeList.length" />
+								v-if="hasAbilityAuth && volumeList.length" />
 							<!-- <Icon type="ios-paper" title="查看检测试卷" @click="onShowPaper"
 								v-if="volumeList.length" />	 -->
 							<Icon type="md-create" :title="$t('syllabus.edit')" @click="doEditVolume"
-								v-if="!inSchoolAbility && volumeList.length" />
+								v-if="hasAbilityAuth && volumeList.length" />
 							<!-- <Icon type="md-trash" :title="$t('syllabus.delete')" @click="doDeleteVolume"
 								v-if="!inSchoolAbility && volumeList.length" />
 							<Icon type="md-add" :title="$t('syllabus.add')" @click="doAddVolume"
@@ -74,7 +74,7 @@
 					<!--<span>{{ $t('syllabus.syllabusMenu') }}</span>-->
 					{{ $t('ability.mgmt.paper') }}
 					<span class="syllabus-content-header-tools"
-						v-if="volumeList.length && curVolume.id && !inShareView &&  !inSchoolAbility">
+						v-if="volumeList.length && curVolume.id && !inShareView &&  hasAbilityAuth">
 						<span style="margin-right: 20px;font-weight: 400;font-size: 12px;cursor: pointer;" @click="isShowPaper = false"><Icon type="md-reorder" size="16" style="margin-right: 5px;"/>切换到章节视图</span>
 						<Dropdown @on-click="onAddQues" style="font-weight: 400;">
 							<a href="javascript:void(0)" style="color: #6b6b6b;font-size: 12px;">
@@ -103,13 +103,13 @@
 					{{ $t('ability.mgmt.chapter') }}
 					<span class="syllabus-content-header-tools"
 						v-if="volumeList.length && curVolume.id && !inShareView">
-						<Icon type="md-add" @click="isAddTreeModal = true" v-if="(hasSyllabusAuth || hasVolumeAuth(curVolume.auth)) &&  !inSchoolAbility" />
+						<Icon type="md-add" @click="isAddTreeModal = true" v-if="(hasSyllabusAuth || hasVolumeAuth(curVolume.auth)) &&  hasAbilityAuth" />
 					</span>
 				</div>
 				<div class="syllabus-tree-box">
 					<EmptyData :top="-240" v-if="!treeOrigin.length"></EmptyData>
 					<Tree ref="treeRef" :treeData="treeOrigin" :volume="curVolume"
-						:editable="hasSyllabusAuth || hasEditAuth(curNode)" @onNodeClick="onNodeClick"
+						:editable="hasAbilityAuth" @onNodeClick="onNodeClick"
 						@doShare="doShare" @addModifyId="addModifyId" v-else>
 					</Tree>
 				</div>
@@ -118,7 +118,7 @@
 				<div class="syllabus-content-header">
 					<!--<span>{{ $t('syllabus.relate') }}</span>-->
 					{{ $t('ability.mgmt.resource') }}({{ curNode.rnodes.length }})
-					<span class="syllabus-content-header-tools" v-if="!inSchoolAbility">
+					<span class="syllabus-content-header-tools" v-if="hasAbilityAuth">
 						<!-- <Icon type="md-add" @click="onAddResource" v-if="curNode.id"/> -->
 						<!-- <Tooltip :content="$t('tip.addVolumeResource')" class="common-toolTip" placement="bottom" theme="light" max-width="200">
 						    <Icon type="ios-information-circle-outline"/>
@@ -161,12 +161,12 @@
 							<img src="../../assets/source/unknow.png" v-else="item.type === 'other'" />
 							<span v-html="item.title" style="max-width: 70%;cursor: pointer;"
 								@click="onPreview(item)"></span>
-							<div class="node-resource-tools"  v-if="!inSchoolAbility || $access.can('area.*')">
+							<div class="node-resource-tools"  v-if="hasAbilityAuth || $access.can('area.*')">
 								<!-- <div class="node-resource-tool" >
 									<Icon type="md-eye" />
 									<span>{{ $t('syllabus.preview') }}</span>
 								</div> -->
-								<div class="node-resource-tool" @click="onDeleteResource(item,index)" v-if="!inSchoolAbility">
+								<div class="node-resource-tool" @click="onDeleteResource(item,index)" v-if="hasAbilityAuth">
 									<Icon type="md-trash" />
 									<span>{{ $t('syllabus.remove') }}</span>
 								</div>
@@ -2037,6 +2037,11 @@
 			isAreaAbility(){
 				return this.$route.name === 'areaAbilityMgmt'
 			},
+			// 判断是否有能力点的编辑权限(区级管理 + 未对接省平台)
+			hasAbilityAuth(){
+				let isAccess = sessionStorage.getItem('areaAccess') && sessionStorage.getItem('areaAccess') == 1
+				return this.$route.name === 'areaAbilityMgmt' && !isAccess
+			}
 		},
 		watch: {
 			volumeList: {

+ 17 - 1
TEAMModelOS/ClientApp/src/view/areaSetting/AreaSetting.vue

@@ -86,6 +86,21 @@
 					</div>
 				</div>
 			</div>
+			<div class="setting-block">
+				<p class="title">接口配置
+				<!-- <span>
+					<Tooltip content="设置教师各方面研修合格所需达到的学时" class="common-toolTip" placement="right" theme="light" max-width="200">
+					    <Icon type="ios-help-circle-outline" />
+					</Tooltip>
+				</span> -->
+				</p>
+				<div class="content">
+					<div class="setting-item">
+						<p>配置内容</p>
+						<Input v-model="areaSetting.accessConfig" style="width: 80%;margin-left: 10px;"/>
+					</div>
+				</div>
+			</div>
         </div>
 		<Button type="info" size="large" @click="saveAreaSetting" :loading="btnLoading">保存变更</Button>
 	</div>
@@ -113,7 +128,8 @@ export default {
 				video:['mp4','webm'],
 				audio:[],
 				image:[],
-				gzip:[]
+				gzip:[],
+				accessConfig:'',
 			}
         }
     },

+ 3 - 3
TEAMModelOS/ClientApp/src/view/areatrain/TrainMgt.less

@@ -13,7 +13,7 @@
     flex-wrap: wrap;
 }
 .train-item{
-    width: 300px;
+    width: 310px;
     background: #fcfcfc;
     border: 1px solid #f0f0f0;
     padding-bottom: 10px;
@@ -35,13 +35,13 @@
         // transform: scale(1.1);
     }
     .train-img-box{
-        width: 300px;
+        width: 310px;
         height: 150px;
         overflow: hidden;   
     }
     .train-img{
         transition: all 0.3s;
-        width: 300px;
+        width: 310px;
         height: 150px;
         background-size: cover;
         background-repeat: no-repeat;

+ 7 - 8
TEAMModelOS/ClientApp/src/view/classmgt/ClassStudent.vue

@@ -617,20 +617,19 @@ export default {
         findClassStu() {
             this.tableLoading = true
             let params = {
-                school_code: this.$store.state.userInfo.schoolCode,
-                ids: [this.curClassCode]
+                id: this.curClassCode,
+                code: this.$store.state.userInfo.schoolCode
             }
-            this.$api.schoolSetting.getStusByClassId(params).then(
+            this.$api.common.getClassStudent(params).then(
                 (res) => {
-                    if (!res.error) {
-                        this.$set(this.classList[this.curClassIndex], 'students', res.list.length ? res.list[0].students : [])
-                        // this.classList[this.curClassIndex].students = res.list.length ? res.list[0].students : []
+                    if (res.students) {
+                        this.$set(this.classList[this.curClassIndex], 'students', res.students)
                     } else {
-                        this.$Message.error('API error!')
+                        this.$Message.error('获取班级名单失败')
                     }
                 },
                 (err) => {
-                    this.$Message.error('API error!')
+                    this.$Message.error('获取班级名单失败')
                 }
             ).finally(() => {
                 setTimeout(() => {

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

@@ -306,7 +306,7 @@
 			// this.getBlobOrigin()
 		},
 		methods: {
-
+			
 			/** 获取区班校信息 */
 			getSchoolInfo() {
 				this.dataLoading = true;

+ 3 - 1
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -259,7 +259,9 @@
 						multipleRule: paper.multipleRule,
 						startTime: 0,
 						endTime: 0,
-						createType: 'manual'
+						createType: 'manual',
+						typeSummaryInfo:paper.typeSummaryInfo,
+						orderTemp:paper.orderTemp
 					}
 					this.isPreview = true
 					this.$emit('onPaperClick')

+ 19 - 19
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue

@@ -148,25 +148,25 @@
 				return this.$store.state.totalAnalysis.paperScrollTop
 			},
 		},
-		beforeRouteEnter(to, from, next) {
-			if(from.name !== 'answerSheet'){
-				to.meta.isKeep = false
-			}else{
-				// console.error('进入题库收到的',to.meta.isKeep)
-				to.meta.isKeep = true
-			}
-			next();
-		},
-		beforeRouteLeave(to, from, next) {
-			if(to.name === 'newSchoolPaper' || to.name === 'newPrivatePaper'){
-				// 设置下一个路由的 meta
-				to.meta.isKeep = false;  // 让 A 缓存,即不刷新
-			}
-			if(to.name === 'answerSheet'){
-				from.meta.isKeep = true
-			}
-			next();
-		},
+		// beforeRouteEnter(to, from, next) {
+		// 	if(from.name !== 'answerSheet'){
+		// 		to.meta.isKeep = false
+		// 	}else{
+		// 		// console.error('进入题库收到的',to.meta.isKeep)
+		// 		to.meta.isKeep = true
+		// 	}
+		// 	next();
+		// },
+		// beforeRouteLeave(to, from, next) {
+		// 	if(to.name === 'newSchoolPaper' || to.name === 'newPrivatePaper'){
+		// 		// 设置下一个路由的 meta
+		// 		to.meta.isKeep = false;  // 让 A 缓存,即不刷新
+		// 	}
+		// 	if(to.name === 'answerSheet'){
+		// 		from.meta.isKeep = true
+		// 	}
+		// 	next();
+		// },
 	}
 </script>
 <style src="./index.less" lang="less" scoped></style>

+ 65 - 12
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue

@@ -9,11 +9,11 @@
 			<Loading :top="200" v-show="dataLoading" type="1"></Loading>
 			<div class="list-view" :key="typeIndex" v-for="(typeItem,typeIndex) in listData">
 				<p v-show="viewModel === 'type' && typeItem.list.length" class="type-name">
-					{{ $tools.numberConvertToUppercase(getLatestTypeIndex(typeItem.type) + 1) }}
+					{{ $tools.getChineseByNum(getLatestTypeIndex(typeItem.type) + 1) }}
 					: {{ exersicesType[typeItem.type] }}
-					<span style="font-size: 14px;font-weight: 600;">({{$t('answerSheet.tip9')}}
-						{{ typeItem.list.length }} {{$t('answerSheet.tip17')}} {{ typeItem.score || 0 }}
-						{{$t('evaluation.paperList.score')}})</span>
+					<!-- <span style="font-size: 14px;font-weight: 600;">({{ typeSummaryInfo ? typeSummaryInfo[typeItem.type] : '' }})</span> -->
+					<span style="font-size: 14px;font-weight: 600;">({{ getTypeSummary(typeItem) }})</span>
+					<Icon type="md-create" color="#6c6c6c" size="16" style="margin-left: 10px;cursor: pointer;" @click="onEditTypeSummary(typeItem)" v-if="!isExamPaper"></Icon>	
 				</p>
 
 				<div v-for="(item,index) of typeItem.list" :key="index"
@@ -58,11 +58,11 @@
 						<!-- 题干部分 -->
 						<div class="item-question">
 							<div v-if="viewModel === 'list'">
-								<div class="item-question-order">{{ index + 1 }} : </div>
+								<div class="item-question-order">{{ getTempOrder(index + 1) }} : </div>
 								<div class="item-question-text" v-html="item.question"></div>
 							</div>
 							<div v-else>
-								<div class="item-question-order">{{ pageSize * (pageNum - 1) + index + 1 }} : </div>
+								<div class="item-question-order">{{ getTempOrder(pageSize * (pageNum - 1) + index + 1) }} : </div>
 								<div class="item-question-text" v-html="item.question"></div>
 							</div>
 						</div>
@@ -259,6 +259,12 @@
 				<Button type="success">{{$t('evaluation.confirm')}}</Button>
 			</div>
 		</Modal>
+		
+		<!-- 编辑题型说明弹窗 -->
+		<Modal v-model="editSumaryModal" class-name="ex-score-modal" width="600px"
+			:title="exersicesType[curEditType] + '说明文本'" @on-visible-change="editModalChange" @on-ok="onConfirmChangeSummary">
+			<Input v-model="curSummary"/>
+		</Modal>
 	</div>
 </template>
 
@@ -285,6 +291,8 @@
 		data() {
 			let that = this
 			return {
+				curOrderTempIndex:0,
+				typeSummaryInfo:{},
 				scoreCol:[
 					{
 						title: '题号',
@@ -296,7 +304,7 @@
 									fontWeight: isGroup ? 'bold' : '400',
 									fontSize: isGroup ? '16px' : '14px'
 								}
-							},isGroup ? that.$tools.numberConvertToUppercase(params.row.groupIndex + 1) + '、' + params.row.type + '(' + params.row.score + '分)' : params.row.no);
+							},isGroup ? that.$tools.getChineseByNum(params.row.groupIndex + 1) + '、' + params.row.type + '(' + params.row.score + '分)' : params.row.no);
 						},
 						width:100
 					},
@@ -380,10 +388,27 @@
 				curErrorSingleAnswer: 'A',
 				curErrorMulAnswer: [],
 				noAnswerList: [],
-				answerModal: false
+				answerModal: false,
+				curEditType:'',
+				editSumaryModal:false,
+				curSummary:''
 			}
 		},
 		methods: {
+			/* 更换题号模板 */
+			onConfirmOrderTemp(index){
+				this.curOrderTempIndex = index
+			},
+			/* 编辑题型的描述文字 */
+			onEditTypeSummary(typeItem){
+				this.editSumaryModal = true
+				this.curEditType = typeItem.type
+				this.curSummary = this.getTypeSummary(typeItem)
+			},
+			/* 确认修改描述文本 */
+			onConfirmChangeSummary(){
+				this.$set(this.typeSummaryInfo,this.curEditType,this.curSummary)
+			},
 			/**
 			 * 题干展开与收缩
 			 * @param index
@@ -783,13 +808,14 @@
 			
 			this.$EventBus.$off('getNewPaper')
 			this.$EventBus.$on('getNewPaper', newPaper => {
-				console.log(newPaper)
+				console.log('BaseExerciseList > event > paper',newPaper)
 				let isSave = Number(sessionStorage.getItem('isSave'))
 				if (newPaper.item && newPaper.item.length && !isSave) {
 					let that = this
 					this.groupList = [] // 题型排序的数据
 					this.orderList = [] //顺序排列的数据
 					this.exerciseList = []
+					that.typeSummaryInfo = newPaper.typeSummaryInfo || that.typeSummaryInfo
 					this.paperInfo = newPaper
 					this.multipleRule = newPaper.multipleRule || 1 // 配分规则
 					if (newPaper.item.length) {
@@ -809,11 +835,12 @@
 							this._.mapKeys(this._.groupBy(newPaper.item, 'type'), function(value, key) {
 								if (key === item) {
 									/* 按照题型排序,并且计算每种题型的总分 */
-									that.groupList.push({
+									let typeInfo = {
 										type: key,
 										list: value,
 										score: value.reduce((p, e) => p + e.score, 0)
-									})
+									}
+									that.groupList.push(typeInfo)
 									that.exerciseList = that.exerciseList.concat(value)
 								}
 							})
@@ -823,7 +850,7 @@
 					this.originData = this.exerciseList
 					this.groupTypeList = this.groupList
 					this.totalNum = newPaper.item.length
-					console.log('groupType', this.groupTypeList);
+					this.curOrderTempIndex = newPaper.orderTemp || 0
 					// 剩余可分配分数 更新
 					this.surPlusScore = newPaper.score - newPaper.item.reduce((p, e) => Number(p) + Number(e.score),
 					0);
@@ -837,6 +864,20 @@
 			
 		},
 		computed: {
+			// 根据题号模板返回对应题号
+			getTempOrder(order){
+				return order => {
+					if(this.curOrderTempIndex === 0){
+						return order
+					}else if(this.curOrderTempIndex === 1){
+						return this.$tools.getRomanByNum(order)
+					}else if(this.curOrderTempIndex === 2){
+						return this.$tools.getChineseByNum(order)
+					}else{
+						return order
+					}
+				}
+			},
 			listData() {
 				return this.viewModel === 'type' ? this.groupList : this.orderList
 			},
@@ -865,6 +906,17 @@
 					return arr.reduce((a, b) => a + this.getComposeScore(b), 0)  / 2
 				}
 			},
+			/* 获取当前题型的说明文本 */
+			getTypeSummary(typeItem){
+				let that = this
+				return typeItem => {
+					if(that.typeSummaryInfo && that.typeSummaryInfo[typeItem.type]){
+						return that.typeSummaryInfo[typeItem.type]
+					}else{
+						return `${this.$t('answerSheet.tip9')}${typeItem.list.length}${this.$t('answerSheet.tip17')}${typeItem.score || 0}${this.$t('evaluation.paperList.score')}`
+					}
+				}
+			}
 		},
 		watch: {
 			paper: {
@@ -995,6 +1047,7 @@
 		float: left;
 		color: white;
 		cursor: pointer;
+		font-size: 14px;
 	}
 
 	.components-el-container .exercise-item .item-tools-t:hover {

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

@@ -6,7 +6,7 @@
 		<div class="dp-content">
 			<div class="dp-group-item" v-for="(gItem,gIndex) in groupList">
 				<p v-show="gItem.list.length" class="dp-group-title">
-					<span>{{ $tools.numberConvertToUppercase(gIndex + 1) }} : {{ exersicesType[gItem.type] }}</span>
+					<span>{{ $tools.getChineseByNum(gIndex + 1) }} : {{ exersicesType[gItem.type] }}</span>
 					<span style="font-size: 14px;">({{ gItem.score || 0 }}{{$t('evaluation.paperList.score')}}) </span>
 				</p>
 					<div class="dp-item" v-for="(item,index) in gItem.list">

+ 1 - 0
TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less

@@ -291,6 +291,7 @@ exersices-attr-diff {
 .save-wrap {
     width:100%;
     justify-content:center;
+	margin-bottom: 20px;
 }
     .save-wrap .ivu-btn {
            font-size:16px;

+ 36 - 14
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -181,7 +181,8 @@
 				errorList: [],
 				noAnswerList: [],
 				oldPaper: null,
-				needSaveCosmosArr: []
+				needSaveCosmosArr: [],
+				typeSummaryInfo:null
 			}
 		},
 		async created() {
@@ -843,6 +844,8 @@
 					if (hasSurplus === 0) {
 						if (!noScoreList.length) {
 							this.isLoading = true
+							this.typeSummaryInfo = exListVm.typeSummaryInfo || {}
+							this.orderTempIndex = exListVm.curOrderTempIndex || 0
 							let isPaperExist = await this.isPaperExist(this.evaluationInfo.name)
 							let isContainerFull = await this.isContainerFull()
 							if (!isPaperExist || (this.isEditPaper && this.evaluationInfo.name === this.oldPaper
@@ -1053,8 +1056,7 @@
 			/* 保存试卷业务 */
 			async doSavePaper(list) {
 				sessionStorage.setItem('isSave', 1)
-				console.log('试卷数据', this.evaluationInfo)
-				console.log('试题数据', list)
+				console.error(this.orderTempIndex)
 				this.$Modal.remove()
 				let multipleRule = this.$refs.testPaper.$refs.exList.multipleRule
 				let modifyItems = this.$refs.testPaper.$refs.exList.modifyItems
@@ -1085,7 +1087,9 @@
 						score: this.evaluationInfo.score,
 						sheet: this.evaluationInfo.sheet || null,
 						tags: [...new Set(this.evaluationInfo.tags)],
-						multipleRule: multipleRule || 1
+						multipleRule: multipleRule || 1,
+						typeSummaryInfo:this.typeSummaryInfo,
+						orderTemp:this.orderTempIndex
 					}
 					let blobPaper = await this.$evTools.createBlobPaper(paperItem, res.slides)
 					// 首先保存新题目的JSON文件到Blob 然后返回URL链接
@@ -1094,8 +1098,6 @@
 					let sasData = this.evaluationInfo.type === 'private' ? await this.$tools
 						.getPrivateSas() : await this.$tools.getSchoolSas()
 					//初始化Blob
-					console.log(sasData);
-					console.log(this.evaluationInfo.type);
 					let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this
 						.evaluationInfo.type)
 					try {
@@ -1247,6 +1249,7 @@
 														'evaluation.paperList.saveSuc')
 												)
 												this.isLoading = false
+												this.$Spin.hide()
 												this.$router.push({
 													name: this
 														.evaluationInfo
@@ -1264,6 +1267,7 @@
 												this.$Message.error(this.$t(
 													'evaluation.paperList.saveFail'
 												))
+												this.$Spin.hide()
 												this.isLoading = false
 											}
 										},
@@ -1271,6 +1275,7 @@
 											this.$Message.error(this.$t(
 												'evaluation.paperList.saveFail'))
 											this.isLoading = false
+											this.$Spin.hide()
 										}
 									)
 								} else {
@@ -1365,8 +1370,6 @@
 			async doRender(paper) {
 				let schoolInfo = null
 				if (paper.paperGrade) {
-					console.log('传进来缓存的paper')
-					console.log(paper)
 					this.evaluationInfo = paper
 					this.oldPaper = JSON.parse(JSON.stringify(this.evaluationInfo))
 					if (paper.scope === 'school') {
@@ -1379,8 +1382,7 @@
 					}
 					return
 				}
-				console.log('渲染的试卷', paper)
-				// localStorage.setItem('c_edit_paper',JSON.stringify(paper))
+				console.log('createPaper > paper', paper)
 				if (paper.scope === 'school') {
 					schoolInfo = await this.getSchoolBaseInfo()
 					console.log(schoolInfo);
@@ -1407,18 +1409,18 @@
 					tags: paper.tags || [],
 					startTime: 0,
 					endTime: 0,
-					createType: 'manual'
+					createType: 'manual',
+					typeSummaryInfo:paper.typeSummaryInfo,
+					orderTemp:paper.orderTemp || 0
 				}
-				console.error(this.propPeriod)
 				this.oldPaper = JSON.parse(JSON.stringify(this.evaluationInfo))
 			}
 		},
 		mounted() {
 			let routerData = this.$route.params.paper
 			this.tags = JSON.parse(sessionStorage.getItem('paperTags')) || []
-			console.log('xxxx', routerData)
+			console.log('createPaper > routerData', routerData)
 			if (routerData) {
-				console.log(routerData)
 				this.doRender(routerData)
 				this.editPaper = routerData
 				this.isEditPaper = true
@@ -1467,6 +1469,26 @@
 		},
 
 		watch: {
+			isLoading(n){
+				if(n){
+					this.$Spin.show({
+						render: (h) => {
+							return h('div', [
+								h('Icon', {
+									'class': 'demo-spin-icon-load',
+									props: {
+										type: 'ios-loading',
+										size: 18
+									}
+								}),
+								h('div', '试卷保存中...')
+							])
+						}
+					});
+				}else{
+					this.$Spin.hide()
+				}
+			},
 			isGeneratePaper(n,o){
 				if(!this.isSchool){
 					this.split1 = n ? 0.2 : 0

+ 57 - 3
TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue

@@ -34,11 +34,11 @@
 								v-show="paperInfo.item.length && !isShowAnalysis">{{ isAllOpen ? $t('evaluation.index.collapseAll') : $t('evaluation.index.openAll')}}</Button>
 							<Button class="base-info-btn" type="info" @click="onSetScoreByType"
 								v-show="paperInfo.item.length && !isShowAnalysis">{{$t('evaluation.exerciseList.typeScore')}}</Button>
-							<!-- <Button class="base-info-btn" type="info" @click="onCleanPaper" v-show="paperInfo.item.length && !isShowAnalysis">{{$t('evaluation.paperList.cleanItems')}}</Button> -->
 							<Button class="base-info-btn" type="info" @click="onViewModelChange"
 								v-show="paperInfo.item.length && !isShowAnalysis">{{ `${ viewModel === 'type' ? this.$t('evaluation.paperList.orderByList') : this.$t('evaluation.paperList.orderByType') }` }}</Button>
 							<Button class="base-info-btn" type="info" @click="isShowAnalysis = !isShowAnalysis"
 								v-show="paperInfo.item.length">{{ isShowAnalysis ? this.$t('evaluation.paperList.paperDetails') : this.$t('evaluation.paperList.paperAnalysis')}}</Button>
+							<Button class="base-info-btn" type="info" v-show="paperInfo.item.length && paperInfo.id" @click="onChooseOrderTemp">题号模板</Button>
 							<Button class="base-info-btn" type="info" @click="downloadSheet" :loading="downLoading"
 								v-show="paperInfo.item.length && paperInfo.id && paper.sheet">{{ $t('evaluation.paperList.goAnswerSheet') }}</Button>
 							<Button class="base-info-btn" type="info" @click="goAnswerSheet"
@@ -86,6 +86,23 @@
 				</TabPane>
 			</Tabs>
 		</Modal>
+		
+		<!-- 选择题号模板 -->
+		<Modal v-model="orderTempModal" title="题号模板选择" width="600px"
+			class="related-point-modal order-temp-modal" @on-ok="onConfirmOrderTemp">
+			<div :class="['order-temp-item',curOrderTempIndex === 0 ? 'order-temp-item-active' : '']" @click="onClickOrderTemp(0)">
+				<p>阿拉伯数字 <span class="order-temp-item-info">(例:1,2,3,4,5......)</span> </p>
+			</div>
+			<div :class="['order-temp-item',curOrderTempIndex === 1 ? 'order-temp-item-active' : '']" @click="onClickOrderTemp(1)">
+				<p>罗马数字 <span class="order-temp-item-info">(例:Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ......)</span></p>
+			</div>
+			<div :class="['order-temp-item',curOrderTempIndex === 2 ? 'order-temp-item-active' : '']" @click="onClickOrderTemp(2)">
+				<p>中文小写 <span class="order-temp-item-info">(例:一、二、三、四、五......)</span></p>
+			</div>
+			<!-- <div :class="['order-temp-item',curOrderTempIndex === 3 ? 'order-temp-item-active' : '']" @click="onClickOrderTemp(3)">
+				<p>中文大写 <span class="order-temp-item-info">(例:壹、贰、叁、肆、伍......)</span></p>
+			</div> -->
+		</Modal>
 
 	</div>
 </template>
@@ -135,6 +152,8 @@
 		},
 		data() {
 			return {
+				curOrderTempIndex:0,
+				orderTempModal:false,
 				isShowPasteTool:false,
 				addNewModal: false,
 				scoreTableModal: false,
@@ -188,6 +207,16 @@
 				// 	this.isShowPasteTool = true
 				// }
 			},
+			onClickOrderTemp(val){
+				console.log(val);
+				this.curOrderTempIndex = val
+			},
+			onChooseOrderTemp(){
+				this.orderTempModal = true
+			},
+			onConfirmOrderTemp(){
+				this.$refs.exList.onConfirmOrderTemp(this.curOrderTempIndex)
+			},
 			/* 下载Blob答题卡 */
 			async downloadSheet() {
 				console.log(this.paperInfo)
@@ -349,6 +378,7 @@
 		},
 		mounted() {
 			// this.isShowSave = window.location.pathname === '/home/evaluation/testPaper'
+			this.$Spin.hide()
 			let paper = this.paper || this.$route.params.paper || JSON.parse(localStorage.getItem('c_edit_paper'))
 			if (!paper || !paper.item) return
 			console.log('xxxx', paper)
@@ -356,6 +386,7 @@
 			// localStorage.setItem('_paperInfo', JSON.stringify(paper))
 			this.paperInfo = paper // 自己页面的值
 			this.paperDiff = paper.item ? this.handleDiffCalc(paper.item) : 0
+			this.curOrderTempIndex = paper.orderTemp || 0
 
 		},
 		computed: {
@@ -374,9 +405,10 @@
 				handler(newValue, oldValue) {
 					if (newValue.item && newValue.item.length) {
 						this.$nextTick(() => {
-							console.log('TestPaper组件接受的paper', newValue)
+							console.log('TestPaper > paper', newValue)
 							this.$EventBus.$emit('getNewPaper', newValue)
 						})
+						this.curOrderTempIndex = newValue.orderTemp || 0
 						this.paperInfo = newValue
 					}
 					this.paperDiff = newValue.item ? this.handleDiffCalc(newValue.item) : 4
@@ -389,9 +421,31 @@
 </script>
 <style src="../index/TestPaper.less" lang="less" scoped>
 </style>
-<style>
+<style lang="less">
 	.complete-line {
 		padding: 0 45px;
 		border-bottom: 2px solid rgb(128, 128, 128);
 	}
+	
+	.order-temp-modal{
+		.order-temp-item{
+			margin: 10px 0;
+			border: 1px solid #DDDDDD;
+			padding: 20px 15px;
+			border-radius: 5px;
+			font-size: 16px;
+			font-weight: bold;
+			cursor: pointer;
+			&-info{
+				font-size: 14px;
+				font-weight: 400;
+				margin-left: 15px;
+			}
+			
+			&-active{
+				background-color: #72cbff;
+				color: #fff;
+			}
+		}
+	}
 </style>

+ 4 - 4
TEAMModelOS/ClientApp/src/view/homepage/MinTable.vue

@@ -187,7 +187,7 @@ export default {
                                     try {
                                         let listRes = await this.getListInfo(listIds)
                                         if (listRes) {
-                                            stuList.push(...listRes.stuList)
+                                            stuList.push(...listRes.groups)
                                             this.fullCus.forEach(cusitem => {
                                                 cusitem.schedule.forEach(item => {
                                                     //补充教室信息
@@ -237,11 +237,11 @@ export default {
         //根据id获取stulist信息
         getListInfo(ids) {
             let requestData = {
-                'code': this.$store.state.userInfo.schoolCode,
-                'scope': 'school',
+                'schoolId': this.$store.state.userInfo.schoolCode,
+                // 'scope': 'school',
                 'ids': ids
             }
-            return this.$api.courseMgmt.findListSummary(requestData)
+            return this.$api.common.getGroupListByIds(requestData)
         },
         //根据schedule处理数据进行渲染
         dataToTable() {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/homework/ManageHomeWork.vue

@@ -577,7 +577,7 @@
 				this.split2 = 0.3
 				this.$refs.leftSplit.$el.getElementsByClassName('ivu-split-trigger-con')[0].style.display = 'none'
 			}
-			this.getMyCourse()
+			// this.getMyCourse()
 		},
 		computed: {
 			getCurCode() {

+ 498 - 405
TEAMModelOS/ClientApp/src/view/jyzx/application.vue

@@ -1,442 +1,535 @@
 <template>
-    <div class="application-container">
-        <div v-if="!isReview && !isShowDetail && !isShowPaper" style="height: 100%;">
-            <Card :bordered="false">
-                <Tabs :value="curTab" @on-click="onTabChange">
-                    <TabPane :label="$t('jyzx.application.list')" name="name1">
-                        <EmptyData v-if="!appList.length"></EmptyData>
-                        <div v-else class="app-table">
-                            <Table :columns="appCol" :data="appList" height="730">
-                                <template slot-scope="{ row }" slot="name">
-                                    <p v-if="row.name">{{ row.no }} {{ row.name }}</p>
-                                    <p v-else>-</p>
-                                </template>
-                                <template slot-scope="{ row }" slot="time">
-                                    <p v-if="row.uploads.length">
-                                        {{ $tools.formatTime(row.selfTime) }}
-                                    </p>
-                                    <p v-else>-</p>
-                                </template>
-                                <template slot-scope="{ row }" slot="result">
-                                    <p v-if="row.uploads.length" style="font-weight: bold;">
-                                        <span v-show="row.self === 2" style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
-                                        <span v-show="row.self === 1" style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
-                                        <span v-show="row.self === 0" style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
-                                    </p>
-                                    <p v-else>-</p>
-                                </template>
+	<div class="application-container">
+		<div v-if="!isReview && !isShowDetail && !isShowPaper" style="height: 100%;">
+			<Card :bordered="false">
+				<Tabs :value="curTab" @on-click="onTabChange" :animated="false">
+					<TabPane :label="$t('jyzx.application.list')" name="name1">
+						<div class="app-table">
+							<Table :columns="appCol" :data="appList" :loading="tableLoading" border>
+								<template slot-scope="{ row }" slot="name">
+									<p v-if="row.name">{{ row.no }} {{ row.name }}</p>
+									<p v-else>-</p>
+								</template>
+								<template slot-scope="{ row }" slot="time">
+									<p v-if="row.uploads.length">
+										{{ $tools.formatTime(row.selfTime) }}
+									</p>
+									<p v-else>-</p>
+								</template>
+								<template slot-scope="{ row }" slot="num">
+
+								</template>
+								<template slot-scope="{ row }" slot="result">
+									<p v-if="row.uploads.length" style="font-weight: bold;">
+										<span v-show="row.self === 2"
+											style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
+										<span v-show="row.self === 1"
+											style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
+										<span v-show="row.self === 0"
+											style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
+									</p>
+									<p v-else>-</p>
+								</template>
 								<template slot-scope="{ row }" slot="schoolAppraise">
-								    <p v-if="row.uploads.length" style="font-weight: bold;">
-								        <span v-show="row.schoolAppraise === 2" style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
-								        <span v-show="row.schoolAppraise === 1" style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
-								        <span v-show="row.schoolAppraise === 0" style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
-								    </p>
-								    <p v-else>-</p>
+									<p v-if="row.uploads.length" style="font-weight: bold;">
+										<span v-show="row.schoolAppraise === 2"
+											style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
+										<span v-show="row.schoolAppraise === 1"
+											style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
+										<span v-show="row.schoolAppraise === 0"
+											style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
+									</p>
+									<p v-else>-</p>
 								</template>
 								<template slot-scope="{ row }" slot="exerciseScore">
-								    <p style="font-weight: bold;">
-								        <span v-show="row.exerciseScore === -1" style="color: #a2a2a2;">-</span>
-								        <span v-show="row.exerciseScore === 0" style="color: red;">{{ $t('jyzx.application.noPass') }}</span>
-								        <span v-show="row.exerciseScore === 1" style="color: #007700;">{{ $t('jyzx.application.pass') }}</span>
-								    </p>
+									<p style="font-weight: bold;">
+										<span v-show="row.exerciseScore === -1" style="color: #a2a2a2;">-</span>
+										<span v-show="row.exerciseScore === 0"
+											style="color: red;">{{ $t('jyzx.application.noPass') }}</span>
+										<span v-show="row.exerciseScore === 1"
+											style="color: #007700;">{{ $t('jyzx.application.pass') }}</span>
+									</p>
 								</template>
-                                <template slot-scope="{ row }" slot="action">
-                                    <Button type="success" size="small" @click="doUpload(row)" v-if="!row.uploads.length">{{ $t('jyzx.application.load') }}</Button>
-                                    <Button size="small" @click="goAppraiseDetail(row)" v-else>{{ $t('jyzx.common.seeEvaluate') }}</Button>
-                                    <Button type="primary" size="small" @click="goTestPaper(row)" style="margin-left: 5px;" v-if="row.exerciseScore !== 1">{{ row.exerciseScore > -1 ? $t('jyzx.application.againTest') : $t('jyzx.application.meTest') }}</Button>
-                                </template>
-                            </Table>
-                        </div>
-                    </TabPane>
-                    <TabPane :label="$t('jyzx.application.discuss')" name="name2">
-                        <EmptyData :textContent="$t('jyzx.common.noData')" v-if="!otherList.length"></EmptyData>
-                        <div v-else class="app-table">
-                            <Table :columns="comCol" :data="otherList">
-								 <template slot-scope="{ row }" slot="myAppraise">
-                                    <span v-show="row.myAppraise === 2" style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
-                                    <span v-show="row.myAppraise === 1" style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
-                                    <span v-show="row.myAppraise === 0" style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
-                                    <span v-show="row.myAppraise === -1">{{ $t('jyzx.application.noEvaluate') }}</span>
-                                </template>
 								<template slot-scope="{ row }" slot="action">
-								    <Button :type="row.myAppraise === -1 ? 'primary':'info'" size="small" @click="appraiseOther(row)">{{ row.myAppraise === -1 ? $t('jyzx.application.score') : $t('jyzx.application.againScore') }}</Button>
+									<Button type="success" size="small" @click="doUpload(row)"
+										v-if="!row.uploads.length">{{ $t('jyzx.application.load') }}</Button>
+									<Button size="small" @click="goAppraiseDetail(row)"
+										v-else>{{ $t('jyzx.common.seeEvaluate') }}</Button>
+									<Button type="primary" size="small" @click="goTestPaper(row)"
+										style="margin-left: 5px;"
+										v-if="row.exerciseScore !== 1">{{ row.exerciseScore > -1 ? $t('jyzx.application.againTest') : $t('jyzx.application.meTest') }}</Button>
+								</template>
+							</Table>
+						</div>
+					</TabPane>
+					<TabPane label="组员互评" name="name2">
+						<!-- <EmptyData textContent="暂无数据" v-if="!otherList.length"></EmptyData> -->
+						<div class="app-table">
+							<Table :columns="comCol" :data="otherList" :span-method="handleSpan" :loading="tableLoading"
+								border>
+								<template slot-scope="{ row }" slot="myAppraise">
+									<span v-show="row.myAppraise === 2"
+										style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
+									<span v-show="row.myAppraise === 1"
+										style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
+									<span v-show="row.myAppraise === 0"
+										style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
+									<span v-show="row.myAppraise === -1">{{ $t('jyzx.application.noEvaluate') }}</span>
 								</template>
-                            </Table>
-                        </div>
-                    </TabPane>
-                </Tabs>
-            </Card>
-        </div>
-        <div class="animated appraise-detail" v-if="isShowDetail">
-            <div class="detail-title">
-                <Icon type="md-arrow-back" @click="isShowDetail = false" />
-                <span>{{ $store.state.userInfo.name }} 【 {{ curData.name }} 】</span>
-            </div>
-            <Table :columns="appraiseColumns" :data="appraiseArr" border>
-                <template slot-scope="{ row }" slot="result">
-                    <span v-show="row.result === '优秀'" style="color: #007700;">{{ $t('jyzx.application.fine') }}</span>
-                    <span v-show="row.result === '合格'" style="color: orangered;">{{ $t('jyzx.application.qualified') }}</span>
-                    <span v-show="row.result === '不合格'" style="color: red;">{{ $t('jyzx.application.unqualified') }}</span>
-                </template>
-            </Table>
-        </div>
-        <Review v-if="isReview" :mode="curReviewMode" :reviewData="reviewData" @goBack="goBack"></Review>
+								<template slot-scope="{ row }" slot="action">
+									<Button :type="row.myAppraise === -1 ? 'primary':'info'" size="small"
+										@click="appraiseOther(row)">{{ row.myAppraise === -1 ? $t('jyzx.application.score') : $t('jyzx.application.againScore') }}</Button>
+								</template>
+							</Table>
+						</div>
+					</TabPane>
+					<TabPane label="小组评价" name="name3" v-if="hasLeaderRole">
+						<div class="app-table">
+							<GroupReview @doReview="doReviewByLeader"></GroupReview>
+						</div>
+					</TabPane>
+				</Tabs>
+			</Card>
+		</div>
+		<div class="animated appraise-detail" v-if="isShowDetail">
+			<div class="detail-title">
+				<Icon type="md-arrow-back" @click="isShowDetail = false" />
+				<span>{{ $store.state.userInfo.name }} 【 {{ curData.name }} 】</span>
+			</div>
+			<Table :columns="appraiseColumns" :data="appraiseArr" border>
+				<template slot-scope="{ row, index }" slot="result">
+					<span v-show="row.result === 2" style="color: #007700;font-weight: bold;">{{ $t('jyzx.application.fine') }}</span>
+					<span v-show="row.result === 1"
+						style="color: orangered;font-weight: bold;">{{ $t('jyzx.application.qualified') }}</span>
+					<span v-show="row.result === 0"
+						style="color: red;font-weight: bold;">{{ $t('jyzx.application.unqualified') }}</span>
+				</template>
+			</Table>
+		</div>
+		<Review v-if="isReview" :mode="curReviewMode" :reviewData="reviewData" @goBack="goBack"></Review>
 		<TestPaper v-if="isShowPaper" :abilityData="curData" @goBack="goBack"></TestPaper>
-    </div>
+	</div>
 </template>
 
 <script>
-import Review from "@/view/ability/Review.vue"
-import TestPaper from "@/view/ability/TestPaper.vue"
-
-export default {
-    components: {
-        Review,TestPaper
-    },
-    data() {
-        return {
-			isShowPaper:false,
-            isShowDetail: false,
-            curReviewMode: 'self',
-			curTab:'name1',
-            appraiseColumns: [
-                {
-                    title: this.$t('jyzx.application.evaName'),
-                    key: 'name'
-                },
-                {
-                    title: this.$t('jyzx.application.evaType'),
-                    key: 'type'
-                },
-                {
-                    title: this.$t('jyzx.application.evaResult'),
-                    slot: 'result',
-                },
-                {
-                    title: this.$t('jyzx.application.evaContent'),
-                    key: 'content'
-                },
-                {
-                    title: this.$t('jyzx.application.evaTime'),
-                    key: 'time'
-                },
-            ],
-            appraiseArr: [],
-            appCol: [{
-                title: this.$t('jyzx.common.pointName'),
-                key: "name",
-                slot: "name",
-            },
-            {
-                title: this.$t('jyzx.common.loadTime'),
-                slot: "time",
-            },
-            {
-                title: this.$t('jyzx.application.disNum'),
-                key: "num",
-				width:100
-            },
-            {
-                title: this.$t('jyzx.application.disByMe'),
-                slot: "result",
-				width:100
-            },
-			{
-			    title: this.$t('jyzx.application.disBySchool'),
-			    slot: "schoolAppraise",
-				width:100
-			},
-			{
-			    title: this.$t('jyzx.application.spotCheck'),
-			    key: "teacherAppraise",
-				width:100
+	import Review from "@/view/ability/Review.vue"
+	import TestPaper from "@/view/ability/TestPaper.vue"
+	import GroupReview from '@/view/ability/GroupReview.vue'
+	export default {
+		components: {
+			Review,
+			TestPaper,
+			GroupReview
+		},
+		data() {
+			return {
+				tableLoading: false,
+				spanb: [],
+				isShowPaper: false,
+				isShowDetail: false,
+				curReviewMode: 'self',
+				curTab: 'name1',
+				groupMemberList: [],
+				appraiseColumns: [{
+						title: this.$t('jyzx.application.evaName'),
+						key: 'name'
+					},
+					{
+						title: this.$t('jyzx.application.evaType'),
+						key: 'type'
+					},
+					{
+						title: this.$t('jyzx.application.evaResult'),
+						slot: 'result',
+					},
+					{
+						title: this.$t('jyzx.application.evaContent'),
+						key: 'content'
+					},
+					{
+						title: this.$t('jyzx.application.evaTime'),
+						key: 'time'
+					},
+				],
+				appraiseArr: [],
+				appCol: [{
+						title: this.$t('jyzx.common.pointName'),
+						key: "name",
+						slot: "name",
+					},
+					{
+						title: this.$t('jyzx.common.loadTime'),
+						slot: "time",
+					},
+					{
+						title: this.$t('jyzx.application.disByMe'),
+						slot: "result",
+						width: 100
+					},
+					{
+						title: '互评结果',
+						slot: "num",
+						width: 100
+					},
+					{
+						title: '小组评价',
+						slot: "schoolAppraise",
+						width: 100
+					},
+					{
+						title: this.$t('jyzx.application.testByMe'),
+						slot: "exerciseScore",
+					},
+					{
+						title: this.$t('jyzx.common.action'),
+						slot: "action",
+					},
+				],
+				appList: [],
+				comCol: [{
+						title: this.$t('jyzx.application.teacherName'),
+						key: "tmdname",
+					},
+					{
+						title:'教研组',
+						key: "groupName",
+					},
+					{
+						title: this.$t('jyzx.common.dimension'),
+						key: "dimension",
+					},
+					{
+						title: this.$t('jyzx.common.point'),
+						key: "abilityName",
+					},
+					{
+						title: this.$t('jyzx.common.loadTime'),
+						key: "time",
+					},
+					{
+						title: this.$t('jyzx.application.evaResult'),
+						slot: "myAppraise",
+					},
+					{
+						title: this.$t('jyzx.common.action'),
+						slot: "action",
+					},
+				],
+				otherList: [],
+				isDiscuss: false,
+				curData: null,
+				isReview: false,
+				hasLeaderRole:false,
+				reviewData: null
+			}
+		},
+		methods: {
+			/* TAB切换 */
+			onTabChange(val) {
+				this.curTab = val
 			},
-			{
-			    title: this.$t('jyzx.application.testByMe'),
-			    slot: "exerciseScore",
+			/* 表格合并 */
+			handleSpan({
+		 	row,
+				column,
+				rowIndex,
+				columnIndex
+			}) {
+				if (columnIndex === 0) {
+					if (this.spanb[rowIndex]) {
+						return {
+							rowspan: this.spanb[rowIndex],
+							colspan: 1
+						}
+					} else {
+						return {
+							rowspan: 0,
+							colspan: 1
+						}
+					}
+				}
 			},
-            {
-                title: this.$t('jyzx.common.action'),
-                slot: "action",
-            },
-            ],
-            appList: [],
-            comCol: [{
-                title: this.$t('jyzx.application.teacherName'),
-                key: "tmdname",
-                align: "center",
-            },
-            {
-                title: this.$t('jyzx.common.dimension'),
-                key: "dimension",
-                align: "center",
-            },
-            {
-                title: this.$t('jyzx.common.point'),
-                key: "abilityName",
-                align: "center",
-            },
-            {
-                title: this.$t('jyzx.common.loadTime'),
-                key: "time",
-                align: "center",
-            },
-			{
-			    title: this.$t('jyzx.application.evaResult'),
-			    slot: "myAppraise",
-			    align: "center",
+			/* 分组操作 */
+			doGroup() {
+				let contactDotb = 0;
+				let spanb = [];
+				this.otherList.forEach((item, index) => {
+		 		if (index === 0) {
+						console.log(spanb)
+						spanb.push(1)
+					} else {
+						if (item.tmdname === this.otherList[index - 1].tmdname) {
+							spanb[contactDotb] += 1;
+							spanb.push(0)
+						} else {
+							contactDotb = index
+							spanb.push(1)
+						}
+					}
+				})
+				this.spanb = spanb;
 			},
-            {
-                title: this.$t('jyzx.common.action'),
-                slot: "action",
-                align: "center",
-            },
-            ],
-            otherList: [],
-            isDiscuss: false,
-            curData: null,
-            isReview: false,
-            reviewData: null
-        }
-    },
-    methods: {
-        onTabChange(val) {
-            this.curTab = val
-        },
-		/* 根据评论ID查找评论内容 */
-		getAppraiseContentById(id){
-			return new Promise((r,j) => {
-				this.$api.jyzx.getReplyContent({
-					"school": this.$store.state.userInfo.schoolCode,
-				    "replyIds": [id]
-				}).then(res => {
-					r(res.replies.map(i => i.replies.comment)[0])
+			/* 根据评论ID查找评论内容 */
+			getAppraiseContentById(id) {
+				return new Promise((r, j) => {
+					this.$api.jyzx.getReplyContent({
+						"school": this.$store.state.userInfo.schoolCode,
+						"replyIds": [id]
+					}).then(res => {
+						r(res.replies.map(i => i.replies.comment)[0])
+					})
 				})
-			})
-		},
-        goAppraiseDetail(data) {
-			let promiseArr = []
-			console.log(data);
-			data.otherScore.forEach(async i => {
-				promiseArr.push(this.getAppraiseContentById(i.replyIds[i.replyIds.length - 1]))
-			})
-			Promise.all(promiseArr).then(result => {
-				this.isShowDetail = true
-				this.appraiseArr = data.otherScore.map((i,index) => {
-				    return {
-				        name: i.roleType === 'school' ? this.$t('jyzx.application.admin') : this.$t('jyzx.application.teacher1'),
-				        result: [this.$t('jyzx.application.unqualified'), this.$t('jyzx.application.qualified'), this.$t('jyzx.application.fine')][i.score],
-				        content: result[index] || '-',
-				        type: i.roleType === 'school' ? this.$t('jyzx.application.evaSchool') : this.$t('jyzx.application.evaOther'),
-				        time: this.$tools.formatTime(i.time)
-				    }
+			},
+			/* 查看评价 */
+			goAppraiseDetail(data) {
+				let promiseArr = []
+				console.log(data);
+				data.otherScore.forEach(async i => {
+					promiseArr.push(this.getAppraiseContentById(i.replyIds[i.replyIds.length - 1]))
 				})
-				this.appraiseArr.unshift({
-				    name: this.$store.state.userInfo.name,
-				    result: [this.$t('jyzx.application.unqualified'), this.$t('jyzx.application.qualified'), this.$t('jyzx.application.fine')][data.self],
-				    content: '-',
-				    type: this.$t('jyzx.application.evaMe'),
-				    time: this.$tools.formatTime(data.uploads[0].time)
+				Promise.all(promiseArr).then(result => {
+					this.isShowDetail = true
+					this.appraiseArr = data.otherScore.map((i, index) => {
+				  return {
+							name: i.roleType === 'school' ? this.$t('jyzx.application.admin') : this.$t(
+								'jyzx.application.teacher1'),
+							result: i.score,
+							content: result[index] || '-',
+							type: i.roleType === 'school' ? this.$t('jyzx.application.evaSchool') : this
+								.$t('jyzx.application.evaOther'),
+							time: this.$tools.formatTime(i.time)
+						}
+					})
+					this.appraiseArr.unshift({
+						name: this.$store.state.userInfo.name,
+						result: data.self,
+						content: '-',
+						type: this.$t('jyzx.application.evaMe'),
+						time: this.$tools.formatTime(data.uploads[0].time)
+					})
+					console.error(this.appraiseArr)
+					this.curData = data
+				}).catch(err => {
+					this.isShowDetail = true
+					this.appraiseArr = data.otherScore.map(i => {
+						return {
+							name: i.roleType === 'school' ? this.$t('jyzx.application.admin') : this.$t(
+								'jyzx.application.teacher1'),
+							result: [this.$t('jyzx.application.unqualified'), this.$t(
+								'jyzx.application.qualified'), this.$t('jyzx.application.fine')][i
+								.score
+							],
+							content: i.replyIds[0],
+							type: i.roleType === 'school' ? this.$t('jyzx.application.evaSchool') : this
+								.$t('jyzx.application.evaOther'),
+							time: this.$tools.formatTime(i.time)
+						}
+					})
+					this.appraiseArr.unshift({
+						name: this.$store.state.userInfo.name,
+				  result: [this.$t('jyzx.application.unqualified'), this.$t(
+								'jyzx.application.qualified'), this.$t('jyzx.application.fine')][data
+							.self],
+						content: '-',
+						type: this.$t('jyzx.application.evaMe'),
+						time: this.$tools.formatTime(data.uploads[0].time)
+					})
+					this.curData = data
 				})
+
+			},
+			/* 自我检测 */
+			goTestPaper(data) {
+				this.isShowPaper = true
 				this.curData = data
-			}).catch(err => {
-				this.isShowDetail = true
-				this.appraiseArr = data.otherScore.map(i => {
-				    return {
-				        name: i.roleType === 'school' ? this.$t('jyzx.application.admin') : this.$t('jyzx.application.teacher1'),
-				        result: [this.$t('jyzx.application.unqualified'), this.$t('jyzx.application.qualified'), this.$t('jyzx.application.fine')][i.score],
-				        content: i.replyIds[0],
-				        type: i.roleType === 'school' ? this.$t('jyzx.application.evaSchool') : this.$t('jyzx.application.evaOther'),
-				        time: this.$tools.formatTime(i.time)
-				    }
+			},
+			/* 监听返回事件 */
+			goBack() {
+				this.isReview = false
+				this.isShowPaper = false
+				this.isShowDetail = false
+				this.tableLoading = true
+				this.getMyAbilities()
+				this.getOtherSubs()
+			},
+			/* 获取用户自己的研修考核材料 */
+			getMyAbilities() {
+				this.$api.jyzx.getPoint({
+					"tmdid": this.$store.state.userInfo.TEAMModelId,
+					"scope": "school",
+					"code": this.$store.state.userInfo.schoolCode
+				}).then(res => {
+					res.rcdSubs.forEach(i => {
+						let curAbility = res.hadSubs.find(j => j.id === i.id)
+						i.name = curAbility ? curAbility.name : ''
+						i.no = curAbility ? curAbility.no : ''
+						i.currency = curAbility ? curAbility.currency : 2
+						i.num = i.uploads.length ? (i.otherScore.length ? i.otherScore.filter(j => j
+							.roleType === 'member').length : 0) : 0
+						i.schoolAppraise = i.otherScore.length && i.otherScore.filter(j => j.roleType ===
+								'school').length ? i.otherScore.find(j => j.roleType === 'school').score :
+							-1
+						i.teacherAppraise = this.$t('jyzx.application.noCheck')
+						i.exerciseScore = i.exerciseScore
+					})
+					this.appList = res.rcdSubs.sort(function(s, t) {
+						var a = s.no.toLowerCase();
+						var b = t.no.toLowerCase();
+						if (a.length === 2) {
+							a = a.slice(0, a.length - 1) + '0' + a.slice(-1)
+						}
+						if (b.length === 2) {
+							b = b.slice(0, b.length - 1) + '0' + b.slice(-1)
+						}
+
+						if (a < b) return -1;
+						if (a > b) return 1;
+						return 0;
+					});
+					/* 忽略通识能力点 */
+					this.appList = this.appList.filter(i => i.currency !== 2)
+					console.log(this.appList);
 				})
-				this.appraiseArr.unshift({
-				    name: this.$store.state.userInfo.name,
-				    result: [this.$t('jyzx.application.unqualified'), this.$t('jyzx.application.qualified'), this.$t('jyzx.application.fine')][data.self],
-				    content: '-',
-				    type: this.$t('jyzx.application.evaMe'),
-				    time: this.$tools.formatTime(data.uploads[0].time)
+			},
+			/* 获取当前用户所有同组成员的考核数据 */
+			getOtherSubs() {
+				this.otherList = []
+				this.$api.jyzx.getOtherSubs({
+					"tmdid": this.$store.state.userInfo.TEAMModelId,
+					"school": this.$store.state.userInfo.schoolCode,
+					"all": "0"
+				}).then(res => {
+					let myId = this.$store.state.userInfo.TEAMModelId
+					res.groupMembers.forEach(i => {
+						if (i.sub.uploads.length) {
+							i.dimension = this.$GLOBAL.DIMENSIONS().find(j => j.code === res.abilities
+								.find(k => k.id === i.sub.abilityId).dimension).val
+							i.abilityName = res.abilities.find(j => j.id === i.sub.abilityId).no + ' ' +
+								res.abilities.find(j => j.id === i.sub.abilityId).name
+							i.time = i.sub.uploads.length ? this.$tools.formatTime(i.sub.uploads[0].time) :
+								'-'
+							i.myAppraise = i.sub.otherScore.find(j => j.tmdid === myId && j.roleType ===
+								'member') ? i.sub.otherScore.find(j => j.tmdid === myId && j
+								.roleType === 'member').score : -1
+							this.otherList.push(i)
+						}
+					})
+					console.log(this.otherList)
+					this.tableLoading = false
+					this.doGroup()
 				})
-				this.curData = data
-			})
-            
-        },
-		
-		goTestPaper(data){
-			this.isShowPaper = true
-			this.curData = data
-		},
-		
-        goBack() {
-            this.isReview = false
-			this.isShowPaper = false
-			this.isShowDetail = false
-            this.getMyAbilities()
-            this.getOtherSubs()
-        },
-		
-        getMyAbilities() {
-            this.$api.jyzx.getPoint({
-                "tmdid": this.$store.state.userInfo.TEAMModelId,
-                "scope": "school",
-                "code": this.$store.state.userInfo.schoolCode
-            }).then(res => {
-                res.rcdSubs.forEach(i => {
-					let curAbility = res.hadSubs.find(j => j.id === i.id)
-                    i.name = curAbility ? curAbility.name : ''
-                    i.no = curAbility ? curAbility.no : ''
-					i.currency = curAbility ? curAbility.currency : 2
-                    i.num = i.uploads.length ? (i.otherScore.length ? i.otherScore.filter(j => j.roleType === 'member').length : 0) : 0
-					i.schoolAppraise = i.otherScore.length && i.otherScore.filter(j => j.roleType === 'school').length ? i.otherScore.find(j => j.roleType === 'school').score : -1
-					i.teacherAppraise = this.$t('jyzx.application.noCheck')
-					i.exerciseScore = i.exerciseScore
-                })
-                this.appList = res.rcdSubs.sort(function(s, t) {
-					var a = s.no.toLowerCase();
-					var b = t.no.toLowerCase();
-					if (a.length === 2) {
-						a = a.slice(0, a.length - 1) + '0' + a.slice(-1)
-					}
-					if (b.length === 2) {
-						b = b.slice(0, b.length - 1) + '0' + b.slice(-1)
-					}
-
-					if (a < b) return -1;
-					if (a > b) return 1;
-					return 0;
-				});
-				/* 忽略通识能力点 */
-				this.appList = this.appList.filter(i => i.currency !== 2)
-                console.log(this.appList);
-            })
-        },
-
-        getOtherSubs() {
-			this.otherList = []
-            this.$api.jyzx.getOtherSubs({
-                "tmdid": this.$store.state.userInfo.TEAMModelId,
-                "school": this.$store.state.userInfo.schoolCode,
-                "all": "0"
-            }).then(res => {
-				let myId = this.$store.state.userInfo.TEAMModelId
-                res.groupMembers.forEach(i => {
-					if(i.sub.uploads.length){
-						i.dimension = this.$GLOBAL.DIMENSIONS().find(j => j.code === res.abilities.find(k => k.id === i.sub.abilityId).dimension).val
-						i.abilityName = res.abilities.find(j => j.id === i.sub.abilityId).no + ' ' + res.abilities.find(j => j.id === i.sub.abilityId).name
-						i.time = i.sub.uploads.length ? this.$tools.formatTime(i.sub.uploads[0].time) : '-'
-						i.myAppraise = i.sub.otherScore.find(j => j.tmdid === myId && j.roleType === 'member') ? i.sub.otherScore.find(j => j.tmdid === myId && j.roleType === 'member').score : -1
-						this.otherList.push(i)
+			},
+			/* 点击上传考核文件 */
+			doUpload(data) {
+				this.reviewData = data
+				this.isReview = true
+				this.curReviewMode = 'self'
+			},
+			/* 互评 */
+			appraiseOther(data) {
+				console.log(data)
+				let reviewData = {
+					id: data.sub.abilityId,
+					uploads: data.sub.uploads,
+					targetId: data.tmdid,
+					targetName: data.tmdname
+				}
+				this.reviewData = reviewData
+				this.isReview = true
+				this.curReviewMode = 'other'
+				console.log(this.curTab);
+			},
+			doReviewByLeader(data){
+				let reviewData = {
+					id: data.sub.abilityId,
+					uploads: data.sub.uploads,
+					targetId: data.tmdid,
+					targetName: data.tmdname
+				}
+				this.reviewData = reviewData
+				this.isReview = true
+				this.curReviewMode = 'leader'
+			},
+			getGroupLeaderTags(){
+				this.$api.common.getGroupLeaderTags({}).then(res => {
+					if(!res.error && res.groupLists.find(i => i.tag === 'leader')){
+						this.hasLeaderRole = true
+					}else{
+						this.hasLeaderRole = false
 					}
-                })
-				console.log(this.otherList)
-            })
-        },
-
-        doUpload(data) {
-            this.reviewData = data
-            this.isReview = true
-            this.curReviewMode = 'self'
-        },
-        appraiseOther(data) {
-            console.log(data)
-            let reviewData = {
-                id: data.sub.abilityId,
-                uploads: data.sub.uploads,
-                targetId: data.tmdid,
-                targetName: data.tmdname
-            }
-            this.reviewData = reviewData
-            this.isReview = true
-            this.curReviewMode = 'other'
-			console.log(this.curTab);
-        },
-
-        delApp() {
-            this.$Modal.confirm({
-                title: this.$t('jyzx.application.message1'),
-                okText: this.$t('jyzx.common.delete'),
-                cancelText: this.$t('jyzx.common.cancel'),
-                onOk: () => {
-                    this.$Message.success(this.$t('jyzx.common.success3'))
-                },
-            })
-        },
-        disApp(data) {
-            this.curData = data
-            this.isReview = true
-        },
-        cancelMo() {
-            this.isDiscuss = false
-        },
-    },
-    mounted() {
-        this.getMyAbilities()
-        this.getOtherSubs()
-    },
-    computed: {
-
-    }
-}
+				})
+			}
+		},
+		mounted() {
+			this.tableLoading = true
+			this.getGroupLeaderTags()
+			this.getMyAbilities()
+			this.getOtherSubs()
+		}
+	}
 </script>
 
 <style lang="less">
-.application-container {
-	height: 100%;
-	// background-color: #f7f7f7;
-    .ivu-card {
-        height: 100%;
+	.application-container {
+		height: 100%;
+
+		// background-color: #f7f7f7;
+		.ivu-card {
+			height: 100%;
 
-        .ivu-card-body {
-            height: 100%;
+			.ivu-card-body {
+				height: 100%;
 
-            .ivu-tabs {
-                height: 100%;
+				.ivu-tabs {
+					height: 100%;
+
+					.ivu-tabs-content-animated {
+						height: 100%;
+					}
+				}
+			}
+		}
 
-                .ivu-tabs-content-animated {
-                    height: 100%;
-                }
-            }
-        }
-    }
+		.ivu-tabs .ivu-tabs-tabpane {
+			height: 100%;
+		}
 
-    .ivu-tabs .ivu-tabs-tabpane {
-        height: 100%;
-    }
-    
-    .ivu-tabs-nav .ivu-tabs-tab,
-    .ivu-tabs-nav .ivu-tabs-tab:hover{
-        color: var(--second-text-color);
-    }
+		.ivu-tabs-nav .ivu-tabs-tab,
+		.ivu-tabs-nav .ivu-tabs-tab:hover {
+			color: var(--second-text-color);
+		}
 
-    .ivu-tabs-nav .ivu-tabs-tab-active{
-        border-color: var(--tabs-bottom-color);
-        color: var(--tabs-text-color);
-        font-weight: bold;
-    }
+		.ivu-tabs-nav .ivu-tabs-tab-active {
+			border-color: var(--tabs-bottom-color);
+			color: var(--tabs-text-color);
+			font-weight: bold;
+		}
 
-}
+	}
 </style>
 
 <style lang="less" scoped>
-.app-table {
-    height: calc(100vh - 190px);
-    padding: 0 5px;
-    overflow: auto;
-}
+	.app-table {
+		// height: calc(100vh - 190px);
+		height: 90vh;
+		padding: 0 5px;
+		overflow: auto;
+		padding-bottom: 50px;
+	}
 
-.appraise-detail {
-    padding: 20px;
+	.appraise-detail {
+		padding: 20px;
 
-    .detail-title {
-        font-size: 20px;
-        // font-weight: bold;
-        margin-bottom: 20px;
+		.detail-title {
+			font-size: 20px;
+			// font-weight: bold;
+			margin-bottom: 20px;
 
-        .ivu-icon {
-            font-size: 24px;
-            margin-right: 10px;
-            cursor: pointer;
-        }
-    }
-}
+			.ivu-icon {
+				font-size: 24px;
+				margin-right: 10px;
+				cursor: pointer;
+			}
+		}
+	}
 </style>

+ 0 - 0
TEAMModelOS/ClientApp/src/view/jyzx/offline.vue


Деякі файли не було показано, через те що забагато файлів було змінено