瀏覽代碼

Merge remote-tracking branch 'origin/TPE/develop5.0' into TPE/develop5.0

osbert 4 年之前
父節點
當前提交
c89e55a0fe
共有 74 個文件被更改,包括 1708 次插入1008 次删除
  1. 89 1
      TEAMModelFunction/ActivityHttpTrigger.cs
  2. 47 35
      TEAMModelFunction/MonitorCosmosDB.cs
  3. 133 0
      TEAMModelFunction/NoticeServiceBus.cs
  4. 158 30
      TEAMModelFunction/TriggerExam.cs
  5. 1 1
      TEAMModelFunction/TriggerStuActivity.cs
  6. 23 0
      TEAMModelFunction/TriggerSurvey.cs
  7. 23 0
      TEAMModelFunction/TriggerVote.cs
  8. 2 2
      TEAMModelGrpc/Startup.cs
  9. 0 20
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/AzureJsonRequest.cs
  10. 0 16
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/BaseJosnRequest.cs
  11. 0 14
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/JosnRequest.cs
  12. 0 15
      TEAMModelOS.SDK/Extension/DataResult/JsonRequest/PaginationRequest.cs
  13. 0 13
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/BaseResponse.cs
  14. 0 19
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/DataJsonResponse.cs
  15. 0 14
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/EmptyJosnResponse.cs
  16. 0 19
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorJosnResponse.cs
  17. 0 15
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorModel.cs
  18. 0 16
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/JsonRPCResult.cs
  19. 0 20
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJosnResponse.cs
  20. 0 15
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJsonResult.cs
  21. 0 175
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ResponseBuilder.cs
  22. 0 20
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJosnResponse.cs
  23. 0 18
      TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJsonResult.cs
  24. 0 13
      TEAMModelOS.SDK/Extension/DataResult/PageToken/AzurePagination.cs
  25. 0 17
      TEAMModelOS.SDK/Extension/DataResult/PageToken/AzureTableToken.cs
  26. 0 31
      TEAMModelOS.SDK/Extension/DataResult/PageToken/Pagination.cs
  27. 0 13
      TEAMModelOS.SDK/Extension/DataResult/RequestData/AzureTokenRequest.cs
  28. 0 12
      TEAMModelOS.SDK/Extension/DataResult/RequestData/BaseRequest.cs
  29. 0 10
      TEAMModelOS.SDK/Extension/DataResult/RequestData/PaginationRequest.cs
  30. 0 38
      TEAMModelOS.SDK/Extension/Language/Implements/LanguageService.cs
  31. 0 12
      TEAMModelOS.SDK/Extension/Language/Interfaces/ILanguageService.cs
  32. 0 18
      TEAMModelOS.SDK/Extension/Language/LanguageExtension.cs
  33. 0 10
      TEAMModelOS.SDK/Extension/Language/Model/SmsCountryCode.cs
  34. 6 0
      TEAMModelOS.SDK/Models/Cosmos/Common/ExamClassResult.cs
  35. 146 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Notice.cs
  36. 1 0
      TEAMModelOS.SDK/Models/Cosmos/Common/StuList.cs
  37. 1 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  38. 26 19
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseBar.vue
  39. 85 67
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScoreRateBar.vue
  40. 2 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  41. 5 1
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue
  42. 17 25
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  43. 0 8
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue
  44. 12 3
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue
  45. 3 6
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  46. 20 14
      TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue
  47. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue
  48. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue
  49. 6 3
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue
  50. 12 12
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue
  51. 6 9
      TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue
  52. 7 2
      TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue
  53. 6 7
      TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue
  54. 6 3
      TEAMModelOS/ClientApp/src/view/settings/Index.vue
  55. 152 0
      TEAMModelOS/ClientApp/src/view/settings/OpenMgmt.less
  56. 318 0
      TEAMModelOS/ClientApp/src/view/settings/OpenMgmt.vue
  57. 0 6
      TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue
  58. 39 37
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue
  59. 5 8
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue
  60. 49 10
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue
  61. 2 2
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.vue
  62. 163 97
      TEAMModelOS/Controllers/Analysis/AchievementController.cs
  63. 22 6
      TEAMModelOS/Controllers/Analysis/AnalysisController.cs
  64. 11 1
      TEAMModelOS/Controllers/Analysis/ClassAys.cs
  65. 23 0
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  66. 6 2
      TEAMModelOS/Controllers/Common/ExamController.cs
  67. 1 1
      TEAMModelOS/Controllers/Common/TriggerStuActivity.cs
  68. 1 0
      TEAMModelOS/Controllers/Core/ImportController.cs
  69. 1 1
      TEAMModelOS/Controllers/School/CourseController.cs
  70. 1 1
      TEAMModelOS/Controllers/School/SchoolTeacherController.cs
  71. 64 0
      TEAMModelOS/Controllers/XTest/TestController.cs
  72. 1 1
      TEAMModelOS/Startup.cs
  73. 3 0
      TEAMModelOS/appsettings.Development.json
  74. 1 1
      TEAMModelOS/appsettings.json

+ 89 - 1
TEAMModelFunction/ActivityHttpTrigger.cs

@@ -35,6 +35,83 @@ namespace TEAMModelFunction
             _azureStorage = azureStorage;
             _azureStorage = azureStorage;
             _azureRedis = azureRedis;
             _azureRedis = azureRedis;
         }
         }
+
+        /// <summary>
+        /// 修复已存在的课程且未初始化学生课程列表的业务。
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
+        [FunctionName("fix-stu-course")]
+        public async Task<IActionResult> StuCourse([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
+        {
+            log.LogInformation("fix-stu-course...");
+            string originCode = await new StreamReader(req.Body).ReadToEndAsync();
+            List<Course> courses = new List<Course>();
+            var client = _azureCosmos.GetCosmosClient();
+            var query = $"select  *  from c ";
+            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
+            {
+                courses.Add(item);
+            }
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
+            {
+                courses.Add(item);
+            }
+            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
+            foreach (var course in courses)
+            {
+                if (course.schedule.IsNotEmpty())
+                {
+                    foreach (var sc in course.schedule)
+                    {
+                        if (!string.IsNullOrEmpty(sc.stulist))
+                        {
+                            (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, new List<string>() { sc.stulist }, course.school);
+                            foreach (var addStu in studentss)
+                            {
+                                var stuCourse = new StuCourse
+                                {
+                                    id = course.id,
+                                    scode = course.code,
+                                    name = course.name,
+                                    code = $"StuCourse-{course.school}-{addStu.id}",
+                                    scope = course.scope,
+                                    school = course.school,
+                                    creatorId = course.creatorId,
+                                    pk = "StuCourse"
+                                };
+                                await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stuCourse, new PartitionKey(stuCourse.code));
+                            }
+                            foreach (var addTmd in tmdids)
+                            {
+                                var tmdCourse = new StuCourse
+                                {
+                                    id = course.id,
+                                    scode = course.code,
+                                    name = course.name,
+                                    code = $"StuCourse-{addTmd}",
+                                    scope = course.scope,
+                                    //school = courseChange.school,
+                                    creatorId = course.creatorId,
+                                    pk = "StuCourse"
+                                };
+                                await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(tmdCourse, new PartitionKey(tmdCourse.code));
+                            }
+                        }
+                    }
+                }
+            }
+            return new OkObjectResult(new { });
+        }
+        /// <summary>
+        /// 设置评测未初始化学生列表的
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
         [FunctionName("fix-exam-activity")]
         [FunctionName("fix-exam-activity")]
         public   async Task<IActionResult> ExamActivity([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,ILogger log)
         public   async Task<IActionResult> ExamActivity([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,ILogger log)
         {
         {
@@ -121,7 +198,12 @@ namespace TEAMModelFunction
             }
             }
             return new OkObjectResult(new { });
             return new OkObjectResult(new { });
         }
         }
-
+        /// <summary>
+        /// 设置投票未初始化学生列表的业务
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
         [FunctionName("fix-vote-activity")]
         [FunctionName("fix-vote-activity")]
         public async Task<IActionResult> VoteActivity(
         public async Task<IActionResult> VoteActivity(
             [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
             [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
@@ -208,6 +290,12 @@ namespace TEAMModelFunction
             }
             }
             return new OkObjectResult(new { });
             return new OkObjectResult(new { });
         }
         }
+        /// <summary>
+        /// 设置问卷调查未初始化学生列表的业务
+        /// </summary>
+        /// <param name="req"></param>
+        /// <param name="log"></param>
+        /// <returns></returns>
         [FunctionName("fix-survey-activity")]
         [FunctionName("fix-survey-activity")]
         public async Task<IActionResult> SurveyActivity(
         public async Task<IActionResult> SurveyActivity(
             [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
             [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,

+ 47 - 35
TEAMModelFunction/MonitorCosmosDB.cs

@@ -48,43 +48,55 @@ namespace TEAMModelFunction
                     string pk = input.GetPropertyValue<string>("pk");
                     string pk = input.GetPropertyValue<string>("pk");
                     if (!string.IsNullOrWhiteSpace(pk))
                     if (!string.IsNullOrWhiteSpace(pk))
                     {
                     {
-                        int ttl = input.GetPropertyValue<int>("ttl");
-                        long stime = input.GetPropertyValue<long>("startTime");
-                        long etime = input.GetPropertyValue<long>("endTime");
-                        string school = input.GetPropertyValue<string>("school");
-                        string code = input.GetPropertyValue<string>("code");
-                        string creatorId = input.GetPropertyValue<string>("creatorId");
-                        string progress = input.GetPropertyValue<string>("progress");
-                        string scope = input.GetPropertyValue<string>("scope");
-                        string name = input.GetPropertyValue<string>("name");
-                        int? status = input.GetPropertyValue<int?>("status");
-                        var data = new TriggerData {
-                            stime = stime,
-                            etime = etime,
-                            school = school,
-                            code = code,
-                            creatorId = creatorId,
-                            progress = progress,
-                            scope = scope,
-                            ttl = ttl,
-                            id = input.Id,
-                            status = status
-                        };
-                        await _dingDing.SendBotMsg($"CosmosDBTrigger,{pk}触发变更\n{data.ToJsonString()}"  ,
-                                        GroupNames.成都开发測試群組);
-                        switch (pk)
-                        {
-                            case "Exam":
-                                TriggerExam.Trigger(_azureCosmos, _serviceBus, _azureStorage, _dingDing, client,input,code,stime,etime,school);
-                                break;
-                            case "Vote":
-                                TriggerVote.Trigger( _serviceBus, _azureStorage, _dingDing, client, input, data, _azureRedis);
-                                break;
-                            case "Survey":
-                                TriggerSurvey.Trigger( _serviceBus, _azureStorage, _dingDing, client, input, data, _azureRedis);
-                                break;
+                        if (pk.Equals("Receiver", StringComparison.OrdinalIgnoreCase))
+                        { 
+                            ///通知接收者的变更
+                            return;
+                           
+                        }
+                        else {
+                            ///活动类型的变更
+                            int ttl = input.GetPropertyValue<int>("ttl");
+                            long stime = input.GetPropertyValue<long>("startTime");
+                            long etime = input.GetPropertyValue<long>("endTime");
+                            string school = input.GetPropertyValue<string>("school");
+                            string code = input.GetPropertyValue<string>("code");
+                            string creatorId = input.GetPropertyValue<string>("creatorId");
+                            string progress = input.GetPropertyValue<string>("progress");
+                            string scope = input.GetPropertyValue<string>("scope");
+                            string name = input.GetPropertyValue<string>("name");
+                            int? status = input.GetPropertyValue<int?>("status");
+                            var data = new TriggerData
+                            {
+                                stime = stime,
+                                etime = etime,
+                                school = school,
+                                code = code,
+                                creatorId = creatorId,
+                                progress = progress,
+                                scope = scope,
+                                ttl = ttl,
+                                id = input.Id,
+                                status = status
+                            };
+                            await _dingDing.SendBotMsg($"CosmosDBTrigger,{pk}触发变更\n{data.ToJsonString()}",
+                                            GroupNames.成都开发測試群組);
+                            switch (pk)
+                            {
+                                case "Exam":
+                                    TriggerExam.Trigger(_azureCosmos, _serviceBus, _azureStorage, _dingDing, client, input, code, stime, etime, school);
+                                    break;
+                                case "Vote":
+                                    TriggerVote.Trigger(_serviceBus, _azureStorage, _dingDing, client, input, data, _azureRedis);
+                                    break;
+                                case "Survey":
+                                    TriggerSurvey.Trigger(_serviceBus, _azureStorage, _dingDing, client, input, data, _azureRedis);
+                                    break;
+
+                            }
 
 
                         }
                         }
+                        
                     }
                     }
                 }
                 }
             }
             }

+ 133 - 0
TEAMModelFunction/NoticeServiceBus.cs

@@ -0,0 +1,133 @@
+using Azure.Messaging.ServiceBus;
+using Microsoft.Azure.WebJobs;
+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.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Models;
+
+namespace TEAMModelFunction
+{
+   
+    public class NoticeServiceBus
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly AzureServiceBusFactory _serviceBus;
+        private readonly DingDing _dingDing;
+        public NoticeServiceBus(AzureCosmosFactory azureCosmos, DingDing dingDing,AzureStorageFactory azureStorage, AzureServiceBusFactory serviceBus)
+        {
+            _azureStorage = azureStorage;
+            _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+            _serviceBus = serviceBus;
+        }
+        [FunctionName("Notice")]
+        public async  Task Notice([ServiceBusTrigger("active-task", "notice", Connection = "Azure:ServiceBus:ConnectionString")] string msg) {
+            var client = _azureCosmos.GetCosmosClient();
+            try {
+                await _dingDing.SendBotMsg($"NoticeServiceBus-Notice:\n发起通知{msg}", GroupNames.成都开发測試群組);
+                List<Task<string>> tasks = new List<Task<string>>();
+                List<Task> sessionTasks = new List<Task>();
+                var jsonMsg = JsonDocument.Parse(msg);
+                Notice notice = msg.ToObject<Notice>();
+                var blobcntr = "";
+                if (notice.scope.Equals("school"))
+                {
+                    blobcntr = notice.school;
+                }
+                else {
+                    blobcntr = notice.creatorId;
+                }
+                var urlNotice = $"{notice.sid}.json";
+                var blobNotice = new { 
+                    notice.sid, 
+                    notice.scode,
+                    notice.spk,
+                    notice.scope,
+                    notice.school,
+                    notice.type,
+                    notice.level,
+                    notice.data,
+                    notice.stime,
+                    notice.etime,
+                    notice.creatorId
+                };
+                tasks.Add(_azureStorage.UploadFileByContainer(blobcntr, blobNotice.ToJsonString(), "notice", urlNotice));
+                var urlReceiver = $"{notice.sid}_receiver.json";
+                var blobReceiver = new
+                {
+                    notice.stuids,
+                    notice.tmdids
+                };
+                tasks.Add(_azureStorage.UploadFileByContainer(blobcntr, blobReceiver.ToJsonString(), "notice", urlReceiver));
+                long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                // "ttl":2592000,不能超过30天(2592000),一天(3600),一周(25200)
+                long ttl = notice.etime - now;
+                long day30 = 2592000L * 1000;
+                if (ttl > day30) {
+                    ttl = day30;
+                }
+                if (notice.stuids.IsNotEmpty()) {
+                    //  List<Receiver> receivers = new List<Receiver>();
+                    foreach (var stu in notice.stuids) {
+                        Receiver receiver = new Receiver
+                        {
+                            id = notice.sid,
+                            pk = "Receiver",
+                            status = 0,
+                            school = stu.schoolId,
+                            scope = "school",
+                            code = $"Receiver-{stu.schoolId}-{stu.id}",
+                            ttl = (int)ttl,
+                            ctime= now,
+                            urlNotice=$"notice/{urlNotice}"
+                        };
+                        await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync<Receiver>(receiver,new Azure.Cosmos.PartitionKey(receiver.code));
+                        //  /student/{stuid}/receive/{notice.sid}.json
+                        //存放通知到学生容器空间
+                        var url = $"{stu.id}/receive/{notice.sid}.json";
+                        tasks.Add(_azureStorage.UploadFileByContainer(blobcntr, receiver.ToJsonString(), "student", url));
+                        var messageBlob = new ServiceBusMessage(notice.ToJsonString()) { SessionId =$"{stu.schoolId}-{stu.id}"};
+                        messageBlob.ApplicationProperties.Add("name", "Receiver");
+                        sessionTasks.Add(_serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageBlob));
+                    }
+                }
+                if (notice.tmdids.IsNotEmpty())
+                {
+                    foreach (var tmdid in notice.tmdids)
+                    {
+                        Receiver receiver = new Receiver
+                        {
+                            id = notice.sid,
+                            pk = "Receiver",
+                            status = 0,
+                            //school = stu.schoolId,
+                            scope = "school",
+                            code = $"Receiver-{tmdid}",
+                            ttl = (int)ttl,
+                            ctime = now,
+                            urlNotice = $"notice/{urlNotice}"
+                        };
+                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Receiver>(receiver, new Azure.Cosmos.PartitionKey(receiver.code));
+                        //  /student/{stuid}/receive/{notice.sid}.json
+                        //存放通知到学生容器空间
+                        var url = $"{notice.sid}.json";
+                        tasks.Add(_azureStorage.UploadFileByContainer(blobcntr, receiver.ToJsonString(), "receive", url));
+                        var messageBlob = new ServiceBusMessage(notice.ToJsonString()) { SessionId = $"{tmdid}" };
+                        messageBlob.ApplicationProperties.Add("name", "Receiver");
+                        sessionTasks.Add(_serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageBlob));
+                    }
+                }
+                await Task.WhenAll(sessionTasks);
+                await Task.WhenAll(tasks);
+            } catch (Exception ex) {
+                 await _dingDing.SendBotMsg($"NoticeServiceBus-Notice\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
+            }
+        }
+    }
+}

+ 158 - 30
TEAMModelFunction/TriggerExam.cs

@@ -178,6 +178,29 @@ namespace TEAMModelFunction
                         });
                         });
                     }
                     }
                     await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
                     await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
+                    //向学生或醍摩豆账号发起通知
+                    #region
+                    Notice notice = new Notice()
+                    {
+                        sid = info.id,
+                        scode = info.code,
+                        spk = info.pk,
+                        scope = info.scope,
+                        school = info.school,
+                        stime = info.startTime,
+                        etime = info.endTime,
+                        creatorId = info.creatorId,
+                        stuids = studentss,
+                        tmdids = tmdids,
+                        type = "exam-join",//评测参加通知
+                        level = 1,
+                        data = new { }.ToJsonString()
+
+                    };
+                    var messageBlob = new ServiceBusMessage(notice.ToJsonString());
+                    messageBlob.ApplicationProperties.Add("name", "Notice");
+                    await _serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageBlob);
+                    #endregion
                     if (examClassResults.Count == 0)
                     if (examClassResults.Count == 0)
                     {
                     {
                         foreach (string cla in info.classes)
                         foreach (string cla in info.classes)
@@ -447,10 +470,57 @@ namespace TEAMModelFunction
                 //存放高分组学生ID
                 //存放高分组学生ID
                 List<string> phId = new List<string>();
                 List<string> phId = new List<string>();
                 List<string> plId = new List<string>();
                 List<string> plId = new List<string>();
-                int phcount = 0;
-                int plcount = 0;
                 List<List<List<string>>> opth = new List<List<List<string>>>();
                 List<List<List<string>>> opth = new List<List<List<string>>>();
                 List<List<List<string>>> optl = new List<List<List<string>>>();
                 List<List<List<string>>> optl = new List<List<List<string>>>();
+                await knowledgeCount(info, subject, _dingDing, no, classResults, rhwCount, rhw, rhlCount, rhl, _azureCosmos);
+                await fieldCount(info, subject, _dingDing, no, classResults, rhwCount, rhw, rhlCount, rhl, _azureCosmos);
+                int PHCount = 0;
+                int PLCount = 0;
+                foreach (ExamClassResult classResult in classResults)
+                {
+                    if (classResult.subjectId.Equals(subject.id))
+                    {
+                        foreach (string id in classResult.studentIds)
+                        {
+                            int index = classResult.studentIds.IndexOf(id);
+                            if (classResult.studentScores[index].Sum() >= rhw && PHCount < rhwCount)
+                            {
+                                if (classResult.ans.Count > 0)
+                                {
+                                    opth.Add(classResult.ans[index]);
+                                    PHCount++;
+                                    continue;
+                                }
+
+                            }
+                            if (classResult.studentScores[index].Sum() <= rhl && PLCount < (scores.Count - rhlCount))
+                            {
+                                if (classResult.ans.Count > 0)
+                                {
+                                    optl.Add(classResult.ans[index]);
+                                    PLCount++;
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                }
+                result.phc = getMore(info, no, opth);
+                result.plc = getMore(info, no, optl);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+            }
+        }
+
+        public static async Task knowledgeCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, List<ExamClassResult> classResults,
+            double rhwCount, double rhw, double rhlCount, double rhl, AzureCosmosFactory _azureCosmos)
+        {
+            try
+            {
+                int phcount = 0;
+                int plcount = 0;
                 //存放并去重知识点
                 //存放并去重知识点
                 HashSet<string> kname = new HashSet<string>();
                 HashSet<string> kname = new HashSet<string>();
                 info.papers[no].knowledge.ForEach(kno =>
                 info.papers[no].knowledge.ForEach(kno =>
@@ -475,7 +545,8 @@ namespace TEAMModelFunction
 
 
                 foreach (ExamClassResult classResult in classResults)
                 foreach (ExamClassResult classResult in classResults)
                 {
                 {
-                    if (classResult.subjectId.Equals(subject.id)) {
+                    if (classResult.subjectId.Equals(subject.id))
+                    {
                         //List<int> phc = new List<int>();
                         //List<int> phc = new List<int>();
                         List<int> ph = new List<int>();
                         List<int> ph = new List<int>();
                         List<int> pl = new List<int>();
                         List<int> pl = new List<int>();
@@ -511,7 +582,7 @@ namespace TEAMModelFunction
                                                 phcount++;
                                                 phcount++;
                                                 continue;
                                                 continue;
                                             }
                                             }
-                                            if (classResult.studentScores[index].Sum() <= rhl && plcount < (scores.Count - rhlCount))
+                                            if (classResult.studentScores[index].Sum() <= rhl && plcount < (info.stuCount - rhlCount))
                                             {
                                             {
                                                 if (classResult.studentScores[index][n] == 0)
                                                 if (classResult.studentScores[index][n] == 0)
                                                 {
                                                 {
@@ -533,56 +604,113 @@ namespace TEAMModelFunction
                             ph.Add(phCount);
                             ph.Add(phCount);
                             pl.Add(plCount);
                             pl.Add(plCount);
                             double per = classResult.studentIds.Count > 0 ? Math.Round(score / classResult.studentIds.Count, 2) : 0;
                             double per = classResult.studentIds.Count > 0 ? Math.Round(score / classResult.studentIds.Count, 2) : 0;
-                            persent.Add(per / allScore);
+                            persent.Add(allScore > 0 ? per / allScore : 0);
                         }
                         }
                         classResult.phc = ph;
                         classResult.phc = ph;
                         classResult.plc = pl;
                         classResult.plc = pl;
                         classResult.pc = pc;
                         classResult.pc = pc;
                         classResult.krate = persent;
                         classResult.krate = persent;
-                    }                    
+                    }
                     await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                     await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                 }
                 }
-                //
-                int PHCount = 0;
-                int PLCount = 0;
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"评测知识点结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+            }
+        }
+
+        public static async Task fieldCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, List<ExamClassResult> classResults,
+            double rhwCount, double rhw, double rhlCount, double rhl, AzureCosmosFactory _azureCosmos)
+        {
+            try
+            {
+                int phcount = 0;
+                int plcount = 0;
+                //存放并去重知识点
+                List<int> knowledgeName = new List<int>();
+                knowledgeName.Add(1);
+                knowledgeName.Add(2);
+                knowledgeName.Add(3);
+                knowledgeName.Add(4);
+                knowledgeName.Add(5);
+                knowledgeName.Add(6);
                 foreach (ExamClassResult classResult in classResults)
                 foreach (ExamClassResult classResult in classResults)
                 {
                 {
                     if (classResult.subjectId.Equals(subject.id))
                     if (classResult.subjectId.Equals(subject.id))
                     {
                     {
-                        foreach (string id in classResult.studentIds)
+                        //List<int> phc = new List<int>();
+                        List<int> ph = new List<int>();
+                        List<int> pl = new List<int>();
+                        List<int> pc = new List<int>();
+                        List<double> persent = new List<double>();
+                        for (int i = 0; i < knowledgeName.Count; i++)
                         {
                         {
-                            int index = classResult.studentIds.IndexOf(id);
-                            if (classResult.studentScores[index].Sum() >= rhw && PHCount < rhwCount)
-                            {
-                                if (classResult.ans.Count > 0)
-                                {
-                                    opth.Add(classResult.ans[index]);
-                                    PHCount++;
-                                    continue;
-                                }
-
-                            }
-                            if (classResult.studentScores[index].Sum() <= rhl && PLCount < (scores.Count - rhlCount))
+                            //初始化单个知识点得分
+                            double score = 0;
+                            double allScore = 0;
+                            int n = 0;
+                            int phCount = 0;
+                            int plCount = 0;
+                            int pCount = 0;
+                            foreach (int str in info.papers[no].field)
                             {
                             {
-                                if (classResult.ans.Count > 0)
+                                if (str == knowledgeName[i])
                                 {
                                 {
-                                    optl.Add(classResult.ans[index]);
-                                    PLCount++;
-                                    continue;
+                                    var itemPersent = 1;
+                                    allScore += info.papers[no].point[n] * itemPersent;
+                                    foreach (string id in classResult.studentIds)
+                                    {
+                                        int index = classResult.studentIds.IndexOf(id);
+                                        if (classResult.studentScores[index].Count > 0)
+                                        {
+                                            score += classResult.studentScores[index][n];
+                                            if (classResult.studentScores[index].Sum() >= rhw && phcount < rhwCount)
+                                            {
+                                                if (classResult.studentScores[index][n] == 0)
+                                                {
+                                                    phCount++;
+                                                }
+                                                phcount++;
+                                                continue;
+                                            }
+                                            if (classResult.studentScores[index].Sum() <= rhl && plcount < (info.stuCount - rhlCount))
+                                            {
+                                                if (classResult.studentScores[index][n] == 0)
+                                                {
+                                                    plCount++;
+                                                }
+                                                plcount++;
+                                                continue;
+                                            }
+                                            if (classResult.studentScores[index][n] == 0)
+                                            {
+                                                pCount++;
+                                            }
+                                        }
+                                    }
                                 }
                                 }
+                                n++;
                             }
                             }
+                            pc.Add(pCount);
+                            ph.Add(phCount);
+                            pl.Add(plCount);
+                            double per = classResult.studentIds.Count > 0 ? Math.Round(score / classResult.studentIds.Count, 2) : 0;
+                            persent.Add(allScore > 0 ? per / allScore : 0);
                         }
                         }
+                        classResult.fphc = ph;
+                        classResult.fplc = pl;
+                        classResult.fpc = pc;
+                        classResult.frate = persent;
                     }
                     }
+                    await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                 }
                 }
-                result.phc = getMore(info, no, opth);
-                result.plc = getMore(info, no, optl);
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
-                await _dingDing.SendBotMsg($"评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"评测认知层次结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
             }
             }
         }
         }
-
         //处理选题计数
         //处理选题计数
         public static List<Dictionary<string, int>> getMore(ExamInfo info, int no, List<List<List<string>>> list)
         public static List<Dictionary<string, int>> getMore(ExamInfo info, int no, List<List<List<string>>> list)
         {
         {

+ 1 - 1
TEAMModelFunction/TriggerStuActivity.cs

@@ -87,7 +87,7 @@ namespace TEAMModelFunction
                 }
                 }
             });
             });
             students.ForEach(x => {
             students.ForEach(x => {
-                studentss.Add(new Students { id = x.id, code = x.code });
+                studentss.Add(new Students { id = x.id, code = x.code,schoolId=x.schoolId });
             });
             });
             return (tmdids,studentss);
             return (tmdids,studentss);
         }
         }

+ 23 - 0
TEAMModelFunction/TriggerSurvey.cs

@@ -128,6 +128,29 @@ namespace TEAMModelFunction
                             });
                             });
                         }
                         }
                         await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
                         await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
+                        //向学生或醍摩豆账号发起通知
+                        #region
+                        Notice notice = new Notice()
+                        {
+                            sid = survey.id,
+                            scode = survey.code,
+                            spk = survey.pk,
+                            scope = survey.scope,
+                            school = survey.school,
+                            stime = survey.startTime,
+                            etime = survey.endTime,
+                            creatorId = survey.creatorId,
+                            stuids = students,
+                            tmdids = tmdids,
+                            type = "survey-join",//问卷参加参加通知
+                            level = 1,
+                            data = new { }.ToJsonString()
+
+                        };
+                        var messageBlob = new ServiceBusMessage(notice.ToJsonString());
+                        messageBlob.ApplicationProperties.Add("name", "Notice");
+                        await _serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageBlob);
+                        #endregion
                         await _dingDing.SendBotMsg($"问卷调查{tdata.id}写入完成!", GroupNames.成都开发測試群組);
                         await _dingDing.SendBotMsg($"问卷调查{tdata.id}写入完成!", GroupNames.成都开发測試群組);
                         var messageSurveyEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                         var messageSurveyEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                         messageSurveyEnd.ApplicationProperties.Add("name", "Survey");
                         messageSurveyEnd.ApplicationProperties.Add("name", "Survey");

+ 23 - 0
TEAMModelFunction/TriggerVote.cs

@@ -137,6 +137,29 @@ namespace TEAMModelFunction
                             });
                             });
                         }
                         }
                         await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
                         await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
+                        //向学生或醍摩豆账号发起通知
+                        #region
+                        Notice notice =   new Notice()
+                        {
+                            sid=vote.id,
+                            scode=vote.code,
+                            spk=vote.pk,
+                            scope=vote.scope,
+                            school=vote.school,
+                            stime=vote.startTime,
+                            etime=vote.endTime,
+                            creatorId=vote.creatorId,
+                            stuids=students,
+                            tmdids=tmdids,
+                            type="vote-join",//投票参加通知
+                            level=1,
+                            data=new { }.ToJsonString()
+
+                        };
+                        var messageBlob = new ServiceBusMessage(notice.ToJsonString());
+                        messageBlob.ApplicationProperties.Add("name", "Notice");
+                        await _serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageBlob);
+                        #endregion
                         var messageVoteEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                         var messageVoteEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString());
                         messageVoteEnd.ApplicationProperties.Add("name", "Vote");
                         messageVoteEnd.ApplicationProperties.Add("name", "Vote");
                         if (voteRecords.Count > 0)
                         if (voteRecords.Count > 0)

+ 2 - 2
TEAMModelGrpc/Startup.cs

@@ -77,8 +77,8 @@ namespace TEAMModelGrpc
             //    .AddCosmosSerializer(new SystemTextJsonCosmosSerializer(new JsonSerializerOptions() { IgnoreNullValues = true }));
             //    .AddCosmosSerializer(new SystemTextJsonCosmosSerializer(new JsonSerializerOptions() { IgnoreNullValues = true }));
  
  
             //注入CSRedis
             //注入CSRedis
-            var csredis = new CSRedis.CSRedisClient(_conf.GetSection("Azure:Redis:ConnectionString").Get<string>());
-            RedisHelper.Initialization(csredis);
+           // var csredis = new CSRedis.CSRedisClient(_conf.GetSection("Azure:Redis:ConnectionString").Get<string>());
+           // RedisHelper.Initialization(csredis);
 
 
             //全局扫描基于IBusinessService接口的实现类
             //全局扫描基于IBusinessService接口的实现类
             //services.Scan(scan => scan.FromApplicationDependencies()
             //services.Scan(scan => scan.FromApplicationDependencies()

+ 0 - 20
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/AzureJsonRequest.cs

@@ -1,20 +0,0 @@
-using TEAMModelOS.SDK;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    /// <summary>
-    /// 
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    public class AzureJsonRequest<T> : BaseJosnRequest
-    {
-
-        public AzureJsonRequest (){
-            @params = new AzureTokenRequest<T>();
-        }
-        public AzureTokenRequest<T> @params { get; set; }
-    }
-}

+ 0 - 16
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/BaseJosnRequest.cs

@@ -1,16 +0,0 @@
-
-using System;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public abstract class BaseJosnRequest
-    {
-      //  public long requestTime { get; set; } = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000;
-       // public string jsonrpc { get; set; } = "2.0";
-        public string method { get; set; }
-    //    public int id { get; set; } = 1;
-      //  public int timeOffset { get; set; }
-        public string lang { get; set; } = "zh-CN";
-    }
-}

+ 0 - 14
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/JosnRequest.cs

@@ -1,14 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class JosnRequest<T>:BaseJosnRequest
-    {
-
-        public T @params { get; set; }
-    }
-}

+ 0 - 15
TEAMModelOS.SDK/Extension/DataResult/JsonRequest/PaginationRequest.cs

@@ -1,15 +0,0 @@
-
-
-using TEAMModelOS.SDK;
-
-namespace TEAMModelOS.SDK
-{
-    public  class PaginationJsonRequest<T> : BaseJosnRequest
-    {
-        public PaginationJsonRequest()
-        {
-            @params = new PaginationRequest<T>();
-        }
-        public PaginationRequest<T> @params { get; set; }
-    }
-}

+ 0 - 13
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/BaseResponse.cs

@@ -1,13 +0,0 @@
-
-using Microsoft.VisualBasic;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class BaseResponse 
-    {
-      //  public string jsonrpc { get; set; } = "2.0";
-       // public double id { get; set; } = 1;
-       
-    }
-}

+ 0 - 19
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/DataJsonResponse.cs

@@ -1,19 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class DataJsonResponse<T> : BaseResponse
-    {
-		public DataJsonResponse() { 
-		  result=  new JsonRPCResult<T>();
-		}
-        public Dictionary<string, object> error { get; set; } = null;
-        public   JsonRPCResult<T> result { get; set; }
-        public int code { get; set; } = 0;
-        public string message { get; set; } = "Success";
-    }
-}

+ 0 - 14
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/EmptyJosnResponse.cs

@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    public class EmptyJosnResponse :BaseResponse
-    {
-        public object result { get; set; } = null;
-        public Dictionary<string,object> error { get; set; } = null;
-        public int code { get; set; } = 1;
-        public string message { get; set; } = "Empty";
-    }
-}

+ 0 - 19
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorJosnResponse.cs

@@ -1,19 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-
-    public class ErrorJosnResponse : BaseResponse
-    {
-        public ErrorJosnResponse()
-        {
-            error = new Dictionary<string, object>();
-        }
-        public object result { get; set; } = null;
-        public Dictionary<string, object> error { get; set; }
-        public int code { get; set; } = 0;
-        public string message { get; set; } = "Error";
-    }
-}

+ 0 - 15
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ErrorModel.cs

@@ -1,15 +0,0 @@
-
-
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK
-{
-    
-   
-
-    public class ErrorModel {
-        public int code { get; set; }
-        public string message { get; set; }
-        public Dictionary<string, object> data { get; set; } = null;
-    }
-}

+ 0 - 16
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/JsonRPCResult.cs

@@ -1,16 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class JsonRPCResult<T>
-    {
-        public Dictionary<string, object> extend { get; set; } = null;
-     //   public long responseTime { get; set; } = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000;
-        public T data { get; set; }
-       
-    }
-}

+ 0 - 20
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJosnResponse.cs

@@ -1,20 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class PageJosnResponse<T> : BaseResponse
-    {
-		public PageJosnResponse()
-		{
-			result = new PageJsonResult<T>();
-		}
-		public   PageJsonResult<T> result { get; set; }
-		public Dictionary<string, object> error { get; set; } = null;
-		public int code { get; set; } = 0;
-		public string message { get; set; } = "Success";
-	}
-}

+ 0 - 15
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/PageJsonResult.cs

@@ -1,15 +0,0 @@
-using TEAMModelOS.SDK;
-
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class PageJsonResult<T> : JsonRPCResult<T>
-    {
-        public Pagination page { get; set; }
-
-        public PageJsonResult()
-        {
-        }
-    }
-}

+ 0 - 175
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/ResponseBuilder.cs

@@ -1,175 +0,0 @@
-using TEAMModelOS.SDK;
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public  class ResponseBuilder
-    {
-        private string message="Success";
-        private object data;
-        private long total;
-        private int currPage;
-        private int pageSize;
-        private int totalPage;
-        private Dictionary<string, object> extend;
-        private Pagination page;
-        private AzureTableToken token;
-        private ErrorModel error =null;
-        
-        public ResponseBuilder()
-        {
-        }
-        public ResponseBuilder Success()
-        {
-            error = null;
-            return this;
-        }
-
-        public ResponseBuilder Success(String message)
-        {
-            this.message = message;
-            return this;
-        }
-        public static ResponseBuilder custom()
-        {
-            return new ResponseBuilder();
-        }
-
-        public ResponseBuilder Data(object data)
-        {
-            this.data = data;
-            return this;
-        }
-		public ResponseBuilder Error( int code, string message)
-		{
-			
-			this.error = new ErrorModel { code=code, message=message, data = null };
-			return this;
-		}
-        public ResponseBuilder Error(int code, Dictionary<string,object> errorData)
-        {
-           
-            this.error = new ErrorModel { code = code, message = message ,data= errorData };
-            return this;
-        }
-        public ResponseBuilder Error( int code)
-		{
-
-            this.error = new ErrorModel { code = code, message = "Error", data = null };
-            return this;
-		}
-        public ResponseBuilder Error(int code, string message, Dictionary<string, object> errorData)
-        {
-
-            this.error = new ErrorModel { code = code, message = message, data = errorData };
-            return this;
-        }
-
-        public ResponseBuilder Extend(Dictionary<String, object> extend)
-        {
-            this.extend = extend;
-            return this;
-        }
-        public ResponseBuilder Token(AzureTableToken token)
-        {
-            this.token = token;
-            return this;
-        }
-        public ResponseBuilder Page(Pagination page)
-        {
-            this.pageSize = page.pageSize;
-            this.currPage = page.currPage;
-            this.total = page.total;
-            this.page = page;
-            this.totalPage = (int)Math.Ceiling((double)this.total / (double)this.pageSize);
-            return this;
-        }
-        public ResponseBuilder totalCount(int totalCount)
-        {
-            this.total = totalCount;
-            return this;
-        }
-
-        public ResponseBuilder CurrPage(int currPage)
-        {
-            this.currPage = currPage;
-            return this;
-        }
-
-        public ResponseBuilder PageSize(int pageSize)
-        {
-            this.pageSize = pageSize;
-            return this;
-        }
-
-        public ResponseBuilder TotalPage(int totalPage)
-        {
-            this.totalPage = totalPage;
-            return this;
-        }
-        public BaseResponse build()
-        {
-
-            object baseResponse = null;
-            if (error != null) {
-                ErrorJosnResponse errorJosnRPCResponse = new ErrorJosnResponse();
-                errorJosnRPCResponse.error = error.data;
-                errorJosnRPCResponse.code = error.code;
-                errorJosnRPCResponse.message = error.message;
-                return errorJosnRPCResponse;
-            }
-            if (this.total > 0 && this.pageSize > 0)
-            {
-                this.totalPage = (int)Math.Ceiling((double)this.total / (double)this.pageSize);
-            }
-            if (null != this.data && this.token != null)
-            {
-                TokenJosnResponse<object> response = new TokenJosnResponse<object>();
-                response.result.data = this.data;
-                response.result.extend = this.extend;
-                response.result.azureToken = this.token;
-                response.code = 0;
-                response.message = message;
-
-                baseResponse = response;
-            }
-            else if (null != this.data && this.total > 0 && this.currPage > 0 && this.pageSize > 0 && this.totalPage > 0)
-            {
-                PageJosnResponse<object> response = new PageJosnResponse<object>();
-                response.result.data = this.data;
-                response.result.page = new Pagination(this.total, this.currPage, this.pageSize, this.totalPage);
-                response.result.extend = this.extend;
-                response.message = message;
-                response.code = 0;
-                baseResponse = response;
-            }
-            else if (this.data != null)
-            {
-                DataJsonResponse<object> response = new DataJsonResponse<object>();
-                response.result.data = this.data;
-                response.result.extend = this.extend;
-                response.message = message;
-                response.code = 0;
-                baseResponse = response;
-            }
-            else if (this.data == null) {
-                DataJsonResponse<object> response = new DataJsonResponse<object>();
-                response.result.data = this.data;
-                response.result.extend = this.extend;
-                response.message = message;
-                response.code = 0;
-                baseResponse = response;
-            }
-            else
-            {
-                return new EmptyJosnResponse() ;
-            }
-            return (BaseResponse)baseResponse;
-        }
-         
-    }
-}

+ 0 - 20
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJosnResponse.cs

@@ -1,20 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class TokenJosnResponse<T>: BaseResponse
-    {
-		public TokenJosnResponse()
-		{
-			result = new TokenJsonResult<T>();
-		}
-		public  TokenJsonResult<T> result { get; set; }
-		public Dictionary<string, object> error { get; set; } = null;
-		public int code { get; set; } = 0;
-		public string message { get; set; } = "Success";
-	}
-}

+ 0 - 18
TEAMModelOS.SDK/Extension/DataResult/JsonResponse/TokenJsonResult.cs

@@ -1,18 +0,0 @@
-using TEAMModelOS.SDK;
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class TokenJsonResult<T> : JsonRPCResult<T>
-    {
-       
-        public AzureTableToken azureToken { get; set; }
-        public TokenJsonResult() { }
-       // public int code { get; set; } = 0;
-      //  public string message { get; set; } = "Success";
-    }
-}

+ 0 - 13
TEAMModelOS.SDK/Extension/DataResult/PageToken/AzurePagination.cs

@@ -1,13 +0,0 @@
-
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class AzurePagination<T>
-    {
-        public AzurePagination(){}
-        public List<T> data { get; set; }
-        public AzureTableToken token { get; set; }
-    }
-}

+ 0 - 17
TEAMModelOS.SDK/Extension/DataResult/PageToken/AzureTableToken.cs

@@ -1,17 +0,0 @@
-
-using System.ComponentModel.DataAnnotations;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class AzureTableToken
-    {
-        //[Required]
-        public string NextPartitionKey { get; set; }
-        //[Required]
-        public string NextRowKey { get; set; }
-        public string NextTableName { get; set; }
-        //[Required]
-        public int? TargetLocation { get; set; }
-    }
-}

+ 0 - 31
TEAMModelOS.SDK/Extension/DataResult/PageToken/Pagination.cs

@@ -1,31 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK
-{
-    
-    public class Pagination
-    {
-        public long total { get; set; }
-        public int currPage { get; set; }
-        public int pageSize { get; set; } 
-        public int totalPage { get; set; }
-      
-        public Pagination() { }
-        public Pagination(long total, int currPage, int pageSize)
-        {
-            this.total = total;
-            this.currPage = currPage;
-            this.pageSize = pageSize;
-            this.totalPage = (int)Math.Ceiling((double)this.total / (double)this.pageSize);
-        }
-        public Pagination(long total, int currPage, int pageSize, int totalPage)
-        {
-            this.total = total;
-            this.currPage = currPage;
-            this.pageSize = pageSize;
-            this.totalPage = totalPage;
-        }
-    }
-}

+ 0 - 13
TEAMModelOS.SDK/Extension/DataResult/RequestData/AzureTokenRequest.cs

@@ -1,13 +0,0 @@
-using TEAMModelOS.SDK;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK
-{
-   public class AzureTokenRequest<T> :BaseRequest
-   {
-        public T data { get; set; }
-        public AzureTableToken azureToken { get; set; }
-   }
-}

+ 0 - 12
TEAMModelOS.SDK/Extension/DataResult/RequestData/BaseRequest.cs

@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK
-{
-    public class BaseRequest
-    {
-        public long requestTime { get; set; } = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000;
-        public string method { get; set; }
-        public string repeatToken { get; set; }
-    }
-}

+ 0 - 10
TEAMModelOS.SDK/Extension/DataResult/RequestData/PaginationRequest.cs

@@ -1,10 +0,0 @@
-using TEAMModelOS.SDK;
-
-namespace TEAMModelOS.SDK
-{
-    public class PaginationRequest<T> : BaseRequest
-    {
-        public T data { get; set; }
-        public Pagination  page{ get; set; }
-    }
-}

+ 0 - 38
TEAMModelOS.SDK/Extension/Language/Implements/LanguageService.cs

@@ -1,38 +0,0 @@
-using TEAMModelOS.SDK.Extension.Language.Interfaces;
-using TEAMModelOS.SDK.Extension.Language.Model;
-using Microsoft.Extensions.Options;
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK.Extension.Language.Implements
-{
-    public class LanguageService : ILanguageService
-    {
-        private Dictionary<string, SmsCountryCode> smsMap { get; set; }
-        public List<SmsCountryCode> countryCodes;
-
-        public LanguageService(IOptions<List<SmsCountryCode>> _option)
-        {
-            countryCodes = _option.Value;
-           
-        }
-        private LanguageService SmsLanguage()
-        {
-            foreach (SmsCountryCode sms in countryCodes) {
-                if (this.smsMap == null)
-                {
-                    smsMap = new Dictionary<string, SmsCountryCode>();
-                }
-                if (!smsMap.ContainsKey(sms.CountryCode))
-                {
-                    smsMap.Add(sms.CountryCode, sms);
-                }
-            }
-            return this;
-        }
-        public Dictionary<string, SmsCountryCode> GetSmsLanguage()
-        {
-            SmsLanguage();
-            return smsMap;
-        }
-    }
-}

+ 0 - 12
TEAMModelOS.SDK/Extension/Language/Interfaces/ILanguageService.cs

@@ -1,12 +0,0 @@
-using TEAMModelOS.SDK.Extension.Language.Model;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Extension.Language.Interfaces
-{
-    public interface ILanguageService
-    {
-        Dictionary<string, SmsCountryCode> GetSmsLanguage();
-    }
-}

+ 0 - 18
TEAMModelOS.SDK/Extension/Language/LanguageExtension.cs

@@ -1,18 +0,0 @@
-using TEAMModelOS.SDK.Extension.Language.Implements;
-using TEAMModelOS.SDK.Extension.Language.Interfaces;
-using TEAMModelOS.SDK.Extension.Language.Model;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK.Extension.Language
-{
-    public static class RedisExtension
-    {
-        public static void AddLanguage(this IServiceCollection services, IConfigurationSection LangConfiguration)
-        {
-            services.Configure<List<SmsCountryCode>>(LangConfiguration);
-            services.AddScoped<ILanguageService, LanguageService>();
-        }
-    }
-}

+ 0 - 10
TEAMModelOS.SDK/Extension/Language/Model/SmsCountryCode.cs

@@ -1,10 +0,0 @@
-namespace TEAMModelOS.SDK.Extension.Language.Model
-{
-    public  class SmsCountryCode
-    {
-        public string Name { get; set; }
-        public string CountryCode { get; set; }
-        public string Language { get; set; }
-        public string SmsLang { get; set; }
-    }
-}

+ 6 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/ExamClassResult.cs

@@ -43,10 +43,16 @@ namespace TEAMModelOS.SDK.Models
         public double srate { get; set; }
         public double srate { get; set; }
         //单科单班标准差
         //单科单班标准差
         public double standard { get; set; }
         public double standard { get; set; }
+        //知识点结算内容
         public List<double> krate { get; set; } = new List<double>();
         public List<double> krate { get; set; } = new List<double>();
         public List<int> phc { get; set; } = new List<int>();
         public List<int> phc { get; set; } = new List<int>();
         public List<int> plc { get; set; } = new List<int>();
         public List<int> plc { get; set; } = new List<int>();
         public List<int> pc { get; set; } = new List<int>();
         public List<int> pc { get; set; } = new List<int>();
+        //认知层次结算内容
+        public List<double> frate { get; set; } = new List<double>();
+        public List<int> fphc { get; set; } = new List<int>();
+        public List<int> fplc { get; set; } = new List<int>();
+        public List<int> fpc { get; set; } = new List<int>();
     }
     }
 /*    public class PaperSimple {
 /*    public class PaperSimple {
         public string id { get; set; }
         public string id { get; set; }

+ 146 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Notice.cs

@@ -0,0 +1,146 @@
+using Microsoft.Azure.Cosmos.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+
+namespace TEAMModelOS.SDK.Models
+{
+
+
+    /// <summary>
+    /// 前端多语言处理
+    /// </summary>
+    //public string title { get; set; }
+    /// <summary>
+    /// 前端多语言处理
+    /// </summary>
+    //public string content { get; set; }
+    /*
+     {
+        "title":"通知标题",
+        "type":"通知类型",
+        "level":"重要程度",
+        "content":"通知内容",
+        "data":"传输数据josn",
+        "stime":"发起时间戳",
+        "etime":"到期时间戳",
+        "id":"通知id",
+        "code":"发起人"
+        "pk":"notice"
+    }
+     */
+    /// <summary>
+    /// 通知主体存放位置:/notice/{业务id}.json
+ 
+    /// 活跃通知放在CosmosDB  Common表中,并设置"ttl":2592000,不能超过30天(2592000),一天(3600),一周(25200),允许删除
+    /// 过期通知存放至blob中,存放位置, 允许被删除,直接删除记录
+    ///             stuid:/student/stuid/receiver/xxxx时间戳排序.json
+    ///             tmdid:/receiver/xxxx时间戳排序.json
+    /// </summary>
+    public class Notice
+    {
+
+        /// <summary>
+        /// 源数据的id
+        /// </summary>
+        public string sid { get; set; }
+        /// <summary>
+        /// 源数据的code
+        /// </summary>
+        public string scode { get; set; }
+        /// <summary>
+        /// 源数据的pk
+        /// </summary>
+        public string spk { get; set; }
+        /// <summary>
+        /// 源数据的学校编码
+        /// </summary>
+        public string school { get; set; }
+        /// <summary>
+        /// 源数据的scope
+        /// </summary>
+        public string scope { get; set; }
+        /// <summary>
+        /// 通知的业务类型,做什么事情用,具体业务类型再定义。 vote-join 
+        /// </summary>
+        public string type { get; set; }
+        /// <summary>
+        /// 重要等级1置顶,2非常重要,3重要,4普通消息,5不重要
+        /// </summary>
+        public int level { get; set; }
+        /// <summary>
+        /// 传输数据josn
+        /// </summary>
+        public string data { get; set; }
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public long stime { get; set; }
+        /// <summary>
+        /// 到期时间,发给接收者的cosmosDB ttl是从当前时间到结束时间为止
+        /// </summary>
+        public long etime { get; set; }
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string creatorId { get; set; }
+
+        /// 通知主体的被通知人存放位置:  /notice/{业务id}_receiver.json
+        /// <summary>
+        /// 被通知的醍摩豆账号
+        /// </summary>
+        public List<string> tmdids { get; set; }
+        /// <summary>
+        /// 被通知的学校学生账号
+        /// </summary>
+        public List<Students> stuids { get; set; }
+    }
+
+
+    /*
+    {
+        "id":"通知id"
+        "code":"接收者1",
+        "status":"接收状态/已发送/已查看",
+        "pk":"receiver",
+        "ttl":2592000,不能超过30天(2592000),一天(3600),一周(25200)
+    }
+     */
+    /// <summary>
+    /// id  :源数据id
+    /// code:Receiver-{hbcn}-{rid}
+    /// ttl :Notice的etime-当前时间戳
+    /// pk  :Receiver
+    /// </summary>
+    /// /student/{stuid}/
+    public class Receiver : CosmosEntity
+    {
+        public string pk { get; set; } = "Receiver";
+        /// <summary>
+        /// 0 已发送,1已查看,2已处理,-1已过期
+        /// </summary>
+        public int status { get; set; }=0;
+        /// <summary>
+        /// 通知接收者
+        /// </summary>
+        public string rid { get; set; }
+        /// <summary>
+        /// 当rid是学校的学生时,学校编码不能为空
+        /// </summary>
+        public string school { get; set; }
+        /// <summary>
+        /// 源数据的scope   school则接收者是学校的学生/teacher接收者是醍摩豆账号
+        /// </summary>
+        public string scope { get; set; }
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public long ctime { get; set; }
+        /// <summary>
+        /// 通知url
+        /// </summary>
+        public string urlNotice { get; set; }
+
+    }
+}

+ 1 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/StuList.cs

@@ -19,6 +19,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
     {
     {
         public string id { get; set; }
         public string id { get; set; }
         public string code { get; set; }
         public string code { get; set; }
+        public string schoolId { get; set; }
     }
     }
     public class CourseInfo
     public class CourseInfo
     {
     {

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

@@ -205,7 +205,7 @@
 							params.scope = this.$route.name === 'personalSurvey' && this.classType ===
 							params.scope = this.$route.name === 'personalSurvey' && this.classType ===
 								'private' ? 'private' : 'school'
 								'private' ? 'private' : 'school'
 							params.name = this.qnForm.name
 							params.name = this.qnForm.name
-							params.startTime = this.publishModel === '1' ? new Date(this.qnForm.startTime)
+							params.startTime = !this.isImmediate ? new Date(this.qnForm.startTime)
 								.getTime() : -1
 								.getTime() : -1
 							params.endTime = new Date(this.qnForm.endTime).getTime()
 							params.endTime = new Date(this.qnForm.endTime).getTime()
 							params.description = this.qnForm.description
 							params.description = this.qnForm.description

+ 26 - 19
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseBar.vue

@@ -5,25 +5,28 @@
 <script>
 <script>
     export default {
     export default {
         name: 'hello',
         name: 'hello',
-        props: ['echartsData'],
+		props:{
+			echartsData:{
+				type:Array,
+				default:() => []
+			},
+			subjectIndex:{
+				type:Number,
+				default:NaN
+			}
+		},
         data() {
         data() {
             return {
             return {
                 subjectList: [],
                 subjectList: [],
                 subjectSeries: [],
                 subjectSeries: [],
                 subjectColors: ['#db615e', '#db8dd2', '#42beda', '#1EB58D', '#99ccff', '#dbaf4f'],
                 subjectColors: ['#db615e', '#db8dd2', '#42beda', '#1EB58D', '#99ccff', '#dbaf4f'],
                 lineData: 440,
                 lineData: 440,
-                areaData: 490.5
+                areaData: 490.5,
+				curSubjectIndex:NaN
             }
             }
         },
         },
-        created() {
-            // this.subjectList = this.echartsData
-            // console.log(this.echartsData)
-            // if (this.getBaseBarData) this.handleOptions(this.getBaseBarData)
-
-        },
 
 
         methods: {
         methods: {
-
             // 处理动态配置文件
             // 处理动态配置文件
             handleOptions(val) {
             handleOptions(val) {
                 let subjectList = val.datas
                 let subjectList = val.datas
@@ -110,12 +113,11 @@
                 // 基于准备好的dom,初始化echarts实例
                 // 基于准备好的dom,初始化echarts实例
                 let myBar = this.$echarts.init(document.getElementById('myBar'))
                 let myBar = this.$echarts.init(document.getElementById('myBar'))
                 let that = this
                 let that = this
-
                 // 指定图表的配置项和数据
                 // 指定图表的配置项和数据
                 var option = {
                 var option = {
                     legend: {
                     legend: {
                         // data: data.datas.map(item => item.name).concat([this.$t('totalAnalysis.ach_text5'), this.$t('totalAnalysis.ach_text6')]),
                         // data: data.datas.map(item => item.name).concat([this.$t('totalAnalysis.ach_text5'), this.$t('totalAnalysis.ach_text6')]),
-                        data: data.classes[0].subjects.map(item => item.name).concat([this.$t('totalAnalysis.ach_text5'), this.$t('totalAnalysis.ach_text6')]),
+                        data: this.subjectSeries.map(item => item.name).concat([this.$t('totalAnalysis.ach_text5'), this.$t('totalAnalysis.ach_text6')]),
                         textStyle: {
                         textStyle: {
                             color: '#e4eadb'
                             color: '#e4eadb'
                         }
                         }
@@ -305,6 +307,7 @@
                 }
                 }
 
 
                 // 绘制图表
                 // 绘制图表
+				myBar.clear()
                 myBar.setOption(option)
                 myBar.setOption(option)
                 window.addEventListener('resize', function() {
                 window.addEventListener('resize', function() {
                     myBar.resize()
                     myBar.resize()
@@ -381,7 +384,7 @@
 				    let seriesItem = {
 				    let seriesItem = {
 				        name: item.name,
 				        name: item.name,
 				        type: 'bar',
 				        type: 'bar',
-				        stack: subjectList[0].name,
+				        stack: !isNaN(this.curSubjectIndex) ? item.name : subjectList[0].name,
 				        legendHoverLink: true,
 				        legendHoverLink: true,
 				        itemStyle: {
 				        itemStyle: {
 				            color: this.subjectColors[index],
 				            color: this.subjectColors[index],
@@ -390,7 +393,10 @@
 						barMaxWidth:30,
 						barMaxWidth:30,
 				        data: this.getSeriesData(val,index)
 				        data: this.getSeriesData(val,index)
 				    }
 				    }
-				    this.subjectSeries.push(seriesItem)
+					// 如果是全科情况 或者 是当前单科情况 则加入
+					if(isNaN(this.curSubjectIndex) || (!isNaN(this.curSubjectIndex) && this.curSubjectIndex === index)){
+						this.subjectSeries.push(seriesItem)
+					}
 				})
 				})
 				this.drawLine(val)
 				this.drawLine(val)
 			}
 			}
@@ -408,12 +414,13 @@
             }
             }
         },
         },
         watch: {
         watch: {
-            getBaseBarData(val) {
-                if (!val) return
-				console.log('BaseBar接收到watch的vuex',val)
-				// this.doRender(val)
-                // this.handleOptions(val.average)
-            }
+            subjectIndex:{
+				handler(n,o){
+					console.log(n)
+					this.curSubjectIndex = n
+					this.doRender(this.getBaseBarData)
+				},
+			}
         }
         }
     }
     }
 </script>
 </script>

+ 85 - 67
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseScoreRateBar.vue

@@ -5,15 +5,27 @@
 <script>
 <script>
 	export default {
 	export default {
 		name: 'hello',
 		name: 'hello',
-		props: ['echartsId','echartsData'],
+		props:{
+			echartsId:{
+				type:String,
+				default:''
+			},
+			echartsData:{
+				type:Array,
+				default:() => []
+			},
+			subjectIndex:{
+				type:Number,
+				default:NaN
+			}
+		},
 		data() {
 		data() {
 			return {
 			return {
-				scoreRateCountArr:[],
-				splitArr:[10,20,30,40,50,60,70,80,90,100]
+				scoreRateCountArr: [],
+				splitArr: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
 			}
 			}
 		},
 		},
-		created() {
-		},
+		created() {},
 
 
 		methods: {
 		methods: {
 
 
@@ -35,13 +47,14 @@
 							},
 							},
 						},
 						},
 						formatter: function(value) {
 						formatter: function(value) {
-							let range = (that.splitArr[value[0].dataIndex] - 10) + '%-' + that.splitArr[value[0].dataIndex] + '%:'
+							let range = (that.splitArr[value[0].dataIndex] - 10) + '%-' + that.splitArr[value[0]
+								.dataIndex] + '%:'
 							return range + '<br>' + value[0].data + that.$t('unit.text7')
 							return range + '<br>' + value[0].data + that.$t('unit.text7')
 						}
 						}
 					},
 					},
 					legend: {
 					legend: {
 						top: '5%',
 						top: '5%',
-						right: '20%',
+						right: '50%',
 						data: ['人数'],
 						data: ['人数'],
 						textStyle: {
 						textStyle: {
 							fontSize: 12,
 							fontSize: 12,
@@ -54,8 +67,7 @@
 						containLabel: true,
 						containLabel: true,
 						height: 300,
 						height: 300,
 						width: '75%',
 						width: '75%',
-						top:'20%',
-						left: '8%',
+						right: '18%',
 						tooltip: {
 						tooltip: {
 							show: true,
 							show: true,
 							trigger: 'axis', // 触发类型
 							trigger: 'axis', // 触发类型
@@ -70,14 +82,14 @@
 						'xAxisIndex': [
 						'xAxisIndex': [
 							0
 							0
 						],
 						],
-						bottom: 40,
+						bottom: 10,
 						'start': 0,
 						'start': 0,
 						'end': 100,
 						'end': 100,
 						handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
 						handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
 						handleSize: '160%',
 						handleSize: '160%',
 						handleStyle: {
 						handleStyle: {
 							color: '#d3dee5'
 							color: '#d3dee5'
-					
+
 						},
 						},
 						textStyle: {
 						textStyle: {
 							color: '#fff'
 							color: '#fff'
@@ -101,17 +113,19 @@
 						axisLabel: {
 						axisLabel: {
 							color: '#aaaaaa',
 							color: '#aaaaaa',
 							margin: 10,
 							margin: 10,
-							align:'left'
+							align: 'left'
 						},
 						},
 						splitLine: {
 						splitLine: {
-						    show: true,
-						    lineStyle: {
-						        color: '#4c504a',
-						        width: 0.5,
-						        type: 'solid'
-						    }
+							show: true,
+							lineStyle: {
+								color: '#4c504a',
+								width: 0.5,
+								type: 'solid'
+							}
 						},
 						},
-						data: ['     10%', '     20%', '     30%', '     40%','     50%', '     60%', '     70%', '     80%','     90%', '   100%'],
+						data: ['     10%', '     20%', '     30%', '     40%', '     50%', '     60%',
+							'     70%', '     80%', '     90%', '   100%'
+						],
 
 
 					}],
 					}],
 					yAxis: [{
 					yAxis: [{
@@ -129,82 +143,86 @@
 							fontSize: 12,
 							fontSize: 12,
 						},
 						},
 						splitLine: {
 						splitLine: {
-						    show: true,
-						    lineStyle: {
-						        color: '#4c504a',
-						        width: 0.5,
-						        type: 'solid'
-						    }
+							show: true,
+							lineStyle: {
+								color: '#4c504a',
+								width: 0.5,
+								type: 'solid'
+							}
 						},
 						},
 						axisTick: {
 						axisTick: {
 							show: true
 							show: true
 						}
 						}
 					}],
 					}],
 					series: [{
 					series: [{
-							name: '人数',
-							type: 'bar',
-							label: {
-								show: true,
-								position: 'top',
-								fontSize: 14,
-								color: '#3DC3F0',
-								fontWeight: 'bold'
-							},
-							barMaxWidth: 40,
-							itemStyle: {
-								color: {
-									type: 'linear',
-									x: 0,
-									y: 0,
-									x2: 0,
-									y2: 1,
-									colorStops: [{
-										offset: 0,
-										color: '#3DC3F0' // 0% 处的颜色
-									}, {
-										offset: 1,
-										color: '#3486b1' // 100% 处的颜色
-									}]
-								}
-							},
-							data: that.scoreRateCountArr
+						name: '人数',
+						type: 'bar',
+						label: {
+							show: true,
+							position: 'top',
+							fontSize: 14,
+							color: '#3DC3F0',
+							fontWeight: 'bold'
+						},
+						barMaxWidth: 40,
+						itemStyle: {
+							color: {
+								type: 'linear',
+								x: 0,
+								y: 0,
+								x2: 0,
+								y2: 1,
+								colorStops: [{
+									offset: 0,
+									color: '#3DC3F0' // 0% 处的颜色
+								}, {
+									offset: 1,
+									color: '#3486b1' // 100% 处的颜色
+								}]
+							}
 						},
 						},
-					]
+						data: that.scoreRateCountArr
+					}, ]
 				};
 				};
 				// 绘制图表
 				// 绘制图表
+				myBar.clear()
 				myBar.setOption(option)
 				myBar.setOption(option)
 				window.addEventListener('resize', function() {
 				window.addEventListener('resize', function() {
-				    myBar.resize()
+					myBar.resize()
 				})
 				})
 			},
 			},
 
 
-			
+
 			/* 根据学生总体数据来换取得分率区间分布数据 */
 			/* 根据学生总体数据来换取得分率区间分布数据 */
-			doRender(list) {
-				let sRateArr = list.map(i => i.sRate)
+			doRender(list,isAll) {
+				let sRateArr = isAll ? list.map(i => i.sRate) : list.map(i => i.subjects[this.subjectIndex].sRate)
 				let splitArr = [...new Array(10).keys()]
 				let splitArr = [...new Array(10).keys()]
 				let result = new Array(10).fill(0)
 				let result = new Array(10).fill(0)
 				sRateArr.forEach(rate => {
 				sRateArr.forEach(rate => {
-					splitArr.forEach((j,index) => {
-						if(rate.toString().slice(0,1) === j.toString()){
+					splitArr.forEach((j, index) => {
+						if (rate.toString().slice(0, 1) === j.toString()) {
 							result[index]++
 							result[index]++
 						}
 						}
 					})
 					})
 				})
 				})
 				this.scoreRateCountArr = result
 				this.scoreRateCountArr = result
+				this.drawLine()
 			}
 			}
 		},
 		},
 		mounted() {
 		mounted() {
-			this.doRender(this.echartsData)
-			this.drawLine()
+			this.doRender(this.echartsData,isNaN(this.subjectIndex))
 		},
 		},
 		watch: {
 		watch: {
-			echartsData(val) {
-				this.doRender(val)
-				this.drawLine()
+			echartsData:{
+				handler(n,o){
+					this.doRender(n,isNaN(this.subjectIndex))
+				},
 			},
 			},
-			deep:true,
-			immediate:true
+			subjectIndex:{
+				handler(n,o){
+					this.doRender(this.echartsData,isNaN(n))
+				},
+			}
 		}
 		}
 	}
 	}
 </script>
 </script>
@@ -212,7 +230,7 @@
 <style scoped>
 <style scoped>
 	.myScoreRateBar {
 	.myScoreRateBar {
 		width: 100%;
 		width: 100%;
-		height: 500px;
+		height: 400px;
 		margin: 0 auto;
 		margin: 0 auto;
 		display: block;
 		display: block;
 	}
 	}

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

@@ -483,6 +483,8 @@
                }
                }
                this.paperData = [...paper]
                this.paperData = [...paper]
                if (this.paperData.length) {
                if (this.paperData.length) {
+                   console.log(this.examInfo)
+                   console.log(this.examInfo.stuAns[0])
                    this.ansData = await this.getItem(this.examInfo.stuAns[0])
                    this.ansData = await this.getItem(this.examInfo.stuAns[0])
                }
                }
                console.log('5456465456456')
                console.log('5456465456456')

+ 5 - 1
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/PaperView.vue

@@ -130,7 +130,11 @@
                                 this.paperData[i].stuAns = []
                                 this.paperData[i].stuAns = []
                                 this.paperData[i].stuScore = []
                                 this.paperData[i].stuScore = []
                             } else {
                             } else {
-                                this.paperData[i].stuAns = resData.stuAns[i]
+                                if (resData.mark[i] !== undefined) {
+                                    this.paperData[i].stuAns = [resData.mark[i]]
+                                } else {
+                                    this.paperData[i].stuAns = resData.stuAns[i]
+                                }
                                 this.paperData[i].stuScore = resData.stuScore[i]
                                 this.paperData[i].stuScore = resData.stuScore[i]
                                 if (resData.stuAns[i][0] !== undefined) {
                                 if (resData.stuAns[i][0] !== undefined) {
                                     let k = 0
                                     let k = 0

+ 17 - 25
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue

@@ -3,7 +3,6 @@
         <div class="list">
         <div class="list">
             <!--活動搜尋與篩選區域-->
             <!--活動搜尋與篩選區域-->
             <div class="event-selector-block">
             <div class="event-selector-block">
-                <!---搜尋--->
                 <div class="search">
                 <div class="search">
                     <div class="search-btn" @click="openSearch = !openSearch">
                     <div class="search-btn" @click="openSearch = !openSearch">
                         <svg-icon icon-class="search"
                         <svg-icon icon-class="search"
@@ -14,7 +13,6 @@
                         <Input type="text" v-model="search" :placeholder="$t('studentWeb.public.search')" clearable />
                         <Input type="text" v-model="search" :placeholder="$t('studentWeb.public.search')" clearable />
                     </div>
                     </div>
                 </div>
                 </div>
-                <!---搜尋--->
                 <!--下拉選單-->
                 <!--下拉選單-->
                 <div>
                 <div>
                     <Dropdown>
                     <Dropdown>
@@ -23,19 +21,12 @@
                             <Icon type="ios-arrow-down"></Icon>
                             <Icon type="ios-arrow-down"></Icon>
                         </a>
                         </a>
                         <DropdownMenu slot="list">
                         <DropdownMenu slot="list">
-                            <div @click="sentEventStatus('all')">
-                                <DropdownItem>{{ $t("studentWeb.event.allStatus") }}</DropdownItem>
-                            </div>
-                            <div @click="sentEventStatus('going')">
-                                <DropdownItem>{{ $t("studentWeb.event.unFinished") }}</DropdownItem>
-                            </div>
-                            <div @click="sentEventStatus('finish')">
-                                <DropdownItem>{{ $t("studentWeb.event.Fineshed") }}</DropdownItem>
+                            <div @click="sentEventStatus(item)" v-for="(item,index) in $t('studentWeb.state')">
+                                <DropdownItem>{{ item.status }}</DropdownItem>
                             </div>
                             </div>
                         </DropdownMenu>
                         </DropdownMenu>
                     </Dropdown>
                     </Dropdown>
                 </div>
                 </div>
-                <!---->
                 <!---按鈕搜尋區(多選)--->
                 <!---按鈕搜尋區(多選)--->
                 <ul class="icon-selector" v-if="hideIconbtn == false">
                 <ul class="icon-selector" v-if="hideIconbtn == false">
                     <li class="icon-btn"
                     <li class="icon-btn"
@@ -57,7 +48,6 @@
                 </ul>
                 </ul>
                 <!---按鈕搜尋區(多選)--->
                 <!---按鈕搜尋區(多選)--->
             </div>
             </div>
-            <!--活動搜尋與篩選區域-->
             <!--活動清單分頁-->
             <!--活動清單分頁-->
             <div class="list-block"
             <div class="list-block"
                 :style="{ height: hideIconbtn == false ? '84vh' : '90vh' }">
                 :style="{ height: hideIconbtn == false ? '84vh' : '90vh' }">
@@ -111,11 +101,10 @@
                                 {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
                                 {{ dateFormat(item.startTime) }} ~ {{ dateFormat(item.endTime) }}
                             </p>
                             </p>
                         </li>
                         </li>
-                            <!--<div>已交卷</div>-->
-                        <li class="list-item-unDone" v-show="item.progress == 'going'">
+                        <li class="list-item-unDone" v-show="timeStatus(item) == 'going'">
                             <div class="isAllowRetry">{{$t("studentWeb.public.going")}}</div>
                             <div class="isAllowRetry">{{$t("studentWeb.public.going")}}</div>
                         </li>
                         </li>
-                        <li class="list-item-unDone" v-show="item.progress == 'finish'">
+                        <li class="list-item-unDone" v-show="timeStatus(item) == 'finish'">
                             <div class="isOvertime">{{$t("studentWeb.public.finish")}}</div>
                             <div class="isOvertime">{{$t("studentWeb.public.finish")}}</div>
                         </li>
                         </li>
                     </ul>
                     </ul>
@@ -123,7 +112,6 @@
                 <div class="list-end"></div>
                 <div class="list-end"></div>
             </div>
             </div>
         </div>
         </div>
-        <!--活動清單分頁-->
         {{ scrollListfromInfoPop() }}
         {{ scrollListfromInfoPop() }}
     </div>
     </div>
 </template>
 </template>
@@ -171,7 +159,7 @@
                 ],
                 ],
                 activityType: this.$t('studentWeb.state'),
                 activityType: this.$t('studentWeb.state'),
                 mockdata: "",
                 mockdata: "",
-                eventPageType: ["Preview", "Exam", "HomeWork", "Vote", "Survey"], //本頁出現的類型
+                eventPageType: ["Learn", "Exam", "HomeWork", "Vote", "Survey"], //本頁出現的類型
                 openSearch: false, //打開搜尋器
                 openSearch: false, //打開搜尋器
                 search: "",
                 search: "",
                 alreadyScrolltimes: 0,
                 alreadyScrolltimes: 0,
@@ -180,7 +168,8 @@
                 hideIconbtn: false,
                 hideIconbtn: false,
                 isListNoItem: false, //清單為空
                 isListNoItem: false, //清單為空
                 eventList: [],
                 eventList: [],
-                eventShow:[]
+                eventShow: [],
+                dateTime: Date.parse(new Date())
             };
             };
         },
         },
         components: { PreviewProgressPie },
         components: { PreviewProgressPie },
@@ -276,37 +265,41 @@
                     x = e.clientX;
                     x = e.clientX;
                     y = e.clientY;
                     y = e.clientY;
                 }
                 }
-
                 return { x: x, y: y }; //posx posy就是游標的X,Y值了
                 return { x: x, y: y }; //posx posy就是游標的X,Y值了
             },
             },
             //取得座標
             //取得座標
             getPosition(element) {
             getPosition(element) {
                 var x = 0;
                 var x = 0;
                 var y = 0;
                 var y = 0;
-
                 while (element) {
                 while (element) {
                     x += element.offsetLeft - element.scrollLeft + element.clientLeft;
                     x += element.offsetLeft - element.scrollLeft + element.clientLeft;
                     y += element.offsetTop - element.scrollLeft + element.clientTop;
                     y += element.offsetTop - element.scrollLeft + element.clientTop;
                     element = element.offsetParent;
                     element = element.offsetParent;
                 }
                 }
-
                 return { x: x, y: y };
                 return { x: x, y: y };
             },
             },
-
+            timeStatus(data) {
+                console.log(data)
+                let date = (new Date()).getTime() //当前时间
+                if (date >= data.endTime) {
+                    return 'finish'
+                } else {
+                    return 'going'
+                }
+            },
             //將目前所滑過的投票項目之高度回傳到$store
             //將目前所滑過的投票項目之高度回傳到$store
             sentVoteResulthover(status) {
             sentVoteResulthover(status) {
                 var hoverItem = {
                 var hoverItem = {
                     status: status,
                     status: status,
                     itemIDHeignt: this.getCursorPosition().y,
                     itemIDHeignt: this.getCursorPosition().y,
                 };
                 };
-
                 this.$store.commit("voteResulthover", hoverItem);
                 this.$store.commit("voteResulthover", hoverItem);
             },
             },
             sentEventStatus(status) {
             sentEventStatus(status) {
                 if (status == "reMake" || status == "reExam") {
                 if (status == "reMake" || status == "reExam") {
                     this.eventTypeCheckers = [];
                     this.eventTypeCheckers = [];
                 }
                 }
-                this.selectedEventStatusNow = status;
+                this.selectedEventStatusNow = status.status;
                 this.predealMockdatafirstItem();
                 this.predealMockdatafirstItem();
             },
             },
             predealMockdatafirstItem() {
             predealMockdatafirstItem() {
@@ -337,7 +330,6 @@
                 if (currentfilterArray.length !== 0) {
                 if (currentfilterArray.length !== 0) {
                     this.eventShow = [...currentfilterArray]
                     this.eventShow = [...currentfilterArray]
                     this.isListNoItem = false;
                     this.isListNoItem = false;
-                    //this.sentSelectedEventTitle(currentfilterArray[0]);
                     document.querySelectorAll(".event-list .list-block")[0].scrollBy({
                     document.querySelectorAll(".event-list .list-block")[0].scrollBy({
                         top: -document.querySelectorAll(".event-list .list-block")[0]
                         top: -document.querySelectorAll(".event-list .list-block")[0]
                             .scrollHeight,
                             .scrollHeight,

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

@@ -8,7 +8,6 @@
                         <svg-icon class="titleIcon" icon-class="calander" />
                         <svg-icon class="titleIcon" icon-class="calander" />
                         <span class="title">{{ $t("studentWeb.calenderCardTitle") }}</span>
                         <span class="title">{{ $t("studentWeb.calenderCardTitle") }}</span>
                     </p>
                     </p>
-
                     <div>
                     <div>
                         <div class="title-rect" />
                         <div class="title-rect" />
                         <p class="title-rect-name">{{ $t("studentWeb.recentClass") }}</p>
                         <p class="title-rect-name">{{ $t("studentWeb.recentClass") }}</p>
@@ -58,8 +57,6 @@
                                         </li>
                                         </li>
                                         <li class="list-item-unDone"></li>
                                         <li class="list-item-unDone"></li>
                                     </ul>
                                     </ul>
-                                    <!--<router-link :to="`/studentWeb/eventView#${item.eventID}`">
-                        </router-link>-->
                                 </li>
                                 </li>
                             </div>
                             </div>
                         </div>
                         </div>
@@ -106,8 +103,6 @@
                         <div class="myTestProgress"></div>
                         <div class="myTestProgress"></div>
                     </div>
                     </div>
                 </Card>
                 </Card>
-                <!--<router-link to="/studentWeb/eventView">
-                </router-link>-->
                 <br />
                 <br />
                 <Card class="bar-card" @click.native="noData">
                 <Card class="bar-card" @click.native="noData">
                     <h3 style="color: #575757; font-weight: 700">
                     <h3 style="color: #575757; font-weight: 700">
@@ -125,8 +120,6 @@
                         <div class="myTestProgress"></div>
                         <div class="myTestProgress"></div>
                     </div>
                     </div>
                 </Card>
                 </Card>
-                <!--<router-link to="/studentWeb/studyView">
-                <!--</router-link>-->
             </i-col>
             </i-col>
         </Row>
         </Row>
         <Row :gutter="30" v-if="spanCharts == true">
         <Row :gutter="30" v-if="spanCharts == true">
@@ -252,7 +245,6 @@
             },
             },
             sentSelectedEventTitle: function (item) {
             sentSelectedEventTitle: function (item) {
                 this.$router.push("/studentWeb/eventView#" + item.eventID);
                 this.$router.push("/studentWeb/eventView#" + item.eventID);
-                //改變ItemName的狀態 vuex mutations
                 this.$store.commit("ChangeItemName", item);
                 this.$store.commit("ChangeItemName", item);
             },
             },
             setSpanCharts() {
             setSpanCharts() {

+ 12 - 3
TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue

@@ -19,7 +19,7 @@
                             <svg-icon v-if="item.eventType == 'Homework'" icon-class="doc" />
                             <svg-icon v-if="item.eventType == 'Homework'" icon-class="doc" />
                             <svg-icon v-if="item.eventType == 'Learn'"
                             <svg-icon v-if="item.eventType == 'Learn'"
                                       icon-class="selflearninginTime" />
                                       icon-class="selflearninginTime" />
-                            <svg-icon v-if="  item.eventType == 'exam'"
+                            <svg-icon v-if="  item.eventType == 'Exam'"
                                       icon-class="test"
                                       icon-class="test"
                                       class="reset-testIcon" />
                                       class="reset-testIcon" />
                             <svg-icon v-if="item.eventType == 'Vote'" icon-class="vote" />
                             <svg-icon v-if="item.eventType == 'Vote'" icon-class="vote" />
@@ -32,10 +32,10 @@
                                 <span v-show="item.eventType == 'Survey'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span>
                                 <span v-show="item.eventType == 'Survey'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span>
                                 <span>{{ item.name }}</span>
                                 <span>{{ item.name }}</span>
                                 <div style="float:right;margin-top:-20px">
                                 <div style="float:right;margin-top:-20px">
-                                    <div class="list-item-unDone" v-show="item.progress == 'going'">
+                                    <div class="list-item-unDone" v-show="timeStatus(item) == 'going'">
                                         <span class="isAllowRetry">{{$t("studentWeb.public.going")}}</span>
                                         <span class="isAllowRetry">{{$t("studentWeb.public.going")}}</span>
                                     </div>
                                     </div>
-                                    <div class="list-item-unDone" v-show="item.progress == 'finish'">
+                                    <div class="list-item-unDone" v-show="timeStatus(item) == 'finish'">
                                         <span class="isOvertime">{{$t("studentWeb.public.finish")}}</span>
                                         <span class="isOvertime">{{$t("studentWeb.public.finish")}}</span>
                                     </div>
                                     </div>
                                 </div>
                                 </div>
@@ -148,6 +148,15 @@
             randomScore: function () {
             randomScore: function () {
                 return Random.integer(70, 96);
                 return Random.integer(70, 96);
             },
             },
+            timeStatus(data) {
+                console.log(data)
+                let date = (new Date()).getTime() //当前时间
+                if (date >= data.endTime) {
+                    return 'finish'
+                } else {
+                    return 'going'
+                }
+            },
             sentSelectedEventTitle: function (item) {
             sentSelectedEventTitle: function (item) {
                 this.$router.push({path: "/studentWeb/eventView",
                 this.$router.push({path: "/studentWeb/eventView",
                   query: {
                   query: {

+ 3 - 6
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue

@@ -176,10 +176,6 @@
 						message: vm.$t('vote.form.ruleName'),
 						message: vm.$t('vote.form.ruleName'),
 						trigger: 'blur'
 						trigger: 'blur'
 					}],
 					}],
-					publishModel: [{
-						required: true,
-						trigger: 'change'
-					}],
 					description: [{
 					description: [{
 						required: true,
 						required: true,
 						message: vm.$t('vote.form.ruleDescription'),
 						message: vm.$t('vote.form.ruleDescription'),
@@ -263,8 +259,9 @@
 							params.code = this.getCurCode
 							params.code = this.getCurCode
 							params.scope = this.$route.name === 'personalVote' && this.classType === 'private' ? 'private' : 'school'
 							params.scope = this.$route.name === 'personalVote' && this.classType === 'private' ? 'private' : 'school'
 							params.name = this.voteForm.name
 							params.name = this.voteForm.name
-							params.startTime = this.voteForm.startTime
-							params.endTime = this.voteForm.endTime
+							params.startTime = !this.isImmediate ? new Date(this.voteForm.startTime)
+								.getTime() : -1
+							params.endTime = new Date(this.voteForm.endTime).getTime()
 							params.description = this.voteForm.description
 							params.description = this.voteForm.description
 							params.selectMax = this.voteForm.selectMax || 1
 							params.selectMax = this.voteForm.selectMax || 1
 							params.secret = this.voteForm.secret.indexOf('secret') > -1
 							params.secret = this.voteForm.secret.indexOf('secret') > -1

+ 20 - 14
TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue

@@ -339,8 +339,26 @@ export default {
         },
         },
         saveGroup() {
         saveGroup() {
             this.tableLoading = true
             this.tableLoading = true
+            // this.$api.schoolSetting.upsertGroup({
+            //     classroom: this.classList[this.curClassIndex]
+            // }).then(
+            //     (res) => {
+            //         if (!res.error) {
+            //             this.$Message.success(this.$t('cusMgt.saveOk'))
+            //         } else {
+            //             this.$Message.error('API error!')
+            //         }
+            //     },
+            //     (err) => {
+            //         this.$Message.error('API error!')
+            //     }
+            // ).finally(() => {
+            //     setTimeout(() => {
+            //         this.tableLoading = false
+            //     }, 500)
+            // })
             this.$api.schoolSetting.upsertGroup({
             this.$api.schoolSetting.upsertGroup({
-                classroom: this.classList[this.curClassIndex]
+                students: this.classList[this.curClassIndex].students
             }).then(
             }).then(
                 (res) => {
                 (res) => {
                     if (!res.error) {
                     if (!res.error) {
@@ -357,7 +375,6 @@ export default {
                     this.tableLoading = false
                     this.tableLoading = false
                 }, 500)
                 }, 500)
             })
             })
-
         },
         },
         comfirmCustomRules() {
         comfirmCustomRules() {
             if (this.groupNum === 0) {
             if (this.groupNum === 0) {
@@ -391,22 +408,11 @@ export default {
             this.classList[this.curClassIndex].students = this.classList[this.curClassIndex].students.sort((a, b) => {
             this.classList[this.curClassIndex].students = this.classList[this.curClassIndex].students.sort((a, b) => {
                 a.seatNo > b.seatNo
                 a.seatNo > b.seatNo
             })
             })
-            // for (let i = 0; i < maxCount; i++) {
-            //     for (let j = 0; j < this.groupNum; j++) {
-            //         let startIndex = this.groupNum * i
-            //         if (startIndex + j < stuLen) {
-            //             this.$set(this.classList[this.curClassIndex].students[startIndex + j], 'groupId', i + 1)
-            //             this.$set(this.classList[this.curClassIndex].students[startIndex + j], 'groupName', (i + 1) + this.$t('cusMgt.groupUnit'))
-            //         } else {
-            //             break
-            //         }
-            //     }
-            // }
             for (let i = 0; i < this.groupNum; i++) {
             for (let i = 0; i < this.groupNum; i++) {
                 let num = surplus == 0 ? maxCount : i < surplus ? maxCount : maxCount - 1 //每组实际人数
                 let num = surplus == 0 ? maxCount : i < surplus ? maxCount : maxCount - 1 //每组实际人数
                 for (let j = 0; j < num; j++) {
                 for (let j = 0; j < num; j++) {
                     let startIndex = i + (j * this.groupNum)
                     let startIndex = i + (j * this.groupNum)
-                    this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupId', i + 1)
+                    this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupId', (i + 1)+'')
                     this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupName', (i + 1) + this.$t('cusMgt.groupUnit'))
                     this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupName', (i + 1) + this.$t('cusMgt.groupUnit'))
                 }
                 }
             }
             }

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

@@ -297,7 +297,7 @@
 				var regex = /(\<math.*?<\/math\>)/g;
 				var regex = /(\<math.*?<\/math\>)/g;
 				var html = res.html
 				var html = res.html
 				var arr = html.match(regex);
 				var arr = html.match(regex);
-				if(arr.length){
+				if(arr && Array.isArray(arr) && arr.length){
 					// 对所有的mathml进行转换成svg操作
 					// 对所有的mathml进行转换成svg操作
 					arr.forEach(math => {
 					arr.forEach(math => {
 						let svgHtml = window.MathJax.mathml2svg(math, { em: 12, ex: 6 })
 						let svgHtml = window.MathJax.mathml2svg(math, { em: 12, ex: 6 })

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

@@ -179,7 +179,7 @@ export default {
                     { required: true, type: 'number', message: this.$t('learnActivity.createEv.errTips9'), trigger: 'change' }
                     { required: true, type: 'number', message: this.$t('learnActivity.createEv.errTips9'), trigger: 'change' }
                 ]
                 ]
             },
             },
-            activeTab: 'preview',
+            activeTab: 'manualPaper', //默认到试卷库
             curSubIndex: 0,
             curSubIndex: 0,
             evaluationInfo: {
             evaluationInfo: {
                 name: '',
                 name: '',

+ 6 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue

@@ -201,7 +201,7 @@ export default {
                 let params = {
                 let params = {
                     '@DESC': 'createTime',
                     '@DESC': 'createTime',
                     'code': this.scope,
                     'code': this.scope,
-                    "scope": scope,
+                    "scope": this.routeScope,
                     //'gradeIds[*]': scope == 'school' ? this.gradeIds : [],
                     //'gradeIds[*]': scope == 'school' ? this.gradeIds : [],
                     'gradeIds[*]': [],
                     'gradeIds[*]': [],
                     'periodId': scope == 'school' ? this.searchPeriod : [],
                     'periodId': scope == 'school' ? this.searchPeriod : [],
@@ -226,7 +226,6 @@ export default {
     },
     },
     created() {
     created() {
         this.routeScope = this.$route.name == 'createPrivEva' ? 'private' : 'school'
         this.routeScope = this.$route.name == 'createPrivEva' ? 'private' : 'school'
-        this.scope = this.$store.state.userInfo.TEAMModelId
         this.$store.dispatch('user/getSchoolProfile').then(
         this.$store.dispatch('user/getSchoolProfile').then(
             res => {
             res => {
                 this.schoolBase = res.school_base
                 this.schoolBase = res.school_base
@@ -284,10 +283,14 @@ export default {
         },
         },
         source:{
         source:{
             handler(n,o){
             handler(n,o){
+                console.log(this.$route.name)
                 if(this.source){
                 if(this.source){
                     this.scope = this.source
                     this.scope = this.source
+                }else{
+                    this.scope = this.$route.name == 'createPrivEva' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode
                 }
                 }
-            }
+            },
+            immediate:true
         }
         }
 
 
     }
     }

+ 12 - 12
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -67,10 +67,10 @@
                             <InputNumber v-model="studentAnswer.scores[item.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="item.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                             <InputNumber v-model="studentAnswer.scores[item.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="item.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                             <!-- 快速打分 满分 零分 -->
                             <!-- 快速打分 满分 零分 -->
                             <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
                             <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
-                                <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore((getScoreIndex(typeIndex,index)),item.score)">
+                                <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore(item.index,item.score)">
                                     <!-- 题目分数 -->{{item.score}}
                                     <!-- 题目分数 -->{{item.score}}
                                 </span>
                                 </span>
-                                <span class="fast-score-tag" :title="$t('learnActivity.score.zeroScore')" @click="fastSetScore((getScoreIndex(typeIndex,index)),0)" style="background:#ed4014">
+                                <span class="fast-score-tag" :title="$t('learnActivity.score.zeroScore')" @click="fastSetScore(item.index,0)" style="background:#ed4014">
                                     0
                                     0
                                 </span>
                                 </span>
                             </div>
                             </div>
@@ -110,9 +110,9 @@
                                 <p class="answer-title">
                                 <p class="answer-title">
                                     <span v-show="!showQu" class="item-question-order">{{$t('learnActivity.score.quIndex1')}} {{ getQuIndex(typeIndex,index)}} .</span>
                                     <span v-show="!showQu" class="item-question-order">{{$t('learnActivity.score.quIndex1')}} {{ getQuIndex(typeIndex,index)}} .</span>
                                     {{$t('learnActivity.score.stuAns')}}
                                     {{$t('learnActivity.score.stuAns')}}
-                                    <Icon type="md-checkmark" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index)] == item.score" />
-                                    <Icon type="md-close" color="#ed4014" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index)] == 0" />
-                                    <Icon custom="iconfont icon-half-right" color="#ff9900" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index)] > 0 && studentAnswer.scores[getScoreIndex(typeIndex,index)] < item.score" />
+                                    <Icon type="md-checkmark" v-show="studentAnswer.scores[item.index] == item.score" />
+                                    <Icon type="md-close" color="#ed4014" v-show="studentAnswer.scores[item.index] == 0" />
+                                    <Icon custom="iconfont icon-half-right" color="#ff9900" v-show="studentAnswer.scores[item.index] > 0 && studentAnswer.scores[item.index] < item.score" />
                                 </p>
                                 </p>
                                 <!--学生作答答案显示区域-->
                                 <!--学生作答答案显示区域-->
                                 <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">
                                 <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">
@@ -193,19 +193,19 @@
                                 <InputNumber v-model="studentAnswer.scores[childItem.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="childItem.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                                 <InputNumber v-model="studentAnswer.scores[childItem.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="childItem.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                                 <!-- 快速打分 满分 零分 -->
                                 <!-- 快速打分 满分 零分 -->
                                 <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
                                 <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
-                                    <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore((getScoreIndex(typeIndex,index,childIndex)),childItem.score)">
+                                    <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore(childItem.index,childItem.score)">
                                         <!-- 题目分数 -->{{childItem.score}}
                                         <!-- 题目分数 -->{{childItem.score}}
                                     </span>
                                     </span>
-                                    <span class="fast-score-tag" :title="$t('learnActivity.score.zeroScore')" @click="fastSetScore((getScoreIndex(typeIndex,index,childIndex)),0)" style="background:#ed4014">
+                                    <span class="fast-score-tag" :title="$t('learnActivity.score.zeroScore')" @click="fastSetScore(childItem.index,0)" style="background:#ed4014">
                                         0
                                         0
                                     </span>
                                     </span>
                                 </div>
                                 </div>
                                 <!-- 加分 减分 -->
                                 <!-- 加分 减分 -->
                                 <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
                                 <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
-                                    <span class="fast-score-tag" @click="scoreUp((getScoreIndex(typeIndex,index,childIndex)),item.score)">
+                                    <span class="fast-score-tag" @click="scoreUp(childItem.index,item.score)">
                                         <Icon type="md-add" />
                                         <Icon type="md-add" />
                                     </span>
                                     </span>
-                                    <span class="fast-score-tag" @click="scoreDown(getScoreIndex(typeIndex,index,childIndex))" style="background:#ed4014">
+                                    <span class="fast-score-tag" @click="scoreDown(childItem.index)" style="background:#ed4014">
                                         <Icon type="md-remove" />
                                         <Icon type="md-remove" />
                                     </span>
                                     </span>
                                 </div>
                                 </div>
@@ -235,9 +235,9 @@
                                     <p class="answer-title">
                                     <p class="answer-title">
                                         <span class="child-item-question-order" v-show="!showQu">{{$t('learnActivity.score.quIndexLabel')}} {{getQuIndex(typeIndex,index)+'-'+ (childIndex + 1) }}{{$t('learnActivity.score.sQuLabel2')}}</span>
                                         <span class="child-item-question-order" v-show="!showQu">{{$t('learnActivity.score.quIndexLabel')}} {{getQuIndex(typeIndex,index)+'-'+ (childIndex + 1) }}{{$t('learnActivity.score.sQuLabel2')}}</span>
                                         {{$t('learnActivity.score.stuAns')}}
                                         {{$t('learnActivity.score.stuAns')}}
-                                        <Icon type="md-checkmark" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)] == childItem.score" />
-                                        <Icon type="md-close" color="#ed4014" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)] == 0" />
-                                        <Icon custom="iconfont icon-half-right" color="#ff9900" v-show="studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)] > 0 && studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)] < childItem.score" />
+                                        <Icon type="md-checkmark" v-show="studentAnswer.scores[childItem.index] == childItem.score" />
+                                        <Icon type="md-close" color="#ed4014" v-show="studentAnswer.scores[childItem.index] == 0" />
+                                        <Icon custom="iconfont icon-half-right" color="#ff9900" v-show="studentAnswer.scores[childItem.index] > 0 && studentAnswer.scores[childItem.index] < childItem.score" />
                                     </p>
                                     </p>
                                     <!--学生作答答案显示区域-->
                                     <!--学生作答答案显示区域-->
                                     <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">
                                     <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">

+ 6 - 9
TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue

@@ -173,7 +173,7 @@
                             </div>
                             </div>
                             <!-- 教师课表 -->
                             <!-- 教师课表 -->
                             <vuescroll v-show="curTab == 1">
                             <vuescroll v-show="curTab == 1">
-                                <TeaTable style="height: calc(100% - 45px)" :courseId="courseId" v-if="hasTimeTable" :teaClassList="schdClassList" :teacher="teaList[curTeaIndex] ? teaList[curTeaIndex].id : ''" :periodId="filterPeriod" :schedData="schdData" @selectCell="selectCell" @cancelCell="cancelCell"></TeaTable>
+                                <TeaTable style="height: calc(100% - 45px)" :tableLoading="tableLoading" :courseId="courseId" v-if="hasTimeTable" :teaClassList="schdClassList" :teacher="teaList[curTeaIndex] ? teaList[curTeaIndex].id : ''" :periodId="filterPeriod" :schedData="schdData" @selectCell="selectCell" @cancelCell="cancelCell"></TeaTable>
                                 <div v-else>
                                 <div v-else>
                                     <p class="no-time-table-tips">
                                     <p class="no-time-table-tips">
                                         {{filterPeriodName}}{{$t('cusMgt.notime1')}}
                                         {{filterPeriodName}}{{$t('cusMgt.notime1')}}
@@ -306,6 +306,7 @@ export default {
             }
             }
         }
         }
         return {
         return {
+            tableLoading: false,
             listLoading: false,
             listLoading: false,
             classList: [],
             classList: [],
             addType: 'class',
             addType: 'class',
@@ -524,17 +525,17 @@ export default {
         async getTeaSchd() {
         async getTeaSchd() {
             let teaId = this.teaList[this.curTeaIndex].id
             let teaId = this.teaList[this.curTeaIndex].id
             try {
             try {
+                this.tableLoading = true
                 let cusList = await this.getTeaCourse(teaId)
                 let cusList = await this.getTeaCourse(teaId)
                 let cusSchd = await this.getTeaDetail(cusList)
                 let cusSchd = await this.getTeaDetail(cusList)
                 this.$set(this.teaSchds, teaId, [])
                 this.$set(this.teaSchds, teaId, [])
-                console.log(cusSchd)
                 cusSchd.forEach(item => {
                 cusSchd.forEach(item => {
                     this.teaSchds[teaId].push(...item.courses)
                     this.teaSchds[teaId].push(...item.courses)
                 })
                 })
-                console.log('hehe', this.teaSchds)
+                this.tableLoading = false
             } catch (e) {
             } catch (e) {
-                console.log(e)
                 this.$Message.error('API ERROR!')
                 this.$Message.error('API ERROR!')
+                this.tableLoading = false
             }
             }
         },
         },
         //获取教师所有课程列表
         //获取教师所有课程列表
@@ -1122,7 +1123,6 @@ export default {
         },
         },
         //获取课程列表
         //获取课程列表
         getCourseList() {
         getCourseList() {
-            this.tableLoading = true
             this.listLoading = true
             this.listLoading = true
             let requestData = {
             let requestData = {
                 'code': this.$store.state.userInfo.schoolCode,
                 'code': this.$store.state.userInfo.schoolCode,
@@ -1145,7 +1145,6 @@ export default {
                 }
                 }
             ).finally(() => {
             ).finally(() => {
                 setTimeout(() => {
                 setTimeout(() => {
-                    this.tableLoading = false
                     this.listLoading = false
                     this.listLoading = false
                 }, 500)
                 }, 500)
             })
             })
@@ -1200,7 +1199,6 @@ export default {
                     }
                     }
                 ).finally(() => {
                 ).finally(() => {
                     setTimeout(() => {
                     setTimeout(() => {
-                        this.tableLoading = false
                         this.listLoading = false
                         this.listLoading = false
                     }, 500)
                     }, 500)
                 })
                 })
@@ -1245,7 +1243,6 @@ export default {
                 title: this.$t('cusMgt.delCus'),
                 title: this.$t('cusMgt.delCus'),
                 content: `${this.$t('cusMgt.delContent')}${cusNames.join(', ')}?`,
                 content: `${this.$t('cusMgt.delContent')}${cusNames.join(', ')}?`,
                 onOk: () => {
                 onOk: () => {
-                    this.tableLoading = true
                     this.confirmDelCus()
                     this.confirmDelCus()
                 }
                 }
             })
             })
@@ -1283,7 +1280,7 @@ export default {
                         this.$Message.error(this.$t('cusMgt.delErr'))
                         this.$Message.error(this.$t('cusMgt.delErr'))
                     }
                     }
                 ).finally(() => {
                 ).finally(() => {
-                    this.tableLoading = false
+                    // this.tableLoading = false
                 })
                 })
             }
             }
 
 

+ 7 - 2
TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue

@@ -5,7 +5,8 @@
                 <div class="class-filter-wrap">
                 <div class="class-filter-wrap">
                 </div>
                 </div>
             </div>
             </div>
-            <Table :columns="timeColumns" disabled-hover :data="timetable" border :span-method="handleSpan" style="width:calc(100% - 15px);margin-top:00px;">
+            <Table :columns="timeColumns" disabled-hover :data="timetable" border :span-method="handleSpan" style="width:calc(100% - 15px);margin-top:00px;" :loading="tableLoading">
+                <Loading slot="loading" :top="0" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
                 <!--上午/下午-->
                 <!--上午/下午-->
                 <template slot-scope="{ row, index }" slot="sub">
                 <template slot-scope="{ row, index }" slot="sub">
                     <p class="am-pm" style="">
                     <p class="am-pm" style="">
@@ -106,7 +107,7 @@
             <Select v-show="teaClassList.length" v-model="setClass" style="display:inline-block;">
             <Select v-show="teaClassList.length" v-model="setClass" style="display:inline-block;">
                 <Option v-for="(item,index) in teaClassList" :key="index" :value="item.classId">{{item.classInfo.name}}</Option>
                 <Option v-for="(item,index) in teaClassList" :key="index" :value="item.classId">{{item.classInfo.name}}</Option>
             </Select>
             </Select>
-            <p class="no-class-tips">{{$t('cusMgt.noCourseClass')}}</p>
+            <p class="no-class-tips" v-show="!teaClassList.length">{{$t('cusMgt.noCourseClass')}}</p>
         </Modal>
         </Modal>
     </div>
     </div>
 </template>
 </template>
@@ -141,6 +142,10 @@ export default {
         mode:{
         mode:{
             type:String,
             type:String,
             default:'set' //set:设置模式 view:视图模式,只渲染功能
             default:'set' //set:设置模式 view:视图模式,只渲染功能
+        },
+        tableLoading:{
+            type:Boolean,
+            default:false
         }
         }
     },
     },
     data() {
     data() {

+ 6 - 7
TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue

@@ -34,7 +34,6 @@
                         <DropdownMenu slot="list">
                         <DropdownMenu slot="list">
                             <DropdownItem name="id">{{$t('schoolBaseInfo.listOrder1')}}</DropdownItem>
                             <DropdownItem name="id">{{$t('schoolBaseInfo.listOrder1')}}</DropdownItem>
                             <DropdownItem name="state">{{$t('schoolBaseInfo.listOrder2')}}</DropdownItem>
                             <DropdownItem name="state">{{$t('schoolBaseInfo.listOrder2')}}</DropdownItem>
-                            <!--<DropdownItem name="total">依學生數排序</DropdownItem>-->
                         </DropdownMenu>
                         </DropdownMenu>
                     </Dropdown>
                     </Dropdown>
                 </div>
                 </div>
@@ -122,7 +121,7 @@
                                     <span slot="label" class="class-attr-wrap-label">{{$t('schoolBaseInfo.classroomCode')}}</span>
                                     <span slot="label" class="class-attr-wrap-label">{{$t('schoolBaseInfo.classroomCode')}}</span>
                                     <Input @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].no" clearable :placeholder="$t('schoolBaseInfo.classroomCodeHolder')" />
                                     <Input @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].no" clearable :placeholder="$t('schoolBaseInfo.classroomCodeHolder')" />
                                 </FormItem>
                                 </FormItem>
-                                <FormItem prop="gradeId" :label="$t('schoolBaseInfo.setGrade')" @click.native.stop class="requird-color">
+                                <FormItem prop="gradeId" :label="$t('schoolBaseInfo.setGrade')" @click.native.stop class="requird-color" v-if="classroomListShow[curClassIndex].openType == '1'">
                                     <span slot="label" class="class-attr-wrap-label">{{$t('schoolBaseInfo.setGrade')}}</span>
                                     <span slot="label" class="class-attr-wrap-label">{{$t('schoolBaseInfo.setGrade')}}</span>
                                     <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].gradeId" clearable>
                                     <Select @on-change="watchUpdate" :disabled="editStatus" v-model="classroomListShow[curClassIndex].gradeId" clearable>
                                         <Option v-for="(item,index) in $jsFn.getPeriod($store.state.user.schoolProfile.school_base,classroomListShow[curClassIndex].periodId).grades" :value="item.id" :key="index">
                                         <Option v-for="(item,index) in $jsFn.getPeriod($store.state.user.schoolProfile.school_base,classroomListShow[curClassIndex].periodId).grades" :value="item.id" :key="index">
@@ -735,10 +734,10 @@ export default {
         },
         },
         dataSort(data) {
         dataSort(data) {
             switch (this.orderBy) {
             switch (this.orderBy) {
-                case 'id': // ID 排序
+                case 'id': // no=>编号 排序
                     data.sort(function (a, b) {
                     data.sort(function (a, b) {
-                        let nameA = a.id.toUpperCase(); // ignore upper and lowercase
-                        let nameB = b.id.toUpperCase(); // ignore upper and lowercase
+                        let nameA = a.no.toUpperCase(); // ignore upper and lowercase
+                        let nameB = b.no.toUpperCase(); // ignore upper and lowercase
                         if (nameA < nameB) {
                         if (nameA < nameB) {
                             return -1;
                             return -1;
                         }
                         }
@@ -753,9 +752,9 @@ export default {
                 case 'state': // 智慧教室排序
                 case 'state': // 智慧教室排序
                     data.sort(function (a, b) {
                     data.sort(function (a, b) {
                         if (a.style == 'smart') {
                         if (a.style == 'smart') {
-                            return 1
-                        } else {
                             return -1
                             return -1
+                        } else {
+                            return 1
                         }
                         }
                     })
                     })
                     break; // 學生總數排序
                     break; // 學生總數排序

+ 6 - 3
TEAMModelOS/ClientApp/src/view/settings/Index.vue

@@ -3,6 +3,7 @@
         <div class="settings-header">
         <div class="settings-header">
             <span :class="['settings-header-item',activeTab === '1' ?  'active-item' : '']" @click="onTabChange('1')">{{ $t('settings.setting_title1')}}</span>
             <span :class="['settings-header-item',activeTab === '1' ?  'active-item' : '']" @click="onTabChange('1')">{{ $t('settings.setting_title1')}}</span>
 			<span :class="['settings-header-item',activeTab === '0' ?  'active-item' : '']" @click="onTabChange('0')">{{ $t('settings.setting_title2')}}</span>
 			<span :class="['settings-header-item',activeTab === '0' ?  'active-item' : '']" @click="onTabChange('0')">{{ $t('settings.setting_title2')}}</span>
+			<span :class="['settings-header-item',activeTab === '2' ?  'active-item' : '']" @click="onTabChange('2')">开放平台</span>
         </div>
         </div>
 
 
         <div class="settings-body">
         <div class="settings-body">
@@ -41,8 +42,8 @@
                     <!-- <Button @click="saveSetting">保存变更</Button> -->
                     <!-- <Button @click="saveSetting">保存变更</Button> -->
                 </div>
                 </div>
             </div>
             </div>
-
-            <SchoolMgmt v-else></SchoolMgmt>
+            <SchoolMgmt v-if="activeTab === '1'"></SchoolMgmt>
+            <OpenMgmt v-if="activeTab === '2'"></OpenMgmt>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
@@ -50,9 +51,11 @@
 <script>
 <script>
     //import "@/css/less-variable.less"
     //import "@/css/less-variable.less"
     import SchoolMgmt from './SchoolMgmt.vue'
     import SchoolMgmt from './SchoolMgmt.vue'
+    import OpenMgmt from './OpenMgmt.vue'
     export default {
     export default {
         components: {
         components: {
-            SchoolMgmt
+            SchoolMgmt,
+            OpenMgmt
         },
         },
         data() {
         data() {
             return {
             return {

+ 152 - 0
TEAMModelOS/ClientApp/src/view/settings/OpenMgmt.less

@@ -0,0 +1,152 @@
+@primaryColor: #1CC0F3;
+@borderColor: #424242;
+@second-textColor: #a5a5a5; //文本副级颜色
+
+.school-container {
+    display: flex;
+    height: 100%;
+
+    .school-container-header {
+        display: flex;
+        justify-content: space-between;
+        padding-right: 20px;
+        font-weight: bold;
+        color: #fff;
+    }
+
+    &-left {
+        width: 15%;
+        height: 100%;
+        border-right: 1px solid @borderColor;
+
+        .school-list-wrap {
+            height: 100%;
+            overflow: hidden;
+
+            .list-wrap {
+                width: 100%;
+                display: flex;
+                flex-direction: column;
+                padding-left: 10px;
+                padding-bottom: 50px;
+                overflow: hidden;
+
+                .school-item {
+                    position: relative;
+                    width: 100%;
+                    padding: 15px;
+                    border-bottom: 1px solid @borderColor;
+                    display: flex;
+                    flex-direction: column;
+
+                    &:last-child {
+                        border-bottom: none;
+                    }
+
+                    &-name {
+                        font-size: 18px;
+                        font-weight: bold;
+                        color: #fff;
+                    }
+
+                    &-status {
+                        font-size: 12px;
+                        background: @primaryColor;
+                        padding: 2px 8px;
+                        margin-left: 10px;
+                        border-radius: 5px;
+                    }
+
+                    &-code {
+                        margin: 5px 0;
+                        color: @second-textColor;
+                        letter-spacing: .6px;
+                    }
+
+                    &-nums {
+                        color: @primaryColor;
+                        margin-top: 5px;
+
+                        .ivu-icon {
+                            font-size: 18px;
+                            margin-right: 5px;
+                        }
+                    }
+
+                    &-role {
+                        position: absolute;
+                        right: 20px;
+                        top: 20px;
+                        color: @second-textColor;
+                    }
+
+                    &-btn {
+                        position: absolute;
+                        right: 20px;
+                        bottom: 20px;
+                        width: 100px;
+                        height: 30px;
+                        line-height: 30px;
+                        border-radius: 5px;
+                        color: #fff;
+                        background: @primaryColor;
+                        text-align: center;
+                        visibility: hidden;
+                        cursor: pointer;
+
+                        .ivu-icon {
+                            font-size: 16px;
+                            margin-right: 2px;
+                        }
+                    }
+
+                    &:hover {
+                        .item-active;
+
+                        .school-item-btn {
+                            visibility: visible;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    &-right {
+        // width: 60%;
+        flex: 1;
+        height: 100%;
+
+        .school-container-header {
+            width: 100%;
+            height: 50px;
+            border-bottom: 1px solid @borderColor;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            padding: 0 20px;
+        }
+
+        .table-wrap {
+            // padding: 0 20px;
+        }
+    }
+
+
+
+    &-header {
+        width: 100%;
+        height: 50px;
+        line-height: 50px;
+        padding-left: 20px;
+        color: @second-textColor;
+        border-bottom: 1px solid @borderColor;
+    }
+
+    .item-active {
+        background-image: -webkit-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+        background-image: -o-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+        background-image: -moz-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+        background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
+    }
+}

+ 318 - 0
TEAMModelOS/ClientApp/src/view/settings/OpenMgmt.vue

@@ -0,0 +1,318 @@
+<template>
+    <div class="school-container">
+        <!--<Loading v-show="isLoading"></Loading>-->
+        <div class="school-container-left">
+            <div class="school-container-header">
+                <span>开放平台设置</span>
+            </div>
+            <vuescroll>
+                <div class="school-list-wrap">
+                    <!--<div v-if="mySchoolList.length === 0">
+                        <EmptyData :top="50"></EmptyData>
+                    </div>-->
+                    <div class="list-wrap">
+                        <!--<Menu active-name="mge" :open-names="['1']">
+                            <Submenu name="1" >
+                                <template slot="title">
+                                    <Icon type="ios-analytics" />
+                                    应用管理
+                                </template>
+                                    <MenuItem  name="mge">应用列表</MenuItem>
+                                    <MenuItem  name="add">添加应用</MenuItem>
+                            </Submenu>
+                        </Menu>-->
+                        <div class="school-item" @click="getSelect('mge')">
+                            <span class="school-item-name">
+                                <span>应用管理</span>
+                            </span>
+                        </div>
+                        <div class="school-item" @click="getSelect('add')">
+                            <span class="school-item-name">
+                                <span>添加应用</span>
+                            </span>
+                        </div>
+                    </div>
+                </div>
+            </vuescroll>
+        </div>
+        <div class="school-container-right">
+            <div class="school-container-header">
+                <span>应用列表</span>
+                <div>
+                    <Input placeholder="请输入搜索名称或appkey">
+                    <Icon type="ios-search" slot="prefix" />
+                    </Input>
+                </div>
+            </div>
+            <div class="table-wrap" v-show="index == 'mge'">
+                <Table :data="tableData1" :columns="tableColumns1">
+                    <template slot-scope="{ row, index }" slot="status">
+                        <div v-show="row.status == 0">
+                            <Button type="primary" size="small" style="margin-right: 5px">通过</Button>
+                            <Button type="error" size="small">不通过</Button>
+                        </div>
+                    </template>            
+                    <template slot-scope="{ row, index }" slot="action">
+                            <Button type="primary" size="small" style="margin-right: 5px">编辑</Button>
+                            <Button type="error" size="small">删除</Button>
+                    </template>
+                </Table>
+                <div style="margin: 10px;overflow: hidden">
+                    <div style="float: right;">
+                        <Page :total="100" :current="1" @on-change="changePage"></Page>
+                    </div>
+                </div>
+            </div>          
+            <div style="width:45%;margin-top:30px;color:#fff;margin-left:30px" v-show="index == 'add'">
+                <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="120">
+                    <FormItem label="应用名称:" prop="name">
+                        <Input v-model="formValidate.name" placeholder="请输入应用名称"></Input>
+                    </FormItem>
+                    <FormItem label="app key:" prop="key">
+                        <Input v-model="formValidate.key" placeholder="请输入appkey"></Input>
+                    </FormItem>
+                    <FormItem label="app_secret:" prop="secret">
+                        <Input v-model="formValidate.secret" placeholder="请输入app_secret"></Input>
+                    </FormItem>
+                    <FormItem label="应用图标:">
+                        <Upload>
+                            <Button icon="ios-cloud-upload-outline">点击上传图片</Button>
+                        </Upload>
+                    </FormItem>
+                    <FormItem label="功能模块" prop="model">
+                        <CheckboxGroup v-model="formValidate.model">
+                            <Checkbox label="模块一"></Checkbox>
+                            <Checkbox label="模块二"></Checkbox>
+                            <Checkbox label="模块三"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                            <Checkbox label="模块四"></Checkbox>
+                        </CheckboxGroup>
+                    </FormItem>
+                    <FormItem label="限制连接次数:" prop="num">
+                        <Select v-model="formValidate.num" :autosize="{minRows: 2,maxRows: 5}" placeholder="不限制"></Select>
+                    </FormItem>
+                    <FormItem label="账号ID:" prop="id">
+                        <Input v-model="formValidate.id" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入账号ID"></Input>
+                    </FormItem>
+                    <FormItem>
+                        <Button type="primary">提交</Button>
+                    </FormItem>
+                </Form>
+            </div>
+        </div>
+
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+                teacherInfo: {
+                    defaultschool: ''
+                },
+                index: 'mge',
+                tableData1: this.mockTableData1(),
+                tableColumns1: [
+                    {
+                        title: 'appkey',
+                        key: 'key'
+                    },
+                    {
+                        title: '应用图标',
+                        key: 'pic'
+                    },
+                    {
+                        title: '应用名称',
+                        key: 'name'
+                    },
+                    {
+                        title: '开发者',
+                        key: 'author'
+                    },
+                    {
+                        title: '申请机构',
+                        key: 'company'
+                    },
+                    {
+                        title: '审核状态',
+                        slot: 'status'
+                    },
+                    {
+                        title: '操作',
+                        slot: 'action',
+                    }
+                ],
+                formValidate: {
+                    name: '',
+                    key: '',
+                    secret: '',
+                    id: '',
+                    model: [],
+                    num:0
+                },
+                ruleValidate: {
+                    name: [
+                        { required: true, message: '请输入应用名称', trigger: 'blur' }
+                    ],
+                    key: [
+                        { required: true, message: '请输入appkey', trigger: 'blur' }
+                    ],
+                    secret: [
+                        { required: true, message: '请输入app_secret', trigger: 'change' }
+                    ],
+                    id: [
+                        { required: true, message: '请输入使用者ID', trigger: 'change' }
+                    ],
+                    num: [
+                        { required: true, type: 'number', min: 1,message: '请输入使用者ID', trigger: 'change' }
+                    ],
+                    model: [
+                        { required: true, type: 'array', min: 1, message: '选择需要的功能模块', trigger: 'change' }
+                    ],
+                }
+            }
+        },
+        created() {
+
+        },
+        methods: {
+            mockTableData1() {
+                let data = [];
+                for (let i = 0; i < 10; i++) {
+                    data.push({
+                        name: 'Business' + Math.floor(Math.random() * 100 + 1),
+                        status: Math.floor(Math.random(0,3)),
+                        key: 'hjfgdhfdjkshkjhgjk',
+                        author: 'SOUL',
+                        company: 'habook',
+                        action: Math.floor(Math.random() * 7 + 1),
+                        update: new Date()
+                    })
+                }
+                return data;
+            },
+            getSelect(data) {
+                this.index = data || ''
+            },
+            formatDate(date) {
+                const y = date.getFullYear();
+                let m = date.getMonth() + 1;
+                m = m < 10 ? '0' + m : m;
+                let d = date.getDate();
+                d = d < 10 ? ('0' + d) : d;
+                return y + '-' + m + '-' + d;
+            },
+            changePage() {
+                this.tableData1 = this.mockTableData1();
+            },
+        },
+        computed: {
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    @import "./OpenMgmt.less";
+</style>
+
+<style lang="less">
+    @borderColor: #424242;
+    @second-textColor: #CBCBCB;
+
+    //文本副级颜色
+    .school-container-header {
+        .ivu-input
+
+    {
+        background: transparent;
+        width: 200px;
+        border-color: #4a4a4a;
+        color: @second-textColor;
+        &::-webkit-input-placeholder
+
+    {
+        /* WebKit browsers */
+        color: #999;
+        font-size: 12px;
+    }
+
+    }
+    }
+
+    .school-container-right {
+        .search-wrap
+
+    {
+        .ivu-input
+
+    {
+        background: transparent;
+        width: 250px;
+        border-color: #4a4a4a;
+        color: @second-textColor;
+        &::-webkit-input-placeholder
+
+    {
+        /* WebKit browsers */
+        color: #999;
+        font-size: 12px;
+    }
+
+    }
+
+    .ivu-select {
+        width: 200px;
+        margin-left: 20px;
+    }
+
+    }
+
+    .table-wrap {
+        .ivu-table
+
+    {
+        background: transparent;
+    }
+
+    .ivu-table th,
+    .ivu-table td {
+        background: transparent;
+        color: @second-textColor;
+        border-color: @borderColor;
+        height: 60px;
+    }
+
+    .ivu-table:before,
+    .ivu-table-border:after,
+    .ivu-table-wrapper-with-border {
+        background: @borderColor;
+        border-color: @borderColor;
+    }
+
+    .ivu-table-stripe .ivu-table-body tr:nth-child(2n) td,
+    .ivu-table-stripe .ivu-table-fixed-body tr:nth-child(2n) td {
+        background: #2a2a2a;
+    }
+
+    .ivu-table-stripe .ivu-table-body tr.ivu-table-row-hover td,
+    .ivu-table-stripe .ivu-table-fixed-body tr.ivu-table-row-hover td {
+        .ivu-btn
+
+    {
+        visibility: visible;
+    }
+
+    background: #5C5A5A;
+    }
+    }
+
+
+    }
+</style>

+ 0 - 6
TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue

@@ -45,12 +45,6 @@
 									<span>{{ $t('settings.goSchool')}}</span>
 									<span>{{ $t('settings.goSchool')}}</span>
 								</span>
 								</span>
 							</span>
 							</span>
-<!-- 							<span class="school-item-btn" style="background: rgb(202,54,54);" v-if="item.status === 'request'">
-								<span>
-									<Icon type="md-close" />
-									<span>取消申请</span>
-								</span>
-							</span> -->
 							<span class="school-item-btn" style="background: #1CC0F3;right: 140px;" v-if="item.status === 'invite'" @click="onConfirmJoin(item)">
 							<span class="school-item-btn" style="background: #1CC0F3;right: 140px;" v-if="item.status === 'invite'" @click="onConfirmJoin(item)">
 								<span>
 								<span>
 									<Icon type="md-checkmark" />
 									<Icon type="md-checkmark" />

+ 39 - 37
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue

@@ -5,26 +5,35 @@
             <span class="component-title" style="margin-top:40px">{{$t('totalAnalysis.ach_title1')}}</span>
             <span class="component-title" style="margin-top:40px">{{$t('totalAnalysis.ach_title1')}}</span>
         </Row>
         </Row>
         <Row class-name="component-percents">
         <Row class-name="component-percents">
-            <div class="percent-item" v-for="(item,index) in passRate" :key="index">
-                <div class="fl-col-center">
-                    <span class="percent-name">{{item.name}}</span>
-                    <span class="percent-value"><span class="percent-line" :style="{background:colorList[index]}"></span>{{item.sRate}} <span style="font-size: 22px;">%</span></span>
-					<div style="margin-left: 30px;">
-						<p>{{ $t('totalAnalysis.echarts_text15') }}:{{item.average.toFixed(1)}} </p>
-						<p>{{ $t('totalAnalysis.ach_table_text4') }}:{{item.standard.toFixed(1)}}</p>
-					</div>
-                </div>
-            </div>
+			<div v-for="(item,index) in passRate" :key="index">
+				<div class="percent-item" v-if="isAllSubject || (!isAllSubject && curSubjectIndex === (index - 1))">
+				    <div class="fl-col-center" >
+				        <span class="percent-name">{{item.name}}</span>
+				        <span class="percent-value"><span class="percent-line" :style="{background:colorList[index]}"></span>{{item.sRate}} <span style="font-size: 22px;">%</span></span>
+						<div style="margin-left: 30px;">
+							<p>{{ $t('totalAnalysis.echarts_text15') }}:{{item.average.toFixed(1)}} </p>
+							<p>{{ $t('totalAnalysis.ach_table_text4') }}:{{item.standard.toFixed(1)}}</p>
+						</div>
+				    </div>
+				</div>
+			</div>
+            
         </Row>
         </Row>
 		
 		
         <Row>
         <Row>
 			<Col span="12">
 			<Col span="12">
 				<span class="component-title">{{$t('totalAnalysis.ach_title2')}}</span>
 				<span class="component-title">{{$t('totalAnalysis.ach_title2')}}</span>
-				<BaseBar :echartsData="baseBarData" ref="baseBar"></BaseBar>
+				<BaseBar :echartsData="baseBarData" :subjectIndex="curSubjectIndex" ref="baseBar"></BaseBar>
 			</Col>
 			</Col>
 			<Col span="12">
 			<Col span="12">
-				<span class="component-title">{{$t('totalAnalysis.ach_title3')}}</span>
-				<BaseEntryBar :echartData="classDatas" echartsId="entryNumberBar"></BaseEntryBar>
+				<div v-if="isAllSubject">
+					<span class="component-title">{{$t('totalAnalysis.ach_title3')}}</span>
+					<BaseEntryBar :echartData="classDatas" echartsId="entryNumberBar"></BaseEntryBar>
+				</div>
+				<div v-else>
+					<span class="component-title">{{$t('totalAnalysis.scoreRate')}}</span>
+					<BaseScoreRateBar echartsId="sRateBar1" :subjectIndex="curSubjectIndex" :echartsData="getAnalysisJson.students"></BaseScoreRateBar>
+				</div>
 			</Col>
 			</Col>
 			<!-- <Col span="8">
 			<!-- <Col span="8">
 				<span class="component-title">{{$t('totalAnalysis.ach_title3')}}</span>
 				<span class="component-title">{{$t('totalAnalysis.ach_title3')}}</span>
@@ -33,38 +42,17 @@
         </Row>
         </Row>
 		
 		
 		<Row></Row>
 		<Row></Row>
-		<Row>
+		<Row v-if="isAllSubject">
 			<Col span="12">
 			<Col span="12">
 				<span class="component-title">{{$t('totalAnalysis.scoreRate')}}</span>
 				<span class="component-title">{{$t('totalAnalysis.scoreRate')}}</span>
-				<BaseScoreRateBar echartsId="sRateBar1" :echartsData="getAnalysisJson.students"></BaseScoreRateBar>
+				<BaseScoreRateBar echartsId="sRateBar11" :echartsData="getAnalysisJson.students"></BaseScoreRateBar>
 			</Col>
 			</Col>
 			<Col span="12">
 			<Col span="12">
 				
 				
 			</Col>
 			</Col>
 		</Row>
 		</Row>
-		
-		<!-- 进线人数统计 -->
-<!--        <Row>
-            <span class="component-title">{{$t('totalAnalysis.ach_title3')}}</span>
-            <div>
-                <BaseEntryBar :echartData="classDatas" echartsId="entryNumberBar2"></BaseEntryBar>
-            </div>
-        </Row>
-        <Divider /> -->
-		
 		<!-- 进线情况统计 -->
 		<!-- 进线情况统计 -->
-        <EntryTables ref="entryTable"></EntryTables>
-		
-		<!-- 进线率统计 -->
-<!--        <Row>
-            <span class="component-title">{{$t('totalAnalysis.ach_title6')}}</span>
-        </Row>
-        <Row type="flex" justify="space-around" class-name="base-table-row">
-            <Col span="24" class-name="achievement-table">
-            <BaseTable :columns="tableColumns" :tableDatas="earlyWarningData" ref="achievementTable" :tableName="$t('totalAnalysis.ach_title6')"  tableRef="achievementTable"></BaseTable>
-            </Col>
-        </Row> -->
-
+        <EntryTables ref="entryTable" :subjectIndex="curSubjectIndex"></EntryTables>
     </div>
     </div>
 </template>
 </template>
 
 
@@ -86,6 +74,8 @@
                 earlyWarningData: [],
                 earlyWarningData: [],
                 baseBarData: null,
                 baseBarData: null,
                 classDatas: [],
                 classDatas: [],
+				isAllSubject:true,
+				curSubjectIndex:NaN,
                 tableColumns: [
                 tableColumns: [
                     {
                     {
                         title: this.$t('totalAnalysis.base_class'),
                         title: this.$t('totalAnalysis.base_class'),
@@ -236,6 +226,18 @@
                     this.$refs.achievementTable.exportData(3)
                     this.$refs.achievementTable.exportData(3)
                 }
                 }
             })
             })
+			
+			
+			this.$EventBus.$off('onEarlySubjectChange')
+			this.$EventBus.$on('onEarlySubjectChange', index => {
+				if(index === 0){
+					this.isAllSubject = true
+					this.curSubjectIndex = NaN
+				}else{
+					this.isAllSubject = false
+					this.curSubjectIndex = index - 1
+				}
+			})
         },
         },
         computed: {
         computed: {
 			
 			

+ 5 - 8
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue

@@ -79,9 +79,7 @@
 		data() {
 		data() {
 			return {
 			return {
 				isAllSubject:true,
 				isAllSubject:true,
-				scoreRateBarData:{
-					students:[]
-				},
+				scoreRateBarData:[],
 				currentClass:{
 				currentClass:{
 					stuCount:0,
 					stuCount:0,
 					lineCount:0,
 					lineCount:0,
@@ -318,9 +316,8 @@
 						show: false,
 						show: false,
 						containLabel: true,
 						containLabel: true,
 						height: 300,
 						height: 300,
-						width: '80%',
-						top:'20%',
-						left: '8%',
+						width: '75%',
+						right:'18%',
 						tooltip: {
 						tooltip: {
 							show: true,
 							show: true,
 							trigger: 'axis', // 触发类型
 							trigger: 'axis', // 触发类型
@@ -335,7 +332,7 @@
 						'xAxisIndex': [
 						'xAxisIndex': [
 							0
 							0
 						],
 						],
-						bottom: 40,
+						bottom: 10,
 						'start': 0,
 						'start': 0,
 						'end': 100,
 						'end': 100,
 						handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
 						handleIcon: 'M512 497.821538m-418.264615 0a418.264615 418.264615 0 1 0 836.52923 0 418.264615 418.264615 0 1 0-836.52923 0Z',
@@ -540,7 +537,7 @@
 	}
 	}
 
 
 	#stuAverageBar {
 	#stuAverageBar {
-		height: 500px;
+		height: 400px;
 	}
 	}
 
 
 	.averageBarRow {
 	.averageBarRow {

+ 49 - 10
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue

@@ -27,6 +27,12 @@
 <script>
 <script>
     import BaseTable from '@/components/student-analysis/total/BaseMyTable.vue'
     import BaseTable from '@/components/student-analysis/total/BaseMyTable.vue'
     export default {
     export default {
+		props:{
+			subjectIndex:{
+				type:Number,
+				default:NaN
+			}
+		},
         components: {
         components: {
             BaseTable
             BaseTable
         },
         },
@@ -39,7 +45,11 @@
                 tipContent: '',
                 tipContent: '',
                 classList: [],
                 classList: [],
                 joinNum: 0,
                 joinNum: 0,
+				isAllSubject:true,
+				curSubjectIndex:0,
 				analysisJson:'',
 				analysisJson:'',
+				originNumberColumns:[],
+				originRateColumns:[],
                 entryNumberColumns: [
                 entryNumberColumns: [
                     {
                     {
                         title: this.$t('totalAnalysis.base_name'),
                         title: this.$t('totalAnalysis.base_name'),
@@ -108,7 +118,7 @@
                     {
                     {
                         title: this.$t('totalAnalysis.ach_text8'),
                         title: this.$t('totalAnalysis.ach_text8'),
                         key: 'entryNum',
                         key: 'entryNum',
-                        sortable: true
+                        sortable: true,
                     },
                     },
                     {
                     {
                         title: this.$t('totalAnalysis.ach_text9'),
                         title: this.$t('totalAnalysis.ach_text9'),
@@ -141,6 +151,9 @@
 			
 			
 			this.analysisJson = this.getAnalysisJson
 			this.analysisJson = this.getAnalysisJson
 			console.log(this.analysisJson)
 			console.log(this.analysisJson)
+			
+			this.originNumberColumns = JSON.parse(JSON.stringify(this.entryNumberColumns))
+			this.originRateColumns = JSON.parse(JSON.stringify(this.entryRateColumns))
         },
         },
 
 
         methods: {
         methods: {
@@ -150,16 +163,28 @@
                 // 渲染进线表格
                 // 渲染进线表格
                 let subjectList = data.classes[0].subjects
                 let subjectList = data.classes[0].subjects
 				let subjectColumns = []
 				let subjectColumns = []
-                subjectList.forEach(item => {
+                subjectList.forEach((item,index) => {
                     let subjectColumn = {
                     let subjectColumn = {
                         title: item.name,
                         title: item.name,
                         sortable: 'custom',
                         sortable: 'custom',
                         key: item.name
                         key: item.name
                     }
                     }
-					subjectColumns.push(subjectColumn)
+					if(this.isAllSubject || (!this.isAllSubject && this.curSubjectIndex === index )){
+						subjectColumns.push(subjectColumn)
+					}
                 })
                 })
 				// 清除之前的科目columns 添加当前评测的科目columns
 				// 清除之前的科目columns 添加当前评测的科目columns
 				this.entryNumberColumns.splice(4,this.entryNumberColumns.length - 4,...subjectColumns)
 				this.entryNumberColumns.splice(4,this.entryNumberColumns.length - 4,...subjectColumns)
+				console.log(this.isAllSubject)
+				// if(!this.isAllSubject){
+				// 	this.entryRateColumns = this.originRateColumns.filter(i => i.key !== 'entryNum')
+				// 	this.entryNumberColumns = this.originNumberColumns.filter(i => i.key !== 'score')
+				// }else{
+				// 	this.entryRateColumns = this.originRateColumns
+				// 	this.entryNumberColumns = this.originNumberColumns
+				// }
+				
+				console.log(this.entryRateColumns)
             },
             },
 			
 			
 			/* 获取进线情况统计表格数据 */
 			/* 获取进线情况统计表格数据 */
@@ -170,11 +195,13 @@
 						name:stu.name,
 						name:stu.name,
 						className:stu.className,
 						className:stu.className,
 						gradeRank:0,
 						gradeRank:0,
-						score:stu.total,
+						score:this.isAllSubject ? stu.total : stu.subjects[this.curSubjectIndex].score,
 					})
 					})
 					// 动态添加学生每个科目的得分
 					// 动态添加学生每个科目的得分
-					stu.subjects.forEach(subject => {
-						result[stuIndex][subject.name] = subject.score
+					stu.subjects.forEach((subject,subjectIndex)=> {
+						if(this.isAllSubject || (!this.isAllSubject && this.curSubjectIndex === subjectIndex )){
+							result[stuIndex][subject.name] = subject.score
+						}
 					})
 					})
 				})
 				})
 				/* 根据表格每个学生的总分来进行排序 */
 				/* 根据表格每个学生的总分来进行排序 */
@@ -187,6 +214,7 @@
 			
 			
 			/* 获取进线率统计数据 */
 			/* 获取进线率统计数据 */
 			getEntryBarData(analysisJson){
 			getEntryBarData(analysisJson){
+				console.log(this.isAllSubject)
 				let result = []
 				let result = []
 				analysisJson.classes.forEach((classItem,classIndex) => {
 				analysisJson.classes.forEach((classItem,classIndex) => {
 					result.push({
 					result.push({
@@ -194,10 +222,10 @@
 						className:classItem.className,
 						className:classItem.className,
 						entryNum:classItem.lineCount,
 						entryNum:classItem.lineCount,
 						totalNum:classItem.stuCount,
 						totalNum:classItem.stuCount,
-						csRate:classItem.csRate + '%',
+						csRate:this.isAllSubject ? classItem.csRate + '%' : classItem.subjects[this.curSubjectIndex].sRate + '%',
 						overAverageRate:classItem.stuCount > 0 ? ((classItem.lineCount / classItem.stuCount) * 100).toFixed(2) : 0.00,
 						overAverageRate:classItem.stuCount > 0 ? ((classItem.lineCount / classItem.stuCount) * 100).toFixed(2) : 0.00,
-						average:classItem.totalAverage.toFixed(1),
-						standardDeviation:classItem.standardDeviation.toFixed(1),
+						average:this.isAllSubject ? classItem.totalAverage.toFixed(1) : classItem.subjects[this.curSubjectIndex].average.toFixed(1),
+						standardDeviation:this.isAllSubject ? classItem.standardDeviation.toFixed(1) : classItem.subjects[this.curSubjectIndex].standard.toFixed(1),
 					})
 					})
 				})
 				})
 				/* 根据超均率 来对班级进行年级排名 */
 				/* 根据超均率 来对班级进行年级排名 */
@@ -227,6 +255,7 @@
 				this.entryRateColumns[1].filters = filterArr
 				this.entryRateColumns[1].filters = filterArr
 				this.entryNumberColumns[1].filters = filterArr
 				this.entryNumberColumns[1].filters = filterArr
             }
             }
+			
         },
         },
         computed: {
         computed: {
             getAnalysisJson() {
             getAnalysisJson() {
@@ -239,7 +268,17 @@
 				this.renderColumns(val)
 				this.renderColumns(val)
 				this.entryTableData = this.getTableDatas(val)
 				this.entryTableData = this.getTableDatas(val)
 				this.entryBarData = this.getEntryBarData(val)
 				this.entryBarData = this.getEntryBarData(val)
-            }
+            },
+			subjectIndex:{
+				handler(n,o){
+					this.isAllSubject = isNaN(n)
+					this.curSubjectIndex = n
+					let val = this.$store.state.totalAnalysis.analysisJson
+					this.renderColumns(val)
+					this.entryTableData = this.getTableDatas(val)
+					this.entryBarData = this.getEntryBarData(val)
+				},
+			}
         }
         }
     }
     }
 </script>
 </script>

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.vue

@@ -67,7 +67,7 @@
 							<Select v-model="currentClass" @on-change="onClassSelect" class="analysis-select">
 							<Select v-model="currentClass" @on-change="onClassSelect" class="analysis-select">
 								<Option v-for="(item,index) in classList" :value="index" :key="item">{{ item }}</Option>
 								<Option v-for="(item,index) in classList" :value="index" :key="item">{{ item }}</Option>
 							</Select>
 							</Select>
-							<div class="subject-tab" v-if="currentClass !== 0">
+							<div class="subject-tab">
 								<span v-for="(subject,subjectIndex) in getSubjectList" :key="subjectIndex" @click="onEarlySubjectChange(subjectIndex)" :class="['subject-tab-item',curWarningSubjectIndex === subjectIndex ? 'subject-tab-item-active' : '']">{{ subject }}</span>
 								<span v-for="(subject,subjectIndex) in getSubjectList" :key="subjectIndex" @click="onEarlySubjectChange(subjectIndex)" :class="['subject-tab-item',curWarningSubjectIndex === subjectIndex ? 'subject-tab-item-active' : '']">{{ subject }}</span>
 							</div>
 							</div>
 						</div>
 						</div>
@@ -387,7 +387,7 @@
 				this.subjectSelectVal = this.$store.state.totalAnalysis.currentSubject
 				this.subjectSelectVal = this.$store.state.totalAnalysis.currentSubject
 				/* 如果是成绩分析则要加入全科统计栏目 */
 				/* 如果是成绩分析则要加入全科统计栏目 */
 				if(this.dataSelectIndex === '0'){
 				if(this.dataSelectIndex === '0'){
-					return ['全科',...this.$store.state.totalAnalysis.subjectList] 
+					return [this.$t('totalAnalysis.allSubjects'),...this.$store.state.totalAnalysis.subjectList] 
 				}else{
 				}else{
 					return this.$store.state.totalAnalysis.subjectList
 					return this.$store.state.totalAnalysis.subjectList
 				}
 				}

+ 163 - 97
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -3578,107 +3578,112 @@ namespace TEAMModelOS.Controllers.Analysis
         //}
         //}
 
 
 
 
-        //[HttpPost("import")]
-        //public async Task<IActionResult> importIES3(JsonElement request)
-        //{
-        //    获取评测的ID
-        //            if (!request.TryGetProperty("exam", out JsonElement exam)) return BadRequest();
-        //    if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
-        //    try
-        //    {
-        //        var client = _azureCosmos.GetCosmosClient();
-        //        ExamDto examDtos = new ExamDto();
-        //        examDtos = exam.ToObject<ExamDto>();
-        //        ExamInfo info = new ExamInfo();
-        //        info.code = info.pk + "-hbcn";
-        //        info.progress = "pending";
-        //        info.id = examDtos.id;
-        //        info.name = examDtos.name;
-        //        info.grades = examDtos.grades;
-        //        info.subjects = examDtos.subjects;
-        //        info.period = examDtos.period;
-        //        examDtos.targetClasses.ForEach(e =>
-        //        {
-        //            info.classes.Add(e.id);
-        //        });
-        //        examDtos.papers.ForEach(p =>
-        //        {
-        //            PaperSimple simple = new PaperSimple();
-        //            simple.id = p.id;
-        //            simple.name = p.name;
-        //            p.points.ForEach(po =>
-        //            {
-        //                simple.point.Add(double.Parse(po));
-        //            });
-        //            p.answers.ForEach(an =>
-        //            {
-        //                List<string> ans = new List<string>();
-        //                if (an.Length > 1)
-        //                {
-        //                    char[] aa = an.ToCharArray();
-        //                    foreach (char a in aa)
-        //                    {
-        //                        switch (a)
-        //                        {
-        //                            case '1':
-        //                                ans.Add("A");
-        //                                break;
-        //                            case '2':
-        //                                ans.Add("B");
-        //                                break;
-        //                            case '3':
-        //                                ans.Add("C");
-        //                                break;
-        //                            case '4':
-        //                                ans.Add("D");
-        //                                break;
-        //                            default:
-        //                                ans.Add("");
-        //                                break;
-        //                        }
-        //                    }
-        //                }
-        //                else
-        //                {
-        //                    switch (an)
-        //                    {
-        //                        case "1":
-        //                            ans.Add("A");
-        //                            break;
-        //                        case "2":
-        //                            ans.Add("B");
-        //                            break;
-        //                        case "3":
-        //                            ans.Add("C");
-        //                            break;
-        //                        case "4":
-        //                            ans.Add("D");
-        //                            break;
-        //                        default:
-        //                            ans.Add("");
-        //                            break;
-        //                    }
-
-        //                }
-        //                simple.answers.Add(ans);
-        //            });
-        //            info.papers.Add(simple);
-        //        });
-        //        await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(info, new PartitionKey("Exam-hbcn"));
-        //        return Ok(new { info });
-        //    }
-        //    catch (Exception e)
-        //    {
-        //        await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/scoring()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
-        //        return BadRequest();
-        //    }
-        //}
+        [HttpPost("import")]
+        public async Task<IActionResult> importIES3(JsonElement request)
+        {
+            //获取评测的ID
+            if (!request.TryGetProperty("exam", out JsonElement exam)) return BadRequest();
+            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
+            try
+            {
+                var client = _azureCosmos.GetCosmosClient();
+                ExamDto examDtos = new ExamDto();
+                examDtos = exam.ToObject<ExamDto>();
+                ExamInfo info = new ExamInfo();
+                info.code = info.pk +"-"+ code;
+                info.progress = "pending";
+                info.id = examDtos.id;
+                info.name = examDtos.name;
+                info.grades = examDtos.grades;
+                info.subjects = examDtos.subjects;
+                info.period = examDtos.period;
+                examDtos.targetClasses.ForEach(e =>
+                {
+                    info.classes.Add(e.id);
+                });
+                examDtos.papers.ForEach(p =>
+                {
+                    PaperSimple simple = new PaperSimple
+                    {
+                        id = p.id,
+                        name = p.name
+                    };
+                    p.points.ForEach(po =>
+                    {
+                        simple.point.Add(double.Parse(po));
+                    });
+                    //List<List<string>> answers = new List<List<string>>();
+                    p.answers.ForEach(an =>
+                    {
+                        List<string> ans = new List<string>();
+                        if (an.Length > 1)
+                        {
+                            char[] aa = an.ToCharArray();
+                            foreach (char a in aa)
+                            {
+                                switch (a)
+                                {
+                                    case '1':
+                                        ans.Add("A");
+                                        break;
+                                    case '2':
+                                        ans.Add("B");
+                                        break;
+                                    case '3':
+                                        ans.Add("C");
+                                        break;
+                                    case '4':
+                                        ans.Add("D");
+                                        break;
+                                    default:
+                                        ans.Add("");
+                                        break;
+                                }
+                               // answers.Add(ans);
+                            }
+                        }
+                        else
+                        {
+                            switch (an)
+                            {
+                                case "1":
+                                    ans.Add("A");
+                                    break;
+                                case "2":
+                                    ans.Add("B");
+                                    break;
+                                case "3":
+                                    ans.Add("C");
+                                    break;
+                                case "4":
+                                    ans.Add("D");
+                                    break;
+                                default:
+                                    ans.Add("");
+                                    break;
+                            }
+                            //answers.Add(ans);
+                        }
+                        simple.answers.Add(ans);
+                    });
+                    info.papers.Add(simple);
+                });
+                await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(info, new PartitionKey($"Exam-{code}"));
+                return Ok(new { info });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/import()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest();
+            }
+        }
         [HttpPost("importResult")]
         [HttpPost("importResult")]
         public async Task<IActionResult> importClassResult(JsonElement request)
         public async Task<IActionResult> importClassResult(JsonElement request)
         {
         {
             //获取评测的ID
             //获取评测的ID
             if (!request.TryGetProperty("classResult", out JsonElement classResult)) return BadRequest();
             if (!request.TryGetProperty("classResult", out JsonElement classResult)) return BadRequest();
             if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
             if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
+            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
             try
             try
             {
             {
                 var client = _azureCosmos.GetCosmosClient();
                 var client = _azureCosmos.GetCosmosClient();
@@ -3687,7 +3692,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 //获取本次评测所有班级作答结果
                 //获取本次评测所有班级作答结果
                 List<ExamClassResult> examClassResults = new List<ExamClassResult>();
                 List<ExamClassResult> examClassResults = new List<ExamClassResult>();
                 var queryClass = $"select value(c) from c where c.examId =  '{id}'";
                 var queryClass = $"select value(c) from c where c.examId =  '{id}'";
-                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("ExamClassResult-hbcn") }))
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
                 {
                 {
                     examClassResults.Add(item);
                     examClassResults.Add(item);
 
 
@@ -3822,7 +3827,68 @@ namespace TEAMModelOS.Controllers.Analysis
                 return BadRequest();
                 return BadRequest();
             }
             }
         }
         }
-    }
+
+        //获取学校简易基础信息
+        [HttpPost("getSchoolInfo")]
+        public async Task<IActionResult> getInfoSchool(JsonElement request)
+        {
+            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
+            try
+            {
+                var client = _azureCosmos.GetCosmosClient();
+                List<object> info = new List<object>();
+                var query = $"select c.period,c.id,c.campuses from c where c.id = '{code}'";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base")}))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            info.Add(obj.ToObject<object>());
+                        }
+                    }
+                }
+                return Ok(new { info });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/getSchoolInfo()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest();
+            }
+        }
+
+        //获取学校某学段班级信息
+        [HttpPost("getClassInfo")]
+        public async Task<IActionResult> getClassInfo(JsonElement request)
+        {
+            if (!request.TryGetProperty("periodId", out JsonElement periodId)) return BadRequest();
+            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
+            try
+            {
+                var client = _azureCosmos.GetCosmosClient();
+                List<object> classInfo = new List<object>();
+                var query = $"select c.id,c.name from c where c.periodId = '{periodId}'";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{code}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            classInfo.Add(obj.ToObject<object>());
+                        }
+                    }
+                }
+                return Ok(new { classInfo });
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/getClassInfo()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest();
+            }
+        }
+    }   
 }
 }
 //private List<Dictionary<string, dynamic>> getKnowledgePoint(List<ExamResult> examResults, ExamInfo info)
 //private List<Dictionary<string, dynamic>> getKnowledgePoint(List<ExamResult> examResults, ExamInfo info)
 //{
 //{

+ 22 - 6
TEAMModelOS/Controllers/Analysis/AnalysisController.cs

@@ -147,7 +147,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 }
                 }
                 //获取本次评测所有班级作答结果
                 //获取本次评测所有班级作答结果
                 List<ExamClassResult> examClassResults = new List<ExamClassResult>();
                 List<ExamClassResult> examClassResults = new List<ExamClassResult>();
-                var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info,c.standard from c where c.examId =  '{id}' and c.progress = true ";
+                var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info,c.standard,c.krate,c.phc,c.plc,c.pc,c.frate,c.fphc,c.fplc,c.fpc from c where c.examId =  '{id}' and c.progress = true ";
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
                 {
                 {
                     examClassResults.Add(item);
                     examClassResults.Add(item);
@@ -460,6 +460,14 @@ namespace TEAMModelOS.Controllers.Analysis
                             fieldPoints.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
                             fieldPoints.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
                         });
                         });
                         double val = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).standard;
                         double val = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).standard;
+                        List<double> krate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).krate;
+                        List<int> phc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).phc;
+                        List<int> plc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).plc;
+                        List<int> pc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).pc;
+                        List<double> frate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).frate;
+                        List<int> fphc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fphc;
+                        List<int> fplc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fplc;
+                        List<int> fpc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fpc;
                         classAys.subjects.Add(new AysSubject
                         classAys.subjects.Add(new AysSubject
                         {
                         {
                             point = tt,
                             point = tt,
@@ -469,6 +477,14 @@ namespace TEAMModelOS.Controllers.Analysis
                             passCount = passCount,
                             passCount = passCount,
                             average = average,
                             average = average,
                             standard = val,
                             standard = val,
+                            krate = krate,
+                            phc = phc,
+                            plc = plc,
+                            pc = pc,
+                            frate = frate,
+                            fphc = fphc,
+                            fplc = fplc,
+                            fpc = fpc,
                             sRate = paperScore[key] > 0 ? Math.Round(average / paperScore[key] * 100, 2) : 0,
                             sRate = paperScore[key] > 0 ? Math.Round(average / paperScore[key] * 100, 2) : 0,
                             name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
                             name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
                             item = classSubjectPaperDatas.Where(subd => subd.Key == key).First().Value.Where(cls => cls.Key == classId).First().Value
                             item = classSubjectPaperDatas.Where(subd => subd.Key == key).First().Value.Where(cls => cls.Key == classId).First().Value
@@ -572,7 +588,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 average = examResults.FirstOrDefault(c => c.id == x.id).average,
                 average = examResults.FirstOrDefault(c => c.id == x.id).average,
                 standard = examResults.FirstOrDefault(c => c.id == x.id).standard
                 standard = examResults.FirstOrDefault(c => c.id == x.id).standard
             });
             });
-            var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard,total = info.stuCount };
+            var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard, total = info.stuCount };
             return Ok(new
             return Ok(new
             {
             {
                 students,
                 students,
@@ -1035,7 +1051,7 @@ namespace TEAMModelOS.Controllers.Analysis
                                 int index = exam.studentIds.IndexOf(id);
                                 int index = exam.studentIds.IndexOf(id);
                                 if (exam.studentScores[index][n] == 0)
                                 if (exam.studentScores[index][n] == 0)
                                 {
                                 {
-                                    wrong++;                                  
+                                    wrong++;
                                     continue;
                                     continue;
                                 }
                                 }
                                 else
                                 else
@@ -1133,7 +1149,7 @@ namespace TEAMModelOS.Controllers.Analysis
             return (key1, key2, key3, key4, keyValue, valuePair);
             return (key1, key2, key3, key4, keyValue, valuePair);
         }
         }
 
 
-        
+
 
 
         private static (KeyValuePair<string, List<int>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoLevel(ExamResult exam, ExamInfo info, List<string> keynowWrong)
         private static (KeyValuePair<string, List<int>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoLevel(ExamResult exam, ExamInfo info, List<string> keynowWrong)
         {
         {
@@ -1192,7 +1208,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 total += grade.Sum();
                 total += grade.Sum();
             }
             }
             //试卷总分
             //试卷总分
-            double TotalPoint = point.Sum();            
+            double TotalPoint = point.Sum();
             List<double> knowScore = new List<double>();
             List<double> knowScore = new List<double>();
             //得分率
             //得分率
             List<double> Score = new List<double>();
             List<double> Score = new List<double>();
@@ -1231,7 +1247,7 @@ namespace TEAMModelOS.Controllers.Analysis
                             int index = exam.studentIds.IndexOf(id);
                             int index = exam.studentIds.IndexOf(id);
                             if (exam.studentScores[index][n] == 0)
                             if (exam.studentScores[index][n] == 0)
                             {
                             {
-                                wrong++;                                
+                                wrong++;
                                 continue;
                                 continue;
                             }
                             }
                             else
                             else

+ 11 - 1
TEAMModelOS/Controllers/Analysis/ClassAys.cs

@@ -21,7 +21,7 @@ namespace TEAMModelOS.Controllers.Analysis
         public double totalAverage { get; set; }
         public double totalAverage { get; set; }
         public double standardDeviation { get; set; }
         public double standardDeviation { get; set; }
         public string gradeId { get; set; }
         public string gradeId { get; set; }
-        //¼Ç¼°à¼¶µÃ·ÖÂÊ
+        //记录�级得分率
         public double csRate { get; set; }
         public double csRate { get; set; }
     }
     }
     public class AysSubject
     public class AysSubject
@@ -36,6 +36,16 @@ namespace TEAMModelOS.Controllers.Analysis
         public double sRate { get; set; }
         public double sRate { get; set; }
         public double standard { get; set; }
         public double standard { get; set; }
         public List<double> item { get; set; }
         public List<double> item { get; set; }
+        //知识点结算内容
+        public List<double> krate { get; set; } = new List<double>();
+        public List<int> phc { get; set; } = new List<int>();
+        public List<int> plc { get; set; } = new List<int>();
+        public List<int> pc { get; set; } = new List<int>();
+        //认知层次结算内容
+        public List<double> frate { get; set; } = new List<double>();
+        public List<int> fphc { get; set; } = new List<int>();
+        public List<int> fplc { get; set; } = new List<int>();
+        public List<int> fpc { get; set; } = new List<int>();
 
 
     }
     }
 }
 }

+ 23 - 0
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -894,6 +894,29 @@ namespace TEAMModelOS.Controllers.Client
                 //ExamInfo內容取得、調整
                 //ExamInfo內容取得、調整
                 string blobContainer = (dbExamInfo.range == "school" && dbExamInfo.scope == "school" && dbExamInfo.school != null) ? dbExamInfo.school : id; //blob容器
                 string blobContainer = (dbExamInfo.range == "school" && dbExamInfo.scope == "school" && dbExamInfo.school != null) ? dbExamInfo.school : id; //blob容器
                 dbExamInfo.source = "1"; //評測來源固定為  1:課中評量 
                 dbExamInfo.source = "1"; //評測來源固定為  1:課中評量 
+                //取得課堂紀錄下的試卷資料(blob)、複製到評測紀錄下
+                //List<Dictionary<string, string>> recordPaperInfo = new List<Dictionary<string, string>>();
+                //foreach (PaperSimple paperInfo in dbExamInfo.papers)
+                //{
+                //    recordPaperInfo.Add(new Dictionary<string, string>() { { "id", paperInfo.id }, { "blob", paperInfo.blob } });
+                //}
+                //foreach (Dictionary<string, string> recordPaperInfoDic in recordPaperInfo)
+                //{
+                //    string targetScope = dbExamInfo.scope; //評測對象 school:校本班級  private:私人課程
+                //    var blobPrivateContainer = _azureStorage.GetBlobContainerClient(id);
+                //    var sourceBlob = blobPrivateContainer.GetBlobClient(recordPaperInfoDic["blob"]);
+                //    string destBlobPath = $"exam/{dbExamInfo.id}/paper/{recordPaperInfoDic["id"]}"; //path:exam/{評測ID}/paper/{試卷ID}
+                //    if (targetScope == "school") //校本
+                //    {
+                //        string schoolId = dbExamInfo.school;
+                //        var blobSchoolContainer = _azureStorage.GetBlobContainerClient(schoolId);
+                //        blobSchoolContainer.GetBlobClient(destBlobPath).StartCopyFromUri(sourceBlob.Uri);
+                //    }
+                //    else //私人
+                //    {
+                //        blobPrivateContainer.GetBlobClient(destBlobPath).StartCopyFromUri(sourceBlob.Uri);
+                //    }
+                //}
                 //UPDATE
                 //UPDATE
                 var examResponse = _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(dbExamInfo, new PartitionKey(dbExamInfo.code)).GetAwaiter().GetResult();
                 var examResponse = _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(dbExamInfo, new PartitionKey(dbExamInfo.code)).GetAwaiter().GetResult();
                 
                 

+ 6 - 2
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -1042,6 +1042,7 @@ namespace TEAMModelOS.Controllers
                 }
                 }
                 List<List<string>> stuAns = new List<List<string>>();
                 List<List<string>> stuAns = new List<List<string>>();
                 List<List<double>> stuScore = new List<List<double>>();
                 List<List<double>> stuScore = new List<List<double>>();
+                List<string> mark = new List<string> ();
                 List<double> total = new List<double>();
                 List<double> total = new List<double>();
                 if (answers.Count > 0)
                 if (answers.Count > 0)
                 {
                 {
@@ -1053,14 +1054,17 @@ namespace TEAMModelOS.Controllers
                         }
                         }
                         stuAns.Add(result.studentAnswers[index]);
                         stuAns.Add(result.studentAnswers[index]);
                         stuScore.Add(result.studentScores[index]);
                         stuScore.Add(result.studentScores[index]);
+                        if (result.mark.Count > 0) {
+                            mark.Add(result.mark[index]);
+                        }            
                         total.Add(result.sum.Where(s => s <= 59).Count());
                         total.Add(result.sum.Where(s => s <= 59).Count());
-                        total.Add(result.sum.Where(s => s > 59 && s <= 70 ).Count());
+                        total.Add(result.sum.Where(s => s > 59 && s <= 70 ).Count()); 
                         total.Add(result.sum.Where(s => s > 70 && s <= 80).Count());
                         total.Add(result.sum.Where(s => s > 70 && s <= 80).Count());
                         total.Add(result.sum.Where(s => s > 80 && s <= 90).Count());
                         total.Add(result.sum.Where(s => s > 80 && s <= 90).Count());
                         total.Add(result.sum.Where(s => s > 90 && s <= 100).Count());
                         total.Add(result.sum.Where(s => s > 90 && s <= 100).Count());
                     }                   
                     }                   
                 }
                 }
-                return Ok(new { papers, subjects,stuScore, stuAns, total,claId = infoIds });
+                return Ok(new { papers, subjects,stuScore, stuAns, mark,total,claId = infoIds });
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {

+ 1 - 1
TEAMModelOS/Controllers/Common/TriggerStuActivity.cs

@@ -90,7 +90,7 @@ namespace OS.Funct
                 }
                 }
             });
             });
             students.ForEach(x => {
             students.ForEach(x => {
-                studentss.Add(new Students { id = x.id, code = x.code });
+                studentss.Add(new Students { id = x.id, code = x.code,schoolId=x.schoolId });
             });
             });
             return (tmdids,studentss);
             return (tmdids,studentss);
         }
         }

+ 1 - 0
TEAMModelOS/Controllers/Core/ImportController.cs

@@ -266,6 +266,7 @@ namespace TEAMModelOS.Controllers
             }
             }
             var doc = _DOXC2HTMLTranslator.Translate(file.OpenReadStream());
             var doc = _DOXC2HTMLTranslator.Translate(file.OpenReadStream());
              (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
              (List<HTEXLib.DOCX.Models.ItemInfo> tests, List<string> error) = _HTML2ITEMV3Translator.Translate(doc);
+
             return Ok(new { tests, emferror= error });
             return Ok(new { tests, emferror= error });
         }
         }
 
 

+ 1 - 1
TEAMModelOS/Controllers/School/CourseController.cs

@@ -1362,7 +1362,7 @@ namespace TEAMModelOS.Controllers
         [HttpPost("find-teach-class")]
         [HttpPost("find-teach-class")]
         public async Task<IActionResult> FindPlanClass(JsonElement request)
         public async Task<IActionResult> FindPlanClass(JsonElement request)
         {
         {
-            ResponseBuilder builder = ResponseBuilder.custom();
+            
             HashSet<string> data = new HashSet<string>();
             HashSet<string> data = new HashSet<string>();
             if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
             if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
             if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
             if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();

+ 1 - 1
TEAMModelOS/Controllers/School/SchoolTeacherController.cs

@@ -103,7 +103,7 @@ namespace TEAMModelOS.Controllers
         [HttpPost("get-teacher-authoritylist")]
         [HttpPost("get-teacher-authoritylist")]
         public async Task<IActionResult> GetSchoolAuthorityList()
         public async Task<IActionResult> GetSchoolAuthorityList()
         {
         {
-            ResponseBuilder builder = ResponseBuilder.custom();
+             
             Dictionary<string, object> dict = new Dictionary<string, object>
             Dictionary<string, object> dict = new Dictionary<string, object>
             {
             {
                 { "PartitionKey",  "authority"}
                 { "PartitionKey",  "authority"}

+ 64 - 0
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -118,7 +118,71 @@ namespace TEAMModelOS.Controllers.XTest
 
 
 
 
 
 
+        [ProducesDefaultResponseType]
+        //[AuthToken(Roles = "teacher")]
+        [HttpPost("fix-stu-course")]
+        public async Task<IActionResult> fixStuCourse(JsonElement request) {
 
 
+            string originCode = request.GetProperty("originCode").GetString();
+            List<Course> courses = new List<Course>();
+            var client = _azureCosmos.GetCosmosClient();
+            var query = $"select  *  from c ";
+            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
+            {
+                courses.Add(item);
+            }
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
+            {
+                courses.Add(item);
+            }
+            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
+            foreach (var course in courses)
+            {
+                if (course.schedule.IsNotEmpty())
+                {
+                    foreach (var sc in course.schedule)
+                    {
+                        if (!string.IsNullOrEmpty(sc.stulist))
+                        {
+                            (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, new List<string>() { sc.stulist }, course.school);
+                            foreach (var addStu in studentss)
+                            {
+                                var stuCourse = new StuCourse
+                                {
+                                    id = course.id,
+                                    scode = course.code,
+                                    name = course.name,
+                                    code = $"StuCourse-{course.school}-{addStu.id}",
+                                    scope = course.scope,
+                                    school = course.school,
+                                    creatorId = course.creatorId,
+                                    pk = "StuCourse"
+                                };
+                                await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stuCourse, new PartitionKey(stuCourse.code));
+                            }
+                            foreach (var addTmd in tmdids)
+                            {
+                                var tmdCourse = new StuCourse
+                                {
+                                    id = course.id,
+                                    scode = course.code,
+                                    name = course.name,
+                                    code = $"StuCourse-{addTmd}",
+                                    scope = course.scope,
+                                    //school = courseChange.school,
+                                    creatorId = course.creatorId,
+                                    pk = "StuCourse"
+                                };
+                                await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(tmdCourse, new PartitionKey(tmdCourse.code));
+                            }
+                        }
+                    }
+                }
+            }
+            return new OkObjectResult(new { });
+        }
 
 
 
 
 
 

+ 1 - 1
TEAMModelOS/Startup.cs

@@ -92,7 +92,7 @@ namespace TEAMModelOS
                     .AllowAnyMethod();
                     .AllowAnyMethod();
                 });
                 });
             });
             });
-            services.AddAzureStorage(Configuration.GetValue<string>("Azure:Starage:ConnectionString"));
+            services.AddAzureStorage(Configuration.GetValue<string>("Azure:Storage:ConnectionString"));
             services.AddAzureRedis(Configuration.GetValue<string>("Azure:Redis:ConnectionString"));
             services.AddAzureRedis(Configuration.GetValue<string>("Azure:Redis:ConnectionString"));
             services.AddAzureCosmos(Configuration.GetValue<string>("Azure:Cosmos:ConnectionString"));
             services.AddAzureCosmos(Configuration.GetValue<string>("Azure:Cosmos:ConnectionString"));
             services.AddAzureServiceBus(Configuration.GetValue<string>("Azure:ServiceBus:ConnectionString"));
             services.AddAzureServiceBus(Configuration.GetValue<string>("Azure:ServiceBus:ConnectionString"));

+ 3 - 0
TEAMModelOS/appsettings.Development.json

@@ -18,6 +18,9 @@
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4"
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4"
   },
   },
   "Azure": {
   "Azure": {
+    "Storage": {
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn"
+    },
     "Table": {
     "Table": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn"
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn"
     },
     },

+ 1 - 1
TEAMModelOS/appsettings.json

@@ -19,7 +19,7 @@
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4"
     "IdTokenSalt": "8263692E2213497BB55E74792B7900B4"
   },
   },
   "Azure": {
   "Azure": {
-    "Starage": {
+    "Storage": {
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn"
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn"
     },
     },
     "Blob": {
     "Blob": {