zhousheng 4 年之前
父节点
当前提交
af453c005a
共有 59 个文件被更改,包括 7273 次插入6650 次删除
  1. 60 32
      TEAMModelFunction/CourseServiceBus.cs
  2. 203 0
      TEAMModelFunction/StuListServiceBus.cs
  3. 250 82
      TEAMModelFunction/TriggerExam.cs
  4. 1 1
      TEAMModelFunction/TriggerStuActivity.cs
  5. 2 2
      TEAMModelFunction/TriggerSurvey.cs
  6. 2 2
      TEAMModelFunction/TriggerVote.cs
  7. 12 5
      TEAMModelOS.SDK/Models/Cosmos/Common/ExamClassResult.cs
  8. 0 34
      TEAMModelOS.SDK/Models/Cosmos/Common/Inner/ClassChange.cs
  9. 0 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Inner/CourseChange.cs
  10. 32 0
      TEAMModelOS.SDK/Models/Cosmos/Common/Inner/StuListChange.cs
  11. 1 1
      TEAMModelOS.SDK/Models/Cosmos/Common/StuCourse.cs
  12. 2 0
      TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs
  13. 56 54
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  14. 16 43
      TEAMModelOS/ClientApp/src/components/evaluation/AnalysisItemTable.vue
  15. 4 4
      TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.less
  16. 87 27
      TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue
  17. 71 196
      TEAMModelOS/ClientApp/src/components/evaluation/OptionsTable.vue
  18. 164 0
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseMiniBar.vue
  19. 2 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnBar.vue
  20. 108 88
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  21. 13 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.less
  22. 46 37
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue
  23. 4 18
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseLine.vue
  24. 18 25
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseRateLine.vue
  25. 52 52
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  26. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/survey.js
  27. 7 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/totalAnalysis.js
  28. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/survey.js
  29. 31 25
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/totalAnalysis.js
  30. 519 358
      TEAMModelOS/ClientApp/src/router/routes.js
  31. 13 11
      TEAMModelOS/ClientApp/src/utils/public.js
  32. 193 190
      TEAMModelOS/ClientApp/src/view/Home.vue
  33. 50 8
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue
  34. 31 8
      TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue
  35. 37 12
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue
  36. 2 2
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.less
  37. 4 8
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue
  38. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.vue
  39. 1 3
      TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue
  40. 5 1
      TEAMModelOS/ClientApp/src/view/newcourse/EvDetail.vue
  41. 1 1
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue
  42. 33 24
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  43. 14 6
      TEAMModelOS/ClientApp/src/view/selflearn/SelfLearn.less
  44. 390 342
      TEAMModelOS/ClientApp/src/view/selflearn/SelfLearn.vue
  45. 1 0
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/KnowledgeAnalysis.vue
  46. 262 399
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue
  47. 3 3
      TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue
  48. 3826 3823
      TEAMModelOS/Controllers/Analysis/AchievementController.cs
  49. 352 701
      TEAMModelOS/Controllers/Analysis/AnalysisController.cs
  50. 19 3
      TEAMModelOS/Controllers/Common/ExamController.cs
  51. 5 0
      TEAMModelOS/Controllers/Common/SurveyController.cs
  52. 5 1
      TEAMModelOS/Controllers/Common/VoteController.cs
  53. 20 7
      TEAMModelOS/Controllers/School/CourseController.cs
  54. 1 1
      TEAMModelOS/Controllers/School/StudentCommonController.cs
  55. 5 0
      TEAMModelOS/Controllers/XTest/TestController.cs
  56. 113 0
      TEAMModelOS/Properties/ServiceDependencies/TeammodelOS - Web Deploy/profile.arm.json
  57. 113 0
      TEAMModelOS/Properties/ServiceDependencies/teammodelos-dep - Web Deploy/profile.arm.json
  58. 4 3
      TEAMModelOS/appsettings.Development.json
  59. 4 1
      TEAMModelOS/appsettings.json

+ 60 - 32
TEAMModelFunction/CourseServiceBus.cs

@@ -1,3 +1,4 @@
+using Azure.Cosmos;
 using Microsoft.Azure.WebJobs;
 using System;
 using System.Collections.Generic;
@@ -19,44 +20,71 @@ namespace TEAMModelFunction
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
         }
+
         /// <summary>
         /// 完善课程变更
         /// </summary>
         /// <data msg>
-        /// "ids":["s111","t1111"]//学生
-        /// "opt":"join/leave",//状态
-        /// "no":"CLASS001"//教室编号
-        /// "source":1/2  //学生名单数据来源 1是不同学校的学生账号,2是扫码加入的醍摩豆ID
+        /// CourseChange
         ///// </data>
         /// <param name="msg"></param>
         /// <returns></returns>
-        //[FunctionName("Course")]
-        //public async Task StuList([ServiceBusTrigger("active-task", "course", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
-        //{
-        //   var client= _azureCosmos.GetCosmosClient();
-        //    try
-        //    {
-        //        await _dingDing.SendBotMsg($"ServiceBus,CourseChange:{msg}", GroupNames.醍摩豆服務運維群組);
-        //        var jsonMsg = JsonDocument.Parse(msg);
-        //        CourseChange courseChange=  msg.ToObject<CourseChange>();
-        //        //根据新增名单获取 新增的学生id 及timdid
-        //        (List<string> addTmdids, List<Students> addStudents)= await TriggerStuActivity.GetStuList(client,courseChange.addList,courseChange.school);
-        //        //根据新增名单获取 新增的学生id 及timdid
-        //        (List<string>delTmdids, List<Students> delStudents) = await TriggerStuActivity.GetStuList(client,courseChange.delList,courseChange.school);
-        //        foreach (var addStu in addStudents) { 
-                
-        //        }
-        //        foreach (var addTmd in addTmdids)
-        //        {
-
-        //        }
-
-        //    }
-        //    catch (Exception ex)
-        //    {
-        //        await _dingDing.SendBotMsg($"ServiceBus,Blob()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-        //    }
-        //}
-
+        [FunctionName("Course")]
+        public async Task Course([ServiceBusTrigger("active-task", "course", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
+        {
+            var client = _azureCosmos.GetCosmosClient();
+            try
+            {
+                await _dingDing.SendBotMsg($"ServiceBus,CourseChange:{msg}", GroupNames.醍摩豆服務運維群組);
+                var jsonMsg = JsonDocument.Parse(msg);
+                CourseChange courseChange = msg.ToObject<CourseChange>();
+                //根据新增名单获取 新增的学生id 及timdid
+                (List<string> addTmdids, List<Students> addStudents) = await TriggerStuActivity.GetStuList(client, courseChange.addList, courseChange.school);
+                //根据删除名单获取 新增的学生id 及timdid
+                (List<string> delTmdids, List<Students> delStudents) = await TriggerStuActivity.GetStuList(client, courseChange.delList, courseChange.school);
+                foreach (var addStu in addStudents)
+                {
+                    var course = new StuCourse
+                    {
+                        id = courseChange.id,
+                        scode = courseChange.code,
+                        name = courseChange.name,
+                        code = $"Course-{courseChange.school}-{addStu.id}",
+                        scope = courseChange.scope,
+                        school = courseChange.school,
+                        creatorId = courseChange.creatorId,
+                        pk = "Course"
+                    };
+                    await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(course, new PartitionKey(course.code));
+                }
+                foreach (var addTmd in addTmdids)
+                {
+                    var course = new StuCourse
+                    {
+                        id = courseChange.id,
+                        scode = courseChange.code,
+                        name = courseChange.name,
+                        code = $"Course-{addTmd}",
+                        scope = courseChange.scope,
+                        //school = courseChange.school,
+                        creatorId = courseChange.creatorId,
+                        pk = "Course"
+                    };
+                    await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(course, new PartitionKey(course.code));
+                }
+                foreach (var delStu in delStudents)
+                {
+                    await client.GetContainer("TEAMModelOS", "Student").DeleteItemStreamAsync(courseChange.id, new PartitionKey($"Course-{courseChange.school}-{delStu.id}"));
+                }
+                foreach (var delTmd in delTmdids)
+                {
+                    await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(courseChange.id, new PartitionKey($"Course-{delTmd}"));
+                }
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"CourseServiceBus-Course\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
+            }
+        }
     }
 }

+ 203 - 0
TEAMModelFunction/StuListServiceBus.cs

@@ -0,0 +1,203 @@
+using Azure.Cosmos;
+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;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+
+namespace TEAMModelFunction
+{
+    public class MQActivity { 
+    
+        public string id { get; set; }
+        public string code { get; set; }
+        public string owner { get; set; }
+        public List<string> classes { get; set; }
+        //如果已经完成则不写入???
+        public string progress { get; set; }
+        public string scope { get; set; }
+        public string school { get; set; }
+        public string creatorId { get; set; }
+        public string pk { get; set; }
+        public string name { get; set; }
+        public List<string> subjects { get; set; }
+        public string blob { get; set; }
+        public long startTime { get; set; }
+        public long endTime { get; set; }
+
+    }
+
+    public class StuListServiceBus
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly DingDing _dingDing;
+        public StuListServiceBus(AzureCosmosFactory azureCosmos, DingDing dingDing)
+        {
+            _azureCosmos = azureCosmos;
+            _dingDing = dingDing;
+        }
+        /// <summary>
+        /// 完善课程变更,StuListChange,  originCode是学校编码 则表示名单是学校自定义名单,如果是tmdid则表示醍摩豆的私有名单,scope=school,private。
+        /// </summary>
+        /// <data msg>
+        /// CourseChange
+        ///// </data>
+        /// <param name="msg"></param>
+        /// <returns></returns>
+        [FunctionName("StuList")]
+        public async Task StuList([ServiceBusTrigger("active-task", "stulist", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
+        {
+            var client = _azureCosmos.GetCosmosClient();
+            try
+            {
+                await _dingDing.SendBotMsg($"ServiceBus,StuList:{msg}", GroupNames.醍摩豆服務運維群組);
+                var jsonMsg = JsonDocument.Parse(msg);
+                StuListChange stuListChange = msg.ToObject<StuListChange>();
+                //名单变动修改学生课程关联信息
+                await FixStuCourse(client, stuListChange);
+                //Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
+                //名单变动修改学生问卷关联信息
+                await FixActivity(client, stuListChange, "Survey");
+                //名单变动修改学生投票关联信息
+                await FixActivity(client, stuListChange, "Vote");
+                //名单变动修改学生评测关联信息
+                await FixActivity(client, stuListChange, "Exam");
+                //TODO学习活动
+                //await FixActivity(client, stuListChange, "Learn");
+                //TODO作业活动
+                // await FixActivity(client, stuListChange, "Homework");
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"StuListServiceBus-StuList\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
+            }
+        }
+
+        public async Task FixActivity(CosmosClient client, StuListChange stuListChange, string type) {
+            var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c  join A1 in c.classes  where  c.pk='{type}' and A1 in('{stuListChange.listid}') ";
+            List<MQActivity> datas = new List<MQActivity>();
+            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<MQActivity>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{stuListChange.originCode}") }))
+            {
+                datas.Add(item);
+            }
+            foreach (MQActivity activity in datas) {
+                //已经完结的不再允许加入
+                if (activity.progress.Equals("finish")) {
+                    continue;
+                }
+                //学生新加入名单的
+                foreach (Students students in stuListChange.stujoin)
+                {
+                    var stucourse = new StuActivity
+                    {
+                        id = activity.id,
+                        scode = activity.code,
+                        name = activity.name,
+                        code = $"Activity-{activity.school}-{students.id}",
+                        scope = activity.scope,
+                        school = activity.school,
+                        creatorId = activity.creatorId,
+                        pk = "Activity",
+                        type = type,
+                        subjects = type.Equals("Exam") ? activity.subjects : new List<string>() { "" },
+                        startTime = activity.startTime,
+                        endTime = activity.endTime
+                    };
+                    await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }//tmd新加入的
+                foreach (string tmdid in stuListChange.tmdjoin)
+                {
+                    var stucourse = new StuActivity
+                    {
+                        id = activity.id,
+                        scode = activity.code,
+                        name = activity.name,
+                        code = $"Activity-{tmdid}",
+                        scope = activity.scope,
+                        school = activity.school,
+                        creatorId = activity.creatorId,
+                        pk = "Activity",
+                        type = type,
+                        subjects= type.ToLower().Equals("Exam")?activity.subjects:new List<string>() {"" }
+                    };
+                    await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }
+            }
+        }
+
+        public async Task FixStuCourse(CosmosClient client, StuListChange stuListChange) {
+            //1.查找学校或教师的课程是否包含该名单的课程。
+            var query = $"select distinct c.code,c.id,c.no,c.name,c.scope, c.creatorId,c.school from c join A0 in c.schedule where A0.stulist = '{stuListChange.listid}'";
+            List<Course> courses = new List<Course>();
+            if (stuListChange.scope.Equals("school"))
+            {
+                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{stuListChange.originCode}") }))
+                {
+                    courses.Add(item);
+                }
+            }
+            else
+            {
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query,
+                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{stuListChange.originCode}") }))
+                {
+                    courses.Add(item);
+                }
+            }
+            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
+            foreach (var course in courses)
+            {
+                //学生新加入名单的
+                foreach (Students students in stuListChange.stujoin)
+                {
+                    var stucourse = new StuCourse
+                    {
+                        id = course.id,
+                        scode = course.code,
+                        name = course.name,
+                        code = $"Course-{course.school}-{students.id}",
+                        scope = course.scope,
+                        school = course.school,
+                        creatorId = course.creatorId,
+                        pk = "Course"
+                    };
+                    await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }
+                //tmd新加入的
+                foreach (string tmdid in stuListChange.tmdjoin)
+                {
+                    var stucourse = new StuCourse
+                    {
+                        id = course.id,
+                        scode = course.code,
+                        name = course.name,
+                        code = $"Course-{tmdid}",
+                        scope = course.scope,
+                        school = course.school,
+                        creatorId = course.creatorId,
+                        pk = "Course"
+                    };
+                    await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
+                }
+                //移除名单的。 在点击相关的课程,再去二次校验是否存在,不存在则再去删除。
+                //foreach (var delStu in stuListChange.stuleave)
+                //{
+                //    await client.GetContainer("TEAMModelOS", "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"Course-{course.school}-{delStu.id}"));
+                //}
+                //foreach (var delTmd in stuListChange.tmdhleave)
+                //{
+                //    await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(course.id, new PartitionKey($"Course-{delTmd}"));
+                //}
+            }
+
+        }
+    }
+}

+ 250 - 82
TEAMModelFunction/TriggerExam.cs

@@ -18,8 +18,8 @@ namespace TEAMModelFunction
 {
     public class TriggerExam
     {
-        public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing, 
-            CosmosClient client, Document input ,string code,long stime,long etime, string school)
+        public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+            CosmosClient client, Document input, string code, long stime, long etime, string school)
         {
             ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(input.Id, new Azure.Cosmos.PartitionKey($"{code}"));
             List<ExamClassResult> examClassResults = new List<ExamClassResult>();
@@ -38,7 +38,8 @@ namespace TEAMModelFunction
                     }
                 }
             }
-            else {
+            else
+            {
                 await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{school}") }))
                 {
                     using var json = await JsonDocument.ParseAsync(item.ContentStream);
@@ -51,7 +52,7 @@ namespace TEAMModelFunction
                     }
                 }
             }
-            
+
 
             List<ChangeRecord> records = await _azureStorage.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", input.Id }, { "PartitionKey", info.progress } });
             //处理科目信息
@@ -88,7 +89,7 @@ namespace TEAMModelFunction
                         //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
                     }
                     break;
-                case "going":                    
+                case "going":
                     //ActivityData data;
                     //if (info.scope == "school")
                     //{
@@ -133,13 +134,14 @@ namespace TEAMModelFunction
                     List<StuActivity> tmdActivities = new List<StuActivity>();
                     if (tmdids.IsNotEmpty())
                     {
-                        tmdids.ForEach(x => {
+                        tmdids.ForEach(x =>
+                        {
                             tmdActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
                                 id = info.id,
                                 code = $"Activity-{x}",
-                                type = "exam",
+                                type = "Exam",
                                 name = info.name,
                                 startTime = info.startTime,
                                 endTime = info.endTime,
@@ -155,13 +157,14 @@ namespace TEAMModelFunction
                     }
                     if (studentss.IsNotEmpty())
                     {
-                        studentss.ForEach(x => {
+                        studentss.ForEach(x =>
+                        {
                             stuActivities.Add(new StuActivity
                             {
                                 pk = "Activity",
                                 id = info.id,
                                 code = $"Activity-{info.school}-{x.id}",
-                                type = "exam",
+                                type = "Exam",
                                 name = info.name,
                                 startTime = info.startTime,
                                 endTime = info.endTime,
@@ -183,11 +186,12 @@ namespace TEAMModelFunction
                             foreach (ExamSubject subject in info.subjects)
                             {
                                 string classCode = "";
-                                if (string.IsNullOrEmpty(info.school) || !info.scope.Equals("school",StringComparison.OrdinalIgnoreCase))
+                                if (string.IsNullOrEmpty(info.school) || !info.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
                                 {
                                     classCode = "ExamClassResult-" + info.creatorId;
                                 }
-                                else {
+                                else
+                                {
                                     classCode = "ExamClassResult-" + info.school;
                                 }
                                 ExamClassResult result = new ExamClassResult
@@ -201,11 +205,13 @@ namespace TEAMModelFunction
                                 };
                                 result.info.id = cla;
                                 List<string> ans = new List<string>();
+                                List<List<string>> anses = new List<List<string>>();
                                 List<double> ansPoint = new List<double>();
                                 List<string> ids = new List<string>();
                                 foreach (double p in info.papers[m].point)
                                 {
                                     //ans.Add(new List<string>());
+                                    anses.Add(new List<string>());
                                     ansPoint.Add(-1);
                                 }
                                 var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"Class-{info.school}"));
@@ -232,9 +238,10 @@ namespace TEAMModelFunction
                                     }
                                 }
                                 if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
-                                {                                                                                                        
+                                {
                                     var stuResponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList"));
-                                    if (stuResponse.Status == 200) {
+                                    if (stuResponse.Status == 200)
+                                    {
                                         using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
                                         StuList stuList = json.ToObject<StuList>();
                                         //result.info.id = stuList.id;
@@ -242,20 +249,21 @@ namespace TEAMModelFunction
                                         //处理发布对象为自选名单(个人)
 
                                         foreach (Students stus in stuList.students)
-                                                {
+                                        {
 
-                                                        ids.Add(stus.id);
-                                                }
-                                                if (stuList.tmids.Count > 0)
-                                                {
-                                                    foreach (string tid in stuList.tmids)
-                                                    {
-                                                        ids.Add(tid);
-                                                    }
-                                                }
-                                    }                                   
+                                            ids.Add(stus.id);
+                                        }
+                                        if (stuList.tmids.Count > 0)
+                                        {
+                                            foreach (string tid in stuList.tmids)
+                                            {
+                                                ids.Add(tid);
+                                            }
+                                        }
+                                    }
                                 }
-                                else {                                                                                                                                                                                                                       
+                                else
+                                {
                                     var stuResponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList-{info.school}"));
                                     if (stuResponse.Status == 200)
                                     {
@@ -266,9 +274,9 @@ namespace TEAMModelFunction
                                         //处理发布对象为自选名单(校本)
                                         foreach (Students stus in stuList.students)
                                         {
-                                                ids.Add(stus.id);
-                                        }                                      
-                                    }                                    
+                                            ids.Add(stus.id);
+                                        }
+                                    }
                                 }
                                 foreach (string stu in ids)
                                 {
@@ -276,9 +284,10 @@ namespace TEAMModelFunction
                                     result.studentIds.Add(stu);
                                     result.studentAnswers.Add(ans);
                                     result.studentScores.Add(ansPoint);
+                                    result.ans.Add(anses);
                                     result.sum.Add(0);
                                 }
-                                
+
                                 //result.progress = info.progress;
                                 result.school = info.school;
                                 m++;
@@ -318,7 +327,7 @@ namespace TEAMModelFunction
                         {
                             if (subject.classCount == info.classes.Count)
                             {
-                                await createClassResultAsync(info, examClassResults, subject, gno,_azureCosmos, _dingDing, _azureStorage);
+                                await createClassResultAsync(info, examClassResults, subject, gno, _azureCosmos, _dingDing, _azureStorage);
                             }
                             gno++;
                         }
@@ -328,10 +337,10 @@ namespace TEAMModelFunction
                     int fno = 0;
                     foreach (ExamSubject subject in info.subjects)
                     {
-                        await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos, _dingDing, _azureStorage);                       
+                        await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos, _dingDing, _azureStorage);
                         fno++;
                     }
-                    
+
                     //计算单次考试简易统计信息
                     List<ExamResult> examResults = new List<ExamResult>();
                     await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
@@ -340,7 +349,8 @@ namespace TEAMModelFunction
                         examResults.Add(item);
                     }
                     //结算单科单班的标准差和平均分
-                    foreach (ExamClassResult classResult in examClassResults) {
+                    foreach (ExamClassResult classResult in examClassResults)
+                    {
                         //标记单科单班总得分
                         double subScore = 0;
                         //标准差
@@ -370,7 +380,8 @@ namespace TEAMModelFunction
                     double powSum = 0;
                     List<string> losStu = new List<string>();
                     //先与第一个值取并集
-                    if (examResults.Count >0 ) {
+                    if (examResults.Count > 0)
+                    {
                         losStu.Union(examResults[0].lostStus);
                         foreach (ExamResult examResult in examResults)
                         {
@@ -393,79 +404,226 @@ namespace TEAMModelFunction
                         allScore += simple.point.Sum();
                     }
                     //计算全科标准差
-                    foreach (string id in examResults[0].studentIds) {
+                    foreach (string id in examResults[0].studentIds)
+                    {
                         double sc = 0;
-                        foreach (ExamResult result in examResults) {
+                        foreach (ExamResult result in examResults)
+                        {
                             sc += result.studentScores[result.studentIds.IndexOf(id)].Sum();
                         }
-                        powSum += Math.Pow(sc - NewsRateScore , 2);
+                        powSum += Math.Pow(sc - NewsRateScore, 2);
                     }
-                    info.standard = Math.Round(examResults[0].studentIds.Count > 0 ? Math.Pow(powSum / examResults[0].studentIds.Count, 0.5) : 0,2);
-                    double  NewsRate= allScore > 0 ? Math.Round(NewsRateScore / allScore * 100,2) : 0;
+                    info.standard = Math.Round(examResults[0].studentIds.Count > 0 ? Math.Pow(powSum / examResults[0].studentIds.Count, 0.5) : 0, 2);
+                    double NewsRate = allScore > 0 ? Math.Round(NewsRateScore / allScore * 100, 2) : 0;
                     info.lostStu = losStu;
                     //判断均分是否发生变化,便于实时的更新评测基本信息
-                    if (info.sRate != NewsRate || info.average != NewsRateScore) {
+                    if (info.sRate != NewsRate || info.average != NewsRateScore)
+                    {
                         info.sRate = NewsRate;
                         info.average = NewsRateScore;
                         await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamInfo>(info, info.id, new Azure.Cosmos.PartitionKey(info.code));
-                    }         
+                    }
                     break;
             }
         }
-        public static async Task examRecordCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no,AzureStorageFactory _azureStorage,ExamResult result) {
+        //处理全部学生选题计数
+        public static async Task examRecordCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, ExamResult result, List<ExamClassResult> classResults, AzureCosmosFactory _azureCosmos)
+        {
             try
             {
-                string blobcntr = "";
-                if (info.scope.Equals("school"))
+                List<double> scores = new List<double>();
+                foreach (List<double> sc in result.studentScores)
+                {
+                    scores.Add(sc.Sum());
+                }
+                //确定高分组 最低分数
+                scores.Sort((s1, s2) => { return s2.CompareTo(s1); });
+                double rhwCount = Math.Floor(scores.Count * 0.27);
+                double rhw = rhwCount > 0 ? scores[int.Parse(rhwCount.ToString("0"))] : 0;
+                //确定低分组 最高分数
+                //scores.Sort((s1, s2) => { return s1.CompareTo(s2); });
+                double rhlCount = Math.Ceiling(scores.Count * 0.73);
+                double rhl = rhlCount > 0 ? scores[int.Parse(rhlCount.ToString("0"))] : 0;
+                //存放高分组学生ID
+                List<string> phId = 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>>> optl = new List<List<List<string>>>();
+                //存放并去重知识点
+                HashSet<string> kname = new HashSet<string>();
+                info.papers[no].knowledge.ForEach(kno =>
                 {
-                    blobcntr = info.school;
+                    kno.ForEach(k =>
+                    {
+                        kname.Add(k);
+                    });
+                });
+                List<string> knowledgeName = new List<string>();
+                foreach (string cla in kname)
+                {
+                    knowledgeName.Add(cla);
+                }
+                for (int k = 0; k < knowledgeName.Count; k++)
+                {
+                    if (null == knowledgeName[k])
+                    {
+                        knowledgeName.Remove(knowledgeName[k]);
+                    }
                 }
-                else {
-                    blobcntr = info.creatorId;
+
+                foreach (ExamClassResult classResult in classResults)
+                {
+                    if (classResult.subjectId.Equals(subject.id)) {
+                        //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++)
+                        {
+                            //初始化单个知识点得分
+                            double score = 0;
+                            double allScore = 0;
+                            int n = 0;
+                            int phCount = 0;
+                            int plCount = 0;
+                            int pCount = 0;
+                            foreach (List<string> str in info.papers[no].knowledge)
+                            {
+                                if (str.Contains(knowledgeName[i]))
+                                {
+                                    var itemPersent = str.Count > 0 ? 1 / Convert.ToDouble(str.Count) : 0;
+                                    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 < (scores.Count - 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(per / allScore);
+                        }
+                        classResult.phc = ph;
+                        classResult.plc = pl;
+                        classResult.pc = pc;
+                        classResult.krate = persent;
+                    }                    
+                    await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                 }
-                var ContainerClient = _azureStorage.GetBlobContainerClient(blobcntr);
-                List<string> items = await ContainerClient.List($"exam/{info.id}/{subject.id}");
-                List<List<List<string>>> ansList = new List<List<List<string>>>();
-                foreach (string item in items)
+                //
+                int PHCount = 0;
+                int PLCount = 0;
+                foreach (ExamClassResult classResult in classResults)
                 {
-                    var Download = await _azureStorage.GetBlobContainerClient(blobcntr).GetBlobClient(item).DownloadAsync();
-                    var json = await JsonDocument.ParseAsync(Download.Value.Content);
-                    var Record = json.RootElement.ToObject<List<List<string>>>();
-                    ansList.Add(Record);
+                    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;
+                                }
+                            }
+                        }
+                    }
                 }
-                /*foreach (List<string> str in info.papers[no].answers) { 
-                    
-                }*/
-                List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
-                for (int i = 0;i< info.papers[no].answers.Count;i++) {
-                    if (info.papers[no].answers[i].Count <= 0) {
+                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 List<Dictionary<string, int>> getMore(ExamInfo info, int no, List<List<List<string>>> list)
+        {
+            List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
+            try
+            {
+                for (int i = 0; i < info.papers[no].answers.Count; i++)
+                {
+                    if (info.papers[no].answers[i].Count <= 0)
+                    {
                         recorde.Add(new Dictionary<string, int>());
                         continue;
                     }
                     Dictionary<string, int> optCount = new Dictionary<string, int>();
-                    foreach (List<List<string>> stu in ansList) {
-                        if (stu.Count == info.papers[no].answers.Count) {
+                    foreach (List<List<string>> stu in list)
+                    {
+                        if (stu.Count == info.papers[no].answers.Count)
+                        {
 
                             var item = stu[i];
-                            foreach (string opt in item) {
+                            foreach (string opt in item)
+                            {
                                 if (optCount.ContainsKey(opt))
                                 {
                                     optCount[opt] = optCount[opt] + 1;
                                 }
-                                else { 
-                                    optCount[opt] = 1; 
+                                else
+                                {
+                                    optCount[opt] = 1;
                                 }
                             }
-                          
+
                         }
                     }
                     recorde.Add(optCount);
                 }
-                result.record = recorde;
+                return recorde;
             }
-            catch (Exception ex)
+            catch (Exception)
             {
-                await _dingDing.SendBotMsg($"评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                return recorde;
             }
         }
         public static async Task createClassResultAsync(ExamInfo info, List<ExamClassResult> examClassResults, ExamSubject subject, int no, AzureCosmosFactory _azureCosmos, DingDing _dingDing, AzureStorageFactory _azureStorage)
@@ -482,24 +640,32 @@ namespace TEAMModelFunction
             List<ClassRange> classRanges = new List<ClassRange>();
             List<string> lostStu = new List<string>();
             List<double> csRate = new List<double>();
+            List<List<List<string>>> opt = new List<List<List<string>>>();
             foreach (ExamClassResult classResult in examClassResults)
             {
                 double classSrate = 0;
                 if (classResult.subjectId.Equals(subject.id))
                 {
+                    foreach (List<List<string>> op in classResult.ans)
+                    {
+                        opt.Add(op);
+                    }
                     //记录缺考学生索引位置
                     int index = 0;
                     foreach (List<double> scores in classResult.studentScores)
                     {
                         List<double> newScores = new List<double>();
                         int count = 0;
-                        foreach (double sc in scores) {
+                        foreach (double sc in scores)
+                        {
                             newScores.Add(sc > -1 ? sc : 0);
-                            if(sc == -1) {
+                            if (sc == -1)
+                            {
                                 count++;
                             }
                         }
-                        if (count == scores.Count) {
+                        if (count == scores.Count)
+                        {
                             lostStu.Add(classResult.studentIds[index]);
                             //mcount++;
                         }
@@ -537,28 +703,30 @@ namespace TEAMModelFunction
                     }
                     csRate.Add(result.studentIds.Count > 0 ? Math.Round(classSrate * 1.0 / classResult.studentIds.Count, 2) : 0 / allScore);
                     //powSum += Math.Pow(classSrate - result.average, 2);
+                    //处理选项计数内容
                 }
             }
+            await examRecordCount(info, subject, _dingDing, no, result, examClassResults, _azureCosmos);
+            result.record = getMore(info, no, opt);
             result.average = result.studentIds.Count > 0 ? Math.Round(score * 1.0 / result.studentIds.Count, 2) : 0;
-            foreach (ExamClassResult classResult in examClassResults) {
+            foreach (ExamClassResult classResult in examClassResults)
+            {
 
                 //double classSrate = 0;
                 if (classResult.subjectId.Equals(subject.id))
                 {
                     foreach (string id in classResult.studentIds)
                     {
-                         double sc =  classResult.studentScores[classResult.studentIds.IndexOf(id)].Sum();
-                         powSum += Math.Pow(sc - result.average, 2);
+                        double sc = classResult.studentScores[classResult.studentIds.IndexOf(id)].Sum();
+                        powSum += Math.Pow(sc - result.average, 2);
                     }
                 }
-                             
+
             }
-            //处理选项计数内容
-            await examRecordCount(info, subject, _dingDing, no, _azureStorage, result);
-            result.standard = Math.Round(result.studentIds.Count > 0 ? Math.Pow(powSum / result.studentIds.Count, 0.5) : 0,2);
+            result.standard = Math.Round(result.studentIds.Count > 0 ? Math.Pow(powSum / result.studentIds.Count, 0.5) : 0, 2);
             result.csRate = csRate;
-            result.lostStus = lostStu;           
-            
+            result.lostStus = lostStu;
+
             result.sRate = Math.Round(result.average / allScore * 100, 2);
             result.classes = classRanges;
             result.code = "ExamResult-" + info.id;

+ 1 - 1
TEAMModelFunction/TriggerStuActivity.cs

@@ -37,7 +37,7 @@ namespace TEAMModelFunction
         }
          
         public  static async Task<(List<string> tmdids,List<Students> studentss)> GetStuList(  CosmosClient client, List<string> classes,string  school) {
-
+            if (!classes.IsNotEmpty()) { return (null, null); }
             List<Students> studentss = new List<Students>();
             List<string> sqlList = new List<string>();
             classes.ForEach(x => { sqlList.Add($" '{x}' "); });

+ 2 - 2
TEAMModelFunction/TriggerSurvey.cs

@@ -133,7 +133,7 @@ namespace TEAMModelFunction
                                     pk = "Activity",
                                     id = survey.id,
                                     code = $"Activity-{x}",
-                                    type = "survey",
+                                    type = "Survey",
                                     name = survey.name,
                                     startTime = survey.startTime,
                                     endTime = survey.endTime,
@@ -153,7 +153,7 @@ namespace TEAMModelFunction
                                     pk = "Activity",
                                     id = survey.id,
                                     code = $"Activity-{survey.school}-{x.id}",
-                                    type = "survey",
+                                    type = "Survey",
                                     name = survey.name,
                                     startTime = survey.startTime,
                                     endTime = survey.endTime,

+ 2 - 2
TEAMModelFunction/TriggerVote.cs

@@ -140,7 +140,7 @@ namespace TEAMModelFunction
                                     pk = "Activity",
                                     id = vote.id,
                                     code = $"Activity-{x}",
-                                    type = "vote",
+                                    type = "Vote",
                                     name = vote.name,
                                     startTime = vote.startTime,
                                     endTime = vote.endTime,
@@ -161,7 +161,7 @@ namespace TEAMModelFunction
                                     pk = "Activity",
                                     id = vote.id,
                                     code = $"Activity-{vote.school}-{x.id}",
-                                    type = "vote",
+                                    type = "Vote",
                                     name = vote.name,
                                     startTime = vote.startTime,
                                     endTime = vote.endTime,

+ 12 - 5
TEAMModelOS.SDK/Models/Cosmos/Common/ExamClassResult.cs

@@ -6,8 +6,8 @@ using TEAMModelOS.SDK.Context.Attributes.Azure;
 using TEAMModelOS.SDK.DI;
 
 namespace TEAMModelOS.SDK.Models
-{    
-    public class ExamClassResult :CosmosEntity
+{
+    public class ExamClassResult : CosmosEntity
     {
         public ExamClassResult() {
             pk = "ExamClassResult";
@@ -18,6 +18,7 @@ namespace TEAMModelOS.SDK.Models
             studentScores = new List<List<double>>();
             sum = new List<double>();
             mark = new List<string>();
+            ans = new List<List<List<string>>>();
         }
         public string school { get; set; }
         public string examId { get; set; }
@@ -30,16 +31,22 @@ namespace TEAMModelOS.SDK.Models
         //public List<double> point { get; set; }
         public List<string> studentIds { get; set; }
         public List<List<string>> studentAnswers { get; set; }
+        //记录学生客观题选项内容,便于学情分析
+        public List<List<List<string>>> ans { get; set; }
         public List<List<double>> studentScores { get; set; }
-        //蠶蛁
+        //批注
         public List<string> mark { get; set; }
         public string scope { get; set; }
         public List<double> sum { get; set; }
         public double average { get; set; }
-        //等褪等啤腕煦薹
+        //单科单班得分率
         public double srate { get; set; }
-        //等褪等啤梓袧船
+        //单科单班标准差
         public double standard { 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 class PaperSimple {
         public string id { get; set; }

+ 0 - 34
TEAMModelOS.SDK/Models/Cosmos/Common/Inner/ClassChange.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Models.Cosmos.Common.Inner
-{
-    /// <summary>
-    /// 学生名单变动
-    /// </summary>
-    public class ClassChange
-    {
-        /// <summary>
-        /// 教师名单加入的
-        /// </summary>
-        public List<string> tchjoin { get; set; } = new List<string>();
-        /// <summary>
-        /// 教师名单离开的
-        /// </summary>
-        public List<string> tchleave { get; set; } = new List<string>();
-        /// <summary>
-        /// 学校名单加入的
-        /// </summary>
-        public List<string> schjoin { get; set; } = new List<string>();
-        /// <summary>
-        /// 学校名单离开的
-        /// </summary>
-        public List<string> schleave { get; set; } = new List<string>();
-        public string listid { get; set; }
-        /// <summary>
-        /// 分区
-        /// </summary>
-        public string scope { get; set; }
-    }
-}

TEAMModelOS.SDK/Models/Cosmos/Common/CourseChange.cs → TEAMModelOS.SDK/Models/Cosmos/Common/Inner/CourseChange.cs


+ 32 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/Inner/StuListChange.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Models.Cosmos.Common
+{
+    public class StuListChange
+    {
+        /// <summary>
+        /// 教师名单加入的成员
+        /// </summary>
+        public List<string> tmdjoin { get; set; } = new List<string>();
+        /// <summary>
+        /// 教师名单离开的成员
+        /// </summary>
+        public List<string> tmdhleave { get; set; } = new List<string>();
+        /// <summary>
+        /// 学校学生名单加入的成员
+        /// </summary>
+        public List<Students> stujoin { get; set; } = new List<Students>();
+        /// <summary>
+        /// 学校学生名单离开的成员
+        /// </summary>
+        public List<Students> stuleave { get; set; } = new List<Students>();
+        public string listid { get; set; }
+        /// <summary>
+        /// 分区
+        /// </summary>
+        public string scope { get; set; }
+        public string originCode { get; set; }
+    }
+}

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

@@ -9,7 +9,7 @@ namespace TEAMModelOS.SDK.Models.Cosmos.Common
         /// <summary>
         /// 课程的分区键课程Code
         /// </summary>
-        public string scode { get; set; } = "Course";
+        public string scode { get; set; } 
         public string name { get; set; }
         public  string scope { get; set; }
         public string school { get; set; }

+ 2 - 0
TEAMModelOS.SDK/Models/Cosmos/School/ExamResult.cs

@@ -42,6 +42,8 @@ namespace TEAMModelOS.SDK.Models
         public List<string> lostStus { get; set; } = new List<string>();
         public double standard { get; set; }
         public List<Dictionary<string, int>> record { get; set; } = new List<Dictionary<string, int>>();
+        public List<Dictionary<string, int>> phc { get; set; } = new List<Dictionary<string, int>>();
+        public List<Dictionary<string, int>> plc { get; set; } = new List<Dictionary<string, int>>();
     }
     public class ClassRange {
 

+ 56 - 54
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -18,7 +18,7 @@
             <Menu width="auto" :class="menuitemClasses" accordion :active-name="activeName" :open-names="openNames">
                 <vuescroll :ops="ops">
                     <div v-for="(item,index) in menuTree" :key="index">
-                        <Submenu :name="index" v-if="$access.ability(item.role,item.permission).validateAll && item.child.length" v-show="(index == 0 && $store.state.userInfo.hasSchool) || index > 0">
+                        <Submenu :name="item.subName" v-if="$access.ability(item.role,item.permission).validateAll && item.child.length" v-show="(index == 0 && $store.state.userInfo.hasSchool) || index > 0">
                             <template slot="title">
                                 <Tooltip :content="item.name" placement="right" transfer v-show="isCollapsed">
                                     <Icon :custom="item.icon" style="width:55px;text-align:left;" :class="isCollapsed ? 'collapse-icon-size':''" size="20" />
@@ -26,7 +26,7 @@
                                 <Icon v-show="!isCollapsed" :custom="item.icon" :class="isCollapsed ? 'collapse-icon-size':''" size="20" />
                                 <span>{{item.name}}</span>
                             </template>
-                            <MenuItem class="sub-item-wrap sub-item-wrap-active" :name="menuItem.router" :to="menuItem.router" v-for="(menuItem,i) in item.child" :key="i" v-if="$access.ability(menuItem.role,menuItem.permission).validateAll">
+                            <MenuItem class="sub-item-wrap sub-item-wrap-active" :name="menuItem.menuName" :to="menuItem.router" v-for="(menuItem,i) in item.child" :key="i" v-if="$access.ability(menuItem.role,menuItem.permission).validateAll">
                             <Tooltip :content="menuItem.name" placement="right" transfer v-show="isCollapsed">
                                 <Icon class="sub-menu-icon" :custom="menuItem.icon" size="18" />
                             </Tooltip>
@@ -39,7 +39,7 @@
                             </span>
                             </MenuItem>
                         </Submenu>
-                        <MenuItem :name="item.router" v-else-if="$access.ability(item.role,item.permission).validateAll" :to="item.router">
+                        <MenuItem :name="item.menuName" v-else-if="$access.ability(item.role,item.permission).validateAll" :to="item.router">
                         <Tooltip :content="item.name" placement="right" transfer v-show="isCollapsed">
                             <Icon :custom="item.icon" style="width:55px;text-align:left;" :class="isCollapsed ? 'collapse-icon-size':''" size="22" />
                         </Tooltip>
@@ -73,12 +73,13 @@ export default {
         }
     },
     methods: {
-        initMenu(){
+        initMenu() {
             this.menuTree = [
                 {
                     icon: 'iconfont icon-school',
                     name: this.$t('system.menu.smartSc'),
                     router: '',
+                    subName: 'smartSchool',
                     role: 'teacher|admin',
                     permission: '',
                     child: [
@@ -88,7 +89,8 @@ export default {
                             router: '/home/system',
                             tag: '',
                             role: 'admin',
-                            permission: 'schoolSetting-read|schoolSetting-upd'
+                            permission: 'schoolSetting-read|schoolSetting-upd',
+                            menuName: 'system'
                         },
                         {
                             icon: 'iconfont icon-teacher-mgt',
@@ -96,7 +98,8 @@ export default {
                             router: '/home/teachermgmt',
                             tag: '',
                             role: 'admin',
-                            permission: 'teacher-read|teacher-upd'
+                            permission: 'teacher-read|teacher-upd',
+                            menuName: 'teachermgmt'
                         },
                         {
                             icon: 'iconfont icon-student-mgt',
@@ -104,7 +107,8 @@ export default {
                             router: '/home/studentAccount',
                             tag: '',
                             role: 'admin',
-                            permission: 'student-upd|student-read'
+                            permission: 'student-upd|student-read',
+                            menuName: 'studentAccount'
                         },
                         {
                             icon: 'iconfont icon-class-mgt',
@@ -112,17 +116,9 @@ export default {
                             router: '/home/classroom',
                             tag: '',
                             role: 'admin',
-                            permission: 'classroom-upd|classroom-read'
+                            permission: 'classroom-upd|classroom-read',
+                            menuName: 'classroom'
                         },
-                        //课程设置
-                        // {
-                        //     icon: 'iconfont icon-kecheng',
-                        //     name: this.$t('system.menu.cusSetting'),
-                        //     router: '/home/ManageCourse',
-                        //     tag: 'x',
-                        //     role: 'admin',
-                        //     permission: 'course-read|course-upd',
-                        // },
                         {
                             icon: 'iconfont icon-kecheng',
                             name: this.$t('system.menu.cusMgt'),
@@ -130,6 +126,7 @@ export default {
                             tag: '',
                             role: 'admin',
                             permission: '',
+                            menuName: 'NewCusMgt'
                         },
                         //{
                         //   icon: 'iconfont icon-time',
@@ -154,7 +151,8 @@ export default {
                             router: '/home/serviceDriveAuth',
                             tag: this.$t('system.menu.preview'),
                             role: 'admin',
-                            permission: 'auth-read|auth-upd'
+                            permission: 'auth-read|auth-upd',
+                            menuName: 'serviceDriveAuth'
                         },
                         {
                             icon: 'iconfont icon-syllabus',
@@ -163,6 +161,7 @@ export default {
                             tag: this.$t('system.menu.preview'),
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'syllabus'
                         },
                         {
                             icon: 'iconfont icon-file',
@@ -171,6 +170,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'schoolcontent'
                         },
                         {
                             icon: 'iconfont icon-question-bank',
@@ -179,6 +179,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'schoolBank'
                         },
                         {
                             icon: 'iconfont icon-k-point',
@@ -187,6 +188,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'knowledge'
                         }
                     ]
                 },
@@ -195,6 +197,7 @@ export default {
                     name: this.$t('system.menu.staAna'),
                     router: '',
                     role: 'admin',
+                    subName: 'analysis',
                     permission: 'analysis-read|scboard-read',
                     child: [
                         {
@@ -203,7 +206,8 @@ export default {
                             router: '/totalIndex',
                             tag: '',
                             role: 'admin',
-                            permission: 'analysis-read'
+                            permission: 'analysis-read',
+                            menuName: 'totalIndex'
                         },
                         {
                             icon: 'iconfont icon-school-analysis',
@@ -211,7 +215,8 @@ export default {
                             router: '/home/scboard',
                             tag: this.$t('system.menu.preview'),
                             role: 'admin',
-                            permission: 'scboard-read'
+                            permission: 'scboard-read',
+                            menuName: 'scboard'
                         }
                     ]
                 },
@@ -223,6 +228,7 @@ export default {
                     // permission: 'schoolAc-read|schoolAc-upd',
                     role: 'admin',
                     permission: '',
+                    subName:'scAc',
                     child: [
                         {
                             icon: 'iconfont icon-test',
@@ -230,7 +236,8 @@ export default {
                             router: '/home/schoolEvaluation',
                             tag: '',
                             role: 'admin',
-                            permission: ''
+                            permission: '',
+                            menuName: 'schoolEvaluation'
                         },
                         {
                             icon: 'iconfont icon-vote',
@@ -238,7 +245,8 @@ export default {
                             router: '/home/manageVote',
                             tag: '',
                             role: 'admin',
-                            permission: ''
+                            permission: '',
+                            menuName: 'manageVote'
                         },
                         {
                             icon: 'iconfont icon-questionnaire',
@@ -246,7 +254,8 @@ export default {
                             router: '/home/manageQuestionnaire',
                             tag: '',
                             role: 'admin',
-                            permission: ''
+                            permission: '',
+                            menuName: 'manageQuestionnaire'
                         },
                     ]
                 },
@@ -256,6 +265,7 @@ export default {
                     router: '',
                     role: 'teacher',
                     permission: '',
+                    subName:'cusContent',
                     child: [
                         {
                             icon: 'iconfont icon-syllabus',
@@ -264,6 +274,7 @@ export default {
                             tag: this.$t('system.menu.preview'),
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'personalSyllabus'
                         },
                         {
                             icon: 'iconfont icon-file',
@@ -272,6 +283,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'personalcontent'
                         },
                         {
                             icon: 'iconfont icon-question-bank',
@@ -280,6 +292,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'personalBank'
                         }
                     ]
                 },
@@ -289,6 +302,7 @@ export default {
                     router: '',
                     role: 'teacher|admin',
                     permission: '',
+                    subName:'stuAc',
                     child: [
                         {
                             icon: 'iconfont icon-test',
@@ -297,6 +311,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'privateEvaluation'
                         },
                         {
                             icon: 'iconfont icon-vote',
@@ -305,6 +320,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'personalVote'
                         },
                         {
                             icon: 'iconfont icon-questionnaire',
@@ -313,6 +329,7 @@ export default {
                             tag: '',
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'personalSurvey'
                         },
                         {
                             icon: 'iconfont icon-learning-self',
@@ -321,6 +338,7 @@ export default {
                             tag: this.$t('system.menu.preview'),
                             role: 'teacher|admin',
                             permission: '',
+                            menuName: 'selfLearn'
                         },
                         {
                             icon: 'iconfont icon-hw',
@@ -329,15 +347,8 @@ export default {
                             tag: this.$t('system.menu.preview'),
                             role: 'teacher|admin',
                             permission: '',
-                        },
-                        // {
-                        //     icon: 'iconfont icon-syllabus',
-                        //     name: this.$t('system.menu.acRecord'),
-                        //     router: '/home/manageRecord',
-                        //     tag: this.$t('system.menu.preview'),
-                        //     role: 'teacher|admin',
-                        //     permission: '',
-                        // }
+                            menuName: 'manageHomeWork'
+                        }
                     ]
                 },
                 {
@@ -347,7 +358,8 @@ export default {
                     tag: '',
                     role: 'teacher',
                     permission: '',
-                    child: []
+                    child: [],
+                    menuName: 'manageClass'
                 },
                 {
                     icon: 'iconfont icon-course-self',
@@ -356,7 +368,8 @@ export default {
                     tag: '',
                     role: 'teacher',
                     permission: '',
-                    child: []
+                    child: [],
+                    menuName: 'myCourse'
                 }
             ]
         },
@@ -386,34 +399,23 @@ export default {
     watch: {
         $route: {
             handler(val, oldval) {
-                if(this.menuTree.length == 0){
+                if (this.menuTree.length == 0) {
                     this.initMenu()
                 }
+                console.log(val)
+                let metaName = val.meta.activeName
+                this.activeName = metaName
                 this.openNames = []
-                let flag = false
                 for (let i in this.menuTree) {
-                    if (this.menuTree[i].router == val.path) {
-                        this.activeName = val.path
-                        this.openNames.push(parseInt(i))
-                        flag = true
-                        break
-                    } else {
+                    if (this.menuTree[i].child.length) {
                         for (let j in this.menuTree[i].child) {
-                            if (this.menuTree[i].child[j].router == val.path) {
-                                this.activeName = val.path
-                                this.openNames.push(parseInt(i))
-                                flag = true
+                            if (this.menuTree[i].child[j].menuName == metaName) {
+                                this.activeName = metaName
+                                this.openNames.push(this.menuTree[i].subName)
                                 break
                             }
                         }
                     }
-                    if (flag) {
-                        break
-                    }
-                }
-                if (!flag) {
-                    this.activeName = ''
-                    this.openNames = []
                 }
             },
             // 深度观察监听
@@ -421,7 +423,7 @@ export default {
             //立即执行
             immediate: true
         },
-        '$i18n.locale'(n,o) {
+        '$i18n.locale'(n, o) {
             this.initMenu()
         }
     }

+ 16 - 43
TEAMModelOS/ClientApp/src/components/evaluation/AnalysisItemTable.vue

@@ -10,9 +10,9 @@
 <script>
 	export default {
 		props: {
-			tableDatas: {
-				type: Array,
-				default: () => []
+			analysisJson: {
+				type: Object,
+				default: () => {}
 			},
 
 		},
@@ -38,7 +38,10 @@
 					{
 						title: '难易度',
 						key: 'diff',
-						align: 'center'
+						align: 'center',
+						render: function(h, params) {
+							return h('span', (Number(params.row.diff)).toFixed(2))
+						}
 					},
 					{
 						title: '鉴别度',
@@ -121,52 +124,22 @@
 			}
 		},
 		created() {
-			this.tableData = [{
-				"id": "1",
-				"type": "",
-				"areaName": "A",
-				"score": "3",
-				"diff": "0.775",
-				"identify": " 0.44999999999999996",
-				"classScoreRate": "-",
-				"gradeScoreRate": "hbcn0906:92.68,hbcn0910:90,hbcn0909:84.21,hbcn0907:87.18,hbcn0902:89.47,hbcn0908:87.8,hbcn0901:80.56,hbcn0904:89.47,hbcn0911:85.37,hbcn0912:79.49,hbcn0903:85.37,hbcn0905:87.8",
-				"highScoreRate": "-",
-				"lowScoreRate": "-",
-				"knowledgePoint": "-",
-				"R1": " 1",
-				"R2": " 1",
-				"R3": " 0.98",
-				"R4": " 0.85",
-				"R5": " 0.65",
-				"R6": " 0.35",
-				"PH": " 0.99",
-				"PL": " 0.53",
-				"X": "0.231",
-				"Y": "0.83",
-				"knowledge": "字音",
-				"examScoreRate": "83.33",
-			}]
-
-
+			
 		},
 		methods: {
 
-
 		},
-
 		mounted() {
-
-		},
-
-		computed: {
-			exportTableRefs() {
-				return this.$store.state.totalAnalysis.exportTableRefs
-			}
+			
 		},
-
 		watch: {
-
-
+			analysisJson:{
+				handler(n,o){
+					this.tableData = [n]
+				},
+				immediate:true,
+				deep:true
+			},
 		}
 
 	}

+ 4 - 4
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.less

@@ -109,14 +109,14 @@
 .ev-content {
   background: none;
 }
-.content-wrap {
+.cp-content-wrap {
   position: relative;
   width: 100%;
   height: auto;
   display: flex;
   flex-direction: column;
   padding: 15px;
-  .exercise-item {
+  .cp-exercise-item {
     position: relative;
     width: 100%;
     height: auto;
@@ -133,7 +133,7 @@
     }
   }
 }
-.content-wrap .exercise-item table, .content-wrap .exercise-item td {
+.cp-content-wrap .cp-exercise-item table, .cp-content-wrap .cp-exercise-item td {
   border: 1px solid rgb(128, 128, 128);
   border-collapse: collapse;
   text-align: center;
@@ -144,7 +144,7 @@
   padding: 0 45px;
   border-bottom: 2px solid rgb(128, 128, 128);
 }
-.exercise-item {
+.cp-exercise-item {
   .item-question {
     position: relative;
     cursor: pointer;

+ 87 - 27
TEAMModelOS/ClientApp/src/components/evaluation/ExerciseList.vue

@@ -7,8 +7,8 @@
 			<img src="@/assets/icon/no_data_evaluation.png" width="120" />
 			<span style="margin-top: 15px; color: #808080">{{$t('evaluation.noData')}}</span>
 		</div>
-		<div class="content-wrap" ref="mathJaxContainer" v-else>
-			<div class="exercise-item" v-for="(item, index) of exerciseList" :key="index" @click="onQuestionToggle(index, item.id, $event)">
+		<div class="cp-content-wrap" ref="mathJaxContainer" v-else>
+			<div class="cp-exercise-item" v-for="(item, index) of exerciseList" :key="index" @click="onQuestionToggle(index, item.id, $event)">
 				<!-- 题干部分 -->
 				<div class="item-question">
 					<div>
@@ -25,16 +25,17 @@
 				<div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options">
 					<div class="item-option-content">
 						<div class="item-option-order">
-							{{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} :
+							<!-- {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} : -->
+							{{ option.code }} :
 						</div>
 						<div class="item-option-text" v-html="option.value"></div>
 					</div>
 				</div>
 				<div class="exercise-item-children" v-if="item.children.length">
-					<BaseChild :children="item.children" :isShowAnalysis="isShowAnalysis"></BaseChild>
+					<BaseChild :children="item.children" :isShowAnalysis="isShowAnalysis" :analysisJson="getChildAnalysisJson(item)" :optionRate="getChildOptionRate(item)"></BaseChild>
 				</div>
 				<transition name="slide" v-if="item.type !== 'compose'">
-					<div v-show="collapseList.indexOf(exerciseList.indexOf(item)) > -1" class="toggle-area">
+					<div v-if="collapseList.includes(exerciseList.indexOf(item))" class="toggle-area">
 						<div>
 							<!-- 答案展示部分 -->
 							<div class="item-explain">
@@ -67,7 +68,7 @@
 								<div class="item-explain-details">
 									<span v-if="!item.knowledge || !item.knowledge.length">{{$t('evaluation.noPoints')}}</span>
 									<div v-else>
-										<span v-for="(point, index) in item.knowledge" class="item-point-tag" :key="index">
+										<span v-for="(point, pointIndex) in item.knowledge" class="item-point-tag" :key="pointIndex">
 											{{ point }}
 										</span>
 									</div>
@@ -76,9 +77,22 @@
 							<div class="item-explain" v-if="isShowAnalysis">
 								<span class="explain-title">【{{ $t('totalAnalysis.showAnalysis') }}】</span>
 								<div class="item-explain-details">
-									<AnalysisItemTable></AnalysisItemTable>
+									<AnalysisItemTable :analysisJson="analysisJson[index]"></AnalysisItemTable>
 									</br>
-									<OptionsTable v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'"></OptionsTable>
+									<OptionsTable v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'"
+									 :options="item.option.map(i => i.code)" :optionRate="optionRate[index]"
+									 :answer="item.answer"
+									 ></OptionsTable>
+									 </br>
+									 <Row>
+										 <Col span="12" v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'">
+											<BaseRateLine :ids="'R1R6' + index" :echartsData="getOptionLineData(item,index)"></BaseRateLine>
+										 </Col>
+										 <Col span="12">
+										 	<BaseLine :ids="'rateLine' + index" :echartsData="analysisJson[index]"></BaseLine>
+										 </Col>
+									 </Row>
+									 
 								</div>
 							</div>
 						</div>
@@ -112,8 +126,10 @@
 	import blobTool from "@/utils/blobTool.js";
 	import AnalysisItemTable from '@/components/evaluation/AnalysisItemTable'
 	import OptionsTable from '@/components/evaluation/OptionsTable'
+	import BaseLine from '@/components/student-analysis/total/BaseLine.vue'
+	import BaseRateLine from '@/components/student-analysis/total/BaseRateLine.vue'
 	export default {
-		components:{AnalysisItemTable,OptionsTable},
+		components:{AnalysisItemTable,OptionsTable,BaseRateLine,BaseLine},
 		props:{
 			propsList:{
 				type:Array,
@@ -121,6 +137,24 @@
 					return []
 				}
 			},
+			analysisJson:{
+				type:Array,
+				default:() => {
+					return []
+				}
+			},
+			optionRate:{
+				type:Array,
+				default:() => {
+					return []
+				}
+			},
+			flatIds:{
+				type:Array,
+				default:() => {
+					return []
+				}
+			},
 			selQue: {
 			    type: Array,
 			    default: () => {
@@ -157,11 +191,11 @@
 				collapseList: [],
 				selectList:[],
 				originData: [],
-				exerciseList:[]
+				exerciseList:[],
 			};
 		},
 		created() {
-			console.log('接收到的',this.propsList)
+			console.log('接收到的',this.analysisJson)
 			this.pageSize = this.isAnalysis ? 999 : 5
 			this.pageChange(1)
 		},
@@ -179,6 +213,38 @@
 				})
 			},
 			
+			getOptionLineData(item,index){
+				let result = []
+				let n = this.optionRate[index]
+				let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
+				let phCount = Math.floor(total * 0.27) //取高分组低分组人数
+				item.option.map(i => i.code).forEach(key => {
+					result.push({
+						option:key,
+						rate:n.record[key] ? ((n.record[key] / total) * 100).toFixed(1) : 0,
+						PH: n.ph[key] ? ((n.ph[key] / phCount) * 100).toFixed(1) : 0,
+						PL: n.pl[key] ? ((n.pl[key] / phCount) * 100).toFixed(1) : 0,
+					})
+				})
+				return result
+			},
+			
+			getChildAnalysisJson(pItem){
+				let result = []
+				pItem.children.forEach(child => {
+					result.push(this.analysisJson[this.flatIds.indexOf(child.id)])
+				})
+				return result
+			},
+			
+			getChildOptionRate(pItem){
+				let result = []
+				pItem.children.forEach(child => {
+					result.push(this.optionRate[this.flatIds.indexOf(child.id)])
+				})
+				return result
+			},
+			
 			onSelectItem(item,index){
 				let arrIndex = this.selectList.map(i => i.id).indexOf(item.id)
 				console.log(arrIndex)
@@ -289,23 +355,8 @@
 
 		},
 		mounted() {
-			// 公式渲染
-			this.$nextTick(() => {
-				// window.MathJax.Hub.Queue([
-				// 	"Typeset",
-				// 	MathJax.Hub,
-				// 	this.$refs.mathJaxContainer,
-				// ]);
-			});
-			
-			// console.log('拿到已选',this.selQue)
 			this.selectList = this.selQue
-			
-			// this.$EventBus.$off('onPaperItemChange')
-			// this.$EventBus.$on('onPaperItemChange', data => {
-			// 	console.log('EventBus',data)
-			// 	this.selectList = data
-			// })
+			console.log(this.optionRate)
 		},
 		computed: {
 			curScope() {
@@ -338,6 +389,15 @@
 					}
 				}
 			},
+			optionRate:{
+				handler(n,o){
+					if(n){
+						console.log(n)
+					}
+				},
+				immediate:true,
+				deep:true
+			},
 			examScope:{
 				handler(n,o){
 					this.examPropScope = n

+ 71 - 196
TEAMModelOS/ClientApp/src/components/evaluation/OptionsTable.vue

@@ -3,225 +3,100 @@
 		<!-- 表格组件 -->
 		<Table border ref="table" :data="optionsData" :columns="optionColumns"></Table>
 
-		
+
 
 	</div>
 </template>
 <script>
 	export default {
 		props: {
-			tableDatas: {
+			optionRate: {
+				type: Object,
+				default: () => {}
+			},
+			options: {
 				type: Array,
 				default: () => []
 			},
-			
+			answer:{
+				type: Array,
+				default: () => []
+			}
+
 		},
-		data() {
+		data(vm) {
 			return {
-				dataColumns: [
-				    {
-				        title: '知识点',
-				        key: 'knowledgePoint',
-				        align: 'center',
-				        width: 150
-				    },
-				    {
-				        title: '落点区域',
-				        key: 'areaName',
-				        align: 'center'
-				    },
-				    {
-				        title: '配分',
-				        key: 'score',
-				        align: 'center'
-				    },
-				    {
-				        title: '难易度',
-				        key: 'diff',
-				        align: 'center'
-				    },
-				    {
-				        title: '鉴别度',
-				        key: 'identify',
-				        align: 'center',
-				        render: function (h, params) {
-				            return h('span', (Number(params.row.identify)).toFixed(2))
-				        }
-				    },
-				    {
-				        title: '正答率',
-				        align: 'center',
-				        key: 'classScoreRate'
-				    },
-				    {
-				        title: '高分组正答率',
-				        align: 'center',
-				        key: 'PH',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.PH)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: '低分组正答率',
-				        align: 'center',
-				        key: 'PL',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.PL)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R1',
-				        align: 'center',
-				        key: 'R1',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R1)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R2',
-				        key: 'R2',
-				        align: 'center',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R2)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R3',
-				        align: 'center',
-				        key: 'R3',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R3)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R4',
-				        align: 'center',
-				        key: 'R4',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R4)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R5',
-				        align: 'center',
-				        key: 'R5',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R5)) * 100).toFixed(0) + '%')
-				        }
-				    },
-				    {
-				        title: 'R6',
-				        align: 'center',
-				        key: 'R6',
-				        render: function (h, params) {
-				            return h('span', ((Number(params.row.R6)) * 100).toFixed(0) + '%')
-				        }
-				    }
-				],
-				optionColumns: [
-				    {
-				        title: '选项',
-				        key: 'option',
-				        align: 'center',
-				        width: 150
-				    },
-				    {
-				        title: '选答人数',
-				        key: 'num',
-				        align: 'center'
-				    },
-				    {
-				        title: '选答率',
-				        key: 'rate',
-				        align: 'center',
-				        render: (h, params) => {
-				            return h('div', [
-				                h('Progress', {
-				                    props: {
-				                        percent: params.row.rate,
-				                        strokeColor: params.row.isTrue ? '#14db14' : '#b5bcbe'
-				                    }
-				                })
-				            ])
-				        }
-				    },
-				    {
-				        title: '高分组选答率',
-				        align: 'center',
-				        key: 'PH',
-				        render: function (h, params) {
-				            return h('span', params.row.PH + '%')
-				        }
-				    },
-				    {
-				        title: '低分组选答率',
-				        align: 'center',
-				        key: 'PL',
-				        render: function (h, params) {
-				            return h('span', params.row.PL + '%')
-				        }
-				    }
+				optionsData: [],
+				optionColumns: [{
+						title: vm.$t('totalAnalysis.myTable.option'),
+						key: 'option',
+						align: 'center',
+						width: 150
+					},
+					{
+						title: vm.$t('totalAnalysis.myTable.answerCount'),
+						key: 'num',
+						align: 'center'
+					},
+					{
+						title: vm.$t('totalAnalysis.myTable.answerRate'),
+						key: 'rate',
+						align: 'center',
+						render: (h, params) => {
+							return h('div', [
+								h('Progress', {
+									props: {
+										percent: +params.row.rate.replace('%',''),
+										strokeColor: params.row.isTrue ? '#14db14' : '#b5bcbe'
+									}
+								})
+							])
+						}
+					},
+					{
+						title: vm.$t('totalAnalysis.myTable.RHRate'),
+						align: 'center',
+						key: 'PH',
+					},
+					{
+						title: vm.$t('totalAnalysis.myTable.RLRate'),
+						align: 'center',
+						key: 'PL',
+					}
 				],
 			}
 		},
 		created() {
-			this.optionsData = [
-			    {
-			        option: 'A',
-			        isTrue: false,
-			        num: 12,
-			        rate: 40,
-			        PH: 10,
-			        PL: 60
-			    },
-			    {
-			        option: 'B',
-			        isTrue: false,
-			        num: 6,
-			        rate: 20,
-			        PH: 10,
-			        PL: 23
-			    },
-			    {
-			        option: 'C',
-			        isTrue: true,
-			        num: 9,
-			        rate: 30,
-			        PH: 70,
-			        PL: 10
-			    },
-			    {
-			        option: 'D',
-			        isTrue: false,
-			        num: 3,
-			        rate: 10,
-			        PH: 10,
-			        PL: 7
-			    }
-			]
-
 
 		},
 		methods: {
 
-			
-		},
-
-		mounted() {
-			
-		},
 
-		computed: {
-			exportTableRefs() {
-				return this.$store.state.totalAnalysis.exportTableRefs
-			}
 		},
-
 		watch: {
-			
-			
+			optionRate: {
+				handler(n, o) {
+					if (Object.keys(n).length) {
+						let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
+						let phCount = Math.floor(total * 0.27) //取高分组人数
+						this.options.forEach(key => {
+							this.optionsData.push({
+								option: key,
+								isTrue: this.answer[0].includes(key) ,
+								num: n.record[key] || 0,
+								rate: n.record[key] ? Number((n.record[key] / total) * 100).toFixed(1) +
+									'%' : '0',
+								PH: n.ph[key] ? Number((n.ph[key] / phCount) * 100).toFixed(1) + '%' : 0,
+								PL: n.pl[key] ? Number((n.pl[key] / phCount) * 100).toFixed(1) + '%' : 0,
+							})
+						})
+					}
+				},
+				immediate: true,
+				deep: true
+			},
+
 		}
 
 	}
 </script>
-

+ 164 - 0
TEAMModelOS/ClientApp/src/components/questionnaire/BaseMiniBar.vue

@@ -0,0 +1,164 @@
+<template>
+	<div :id="barId" class="myBar"></div>
+</template>
+
+<script>
+	export default {
+		name: 'BaseBar',
+		props: ['barId', 'barData'],
+		data() {
+			return {
+				barDatas: []
+			}
+		},
+		methods: {
+
+			drawLine(data) {
+				let that = this
+				// 基于准备好的dom,初始化echarts实例
+				let myBar = this.$echarts.init(document.getElementById(this.barId), 'chalk')
+
+				let option = {
+					tooltip: {
+						trigger: "item",
+						padding: [4, 12],
+						backgroundColor: "white",
+						textStyle: {
+							color: "black",
+							fontFamily: "Ariel",
+							fontWeight: "bolder",
+						},
+					},
+					grid: {
+						top: "5%",
+						bottom: "20%",
+						containLabel: true,
+					},
+					xAxis: {
+						type: "category",
+						data: this.$t("studentWeb.studyTimeChart.xAxisData"),
+						splitLine: {
+							lineStyle: {
+								color: "transparent",
+							},
+						},
+						//座標軸線的設置
+						axisLine: {
+							show:false,
+							lineStyle: {
+								color: "gray",
+								width: 2,
+							},
+						},
+						//座標軸的刻度顏色
+						axisLabel: {
+							show:false,
+							color: "black",
+						},
+					},
+					yAxis: {
+						type: "value",
+						show: false,
+						axisLine: {
+							show:false,
+							lineStyle: {
+								color: "gray",
+								width: 2,
+							},
+						},
+						//座標軸的刻度顏色
+						axisLabel: {
+							show:false,
+							color: "black",
+						},
+					},
+					barCategoryGap: "1px",
+
+					emphasis: {
+						itemStyle: {
+							color: "#FA6400", //高亮
+						},
+					},
+					series: [{
+						data: [{
+								value: 4,
+								itemStyle: {
+									color: "#00AD6C"
+								},
+							},
+							{
+								value: 15,
+								itemStyle: {
+									color: "#008352"
+								},
+							},
+							{
+								value: 20,
+								itemStyle: {
+									color: "#008352"
+								},
+							},
+							{
+								value: 40,
+								itemStyle: {
+									color: "rgb(0, 62, 39)"
+								},
+							},
+							{
+								value: 5,
+								itemStyle: {
+									color: "#00AD6C"
+								},
+							},
+							{
+								value: 20,
+								itemStyle: {
+									color: "#00AD6C"
+								},
+							},
+							{
+								value: 10,
+								itemStyle: {
+									color: "#00AD6C"
+								},
+							},
+						],
+						type: "bar",
+					}, ],
+				}
+
+				// 绘制图表
+				myBar.setOption(option)
+
+				window.addEventListener('resize', function() {
+					myBar.resize()
+				})
+			}
+		},
+		mounted() {
+			// if (!this.barData.count.length) return
+			this.drawLine()
+
+
+		},
+		watch: {
+			barData: {
+				deep: true,
+				handler(val) {
+					this.drawLine(val)
+				}
+			}
+		}
+
+	}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+	.myBar {
+		width: 100%;
+		height: 100%;
+		margin: 0 auto;
+		display: block;
+	}
+</style>

+ 2 - 1
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnBar.vue

@@ -48,6 +48,7 @@
 						}
 					},
 					grid: {
+						show:false,
 						"top": "25%",
 						"left": "5%",
 						"bottom": "0",
@@ -137,7 +138,7 @@
 <style scoped>
 	.myBar {
 		width: 100%;
-		height: 380px;
+		height: 280px;
 		margin: 0 auto;
 		display: block;
 	}

+ 108 - 88
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue

@@ -2,42 +2,68 @@
 	<div class="component-qn-form">
 		<Form ref="qnForm" :model="qnForm" label-position="top" :rules="ruleValidate" :disabled="!qnFormEdit">
 			<FormItem :label="$t('survey.form.name')" prop="name">
-				<Input :class="!qnFormEdit ? 'qn-form-disabled':''" v-model="qnForm.name" :placeholder="$t('survey.form.namePlace')"></Input>
+				<Input :class="!qnFormEdit ? 'qn-form-disabled':''" v-model="qnForm.name"
+					:placeholder="$t('survey.form.namePlace')"></Input>
 			</FormItem>
 
 			<FormItem :label="$t('survey.form.target')" prop="classes">
 				<RadioGroup v-model="classType" @on-change="onClassTypeChange" v-if="qnFormEdit">
-				        <Radio label="private">{{ $t('survey.form.privateClass') }}</Radio>
-				        <Radio label="school">{{ $t('survey.form.schoolClass') }}</Radio>
+					<Radio label="private">{{ $t('survey.form.privateClass') }}</Radio>
+					<Radio label="school">{{ $t('survey.form.schoolClass') }}</Radio>
 				</RadioGroup>
 				<div v-if="!qnFormEdit && curQnItem" class="vote-class">
 					<span v-for="item in curQnItem.classes" class="vote-class-item">{{ getTargetName(item) }}</span>
 				</div>
-				<Select multiple v-model="qnForm.classes" :class="!qnFormEdit ? 'qn-form-disabled':''" :placeholder="$t('survey.form.targetPlace')" v-else>
-					<!-- <Option v-for="(item,index) in classRooms" :value="item.id" :key="index">{{ item.name }}</Option> -->
-						<Option v-for="(item,index) in classRooms.filter(i=>i.scope === classType)" :value="item.id" :key="index">{{ item.name }}</Option>
-						<!-- <Option v-for="item in classRooms" :value="item.id" :key="item.id">{{ item.name }}</Option> -->
+				<Select multiple v-model="qnForm.classes" :class="!qnFormEdit ? 'qn-form-disabled':''"
+					:placeholder="$t('survey.form.targetPlace')" v-else>
+					<Option v-for="(item,index) in classRooms.filter(i=>i.scope === classType)" :value="item.id"
+						:key="index">{{ item.name }}</Option>
 				</Select>
 			</FormItem>
 
-			<FormItem :label="$t('survey.form.time')" prop="rangeTime">
+			<!-- <FormItem :label="$t('survey.form.time')" prop="rangeTime">
+				<RadioGroup v-model="publishModel" v-if="qnFormEdit">
+				        <Radio label="0">立即发布</Radio>
+				        <Radio label="1">定时发布</Radio>
+				</RadioGroup>
 				<DatePicker type="datetimerange" @on-change="onChangeRange" @on-open-change="onOpenChange" format="yyyy-MM-dd HH:mm" :class="!qnFormEdit ? 'qn-form-disabled':''"
 				 :editable="isDateEdit" :placeholder="$t('survey.form.endTimePlace')" :value="[qnForm.startTime,qnForm.endTime]">
-
 				</DatePicker>
+			</FormItem> -->
+
+			<FormItem :label="$t('learnActivity.createEv.publishType')" prop="publishModel" v-show="qnFormEdit">
+				<Checkbox v-model="isImmediate">{{ $t('global.publishType1')}}</Checkbox>
+			</FormItem>
+
+			<FormItem :label="$t('learnActivity.createEv.startTime')" v-if="!isImmediate || !qnFormEdit"
+				prop="startTime">
+				<DatePicker v-show="qnFormEdit" type="datetime" :options="startOption" format="yyyy/MM/dd HH:mm"
+					v-model="qnForm.startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')"
+					style="width:100%" @on-change="onChangeSTime"></DatePicker>
+				<div v-show="!qnFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff">
+					{{ $tools.formatTime(qnForm.startTime,'yyyy-MM-dd hh:mm') }}
+				</div>
+			</FormItem>
+
+			<FormItem :label="$t('learnActivity.createEv.endTime')"  prop="endTime">
+				<DatePicker v-show="qnFormEdit" type="datetime" :options="endOption" format="yyyy/MM/dd HH:mm" v-model="qnForm.endTime"
+					split-panels @on-change="onChangeEndTime" :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%"></DatePicker>
+				<div v-show="!qnFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff">
+					{{ $tools.formatTime(qnForm.endTime,'yyyy-MM-dd hh:mm') }}
+				</div>
 			</FormItem>
 
 
 			<FormItem :label="$t('survey.form.description')" prop="description">
 				<div ref="descriptionEditor" style="text-align:left" v-show="qnFormEdit"></div>
-				<div v-html="qnForm.description" v-show="!qnFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff"></div>
+				<div v-html="qnForm.description" v-show="!qnFormEdit"
+					style="margin:10px;font-size:16px;font-weight:bold;color:#fff"></div>
 			</FormItem>
 		</Form>
 
 	</div>
 </template>
 <script>
-	
 	import E from 'wangeditor'
 	export default {
 		props: {
@@ -51,9 +77,10 @@
 			}
 		},
 		data(vm) {
+			 const _this = this
 			return {
-				curQnItem:null,
-				classType:'private',
+				curQnItem: null,
+				classType: 'private',
 				isFalse: false,
 				isLoading: false,
 				isRelatedContent: false,
@@ -71,11 +98,15 @@
 				defaultFileList: [],
 				relateFileList: [],
 				uploadUrl: '',
+				publishModel: '0',
+				isImmediate: true,
+				startTime: '',
+				endTime: '',
 				qnForm: {
 					name: '',
 					classes: [],
 					endTime: '',
-					publishModel: '0',
+					publishModel: 0,
 					rangeTime: [],
 					startTime: '',
 					description: '',
@@ -83,11 +114,10 @@
 					other: []
 				},
 				defaultParams: {
-					id:"",
+					id: "",
 					code: "",
 					name: "",
 					classes: [],
-					publishModel: "0",
 					startTime: 0,
 					endTime: 0,
 					resource: []
@@ -108,51 +138,58 @@
 						required: true,
 						message: vm.$t('survey.form.ruleClasses')
 					}],
-					rangeTime: [{
+					startTime: [{
 						required: true,
-						message: vm.$t('survey.form.ruleTime'),
-						trigger: 'change',
-						type: 'array'
+						type: 'date',
+						message: this.$t('learnActivity.createEv.errTips8'),
+						trigger: 'change'
+					}],
+					endTime: [{
+						required: true,
+						type: 'date',
+						message: this.$t('learnActivity.createEv.errTips9'),
+						trigger: 'change'
 					}]
+				},
+				startOption: {
+					disabledDate(date) {
+					    return date && date.valueOf() < Date.now() - 86400000
+					}
+				},
+				endOption: {
+					disabledDate(date) {
+						let data = _this.qnForm.startTime ? _this.qnForm.startTime : Date.now()
+					    return data && data > date.valueOf() + 86400000
+					}
 				}
 			}
 		},
 		methods: {
-			onClassTypeChange(val){
+			onClassTypeChange(val) {
 				this.qnForm.classes = []
 			},
 
-			onChangeRange(arr) {
-				if (arr[0] === '') {
-					this.qnForm.rangeTime = null
-					this.ruleValidate.rangeTime[0].message = this.$t('survey.form.ruleTime')
-				} else if (this.getTimestampByString(arr[0]) < Date.now()) {
-					this.qnForm.rangeTime = null
-					this.ruleValidate.rangeTime[0].message = this.$t('survey.form.ruleStartTime')
-				} else {
-					console.log(this.getTimestampByString(arr[0]))
-					this.qnForm.startTime = this.getTimestampByString(arr[0])
-					this.qnForm.endTime = this.getTimestampByString(arr[1])
-					this.qnForm.rangeTime = arr
-					this.ruleValidate.rangeTime[0].message = this.$t('survey.form.ruleTime')
+			onChangeSTime(val) {
+				let endTime = this.qnForm.endTime || Date.now()
+				if (new Date(val).getTime() >= new Date(endTime).getTime()) {
+					this.qnForm.endTime = null
 				}
 			},
 			
-			/* 如果是第一次点击 则设置默认值为当前时间 默认结束为一天后的当前时间 */
-			onOpenChange(flag){
-				if(flag && !this.qnForm.rangeTime){
-					this.qnForm.startTime = Date.now()
-					this.qnForm.endTime = Date.now() + 86400000
-					this.qnForm.rangeTime = [Date.now(),Date.now() + 86400000]
+			onChangeEndTime(val){
+				if (val.indexOf('00:00') > 0) {
+				    val = val.replace('00:00', '23:59')
+					this.qnForm.endTime = val
+				}
+				let startTime = this.qnForm.startTime || Date.now()
+				if (new Date(val).getTime() <= new Date(startTime).getTime()) {
+					this.qnForm.endTime = null
+					this.ruleValidate.endTime[0].message = this.$t('survey.form.ruleStartTime')
+				}else{
+					this.ruleValidate.endTime[0].message = this.$t('survey.form.ruleDate')
 				}
 			},
 
-			getTimestampByString(str) {
-				str = str.substring(0, 19);
-				str = str.replace(/-/g, '/'); //必须把日期'-'转为'/'
-				var timestamp = new Date(str).getTime();
-				return timestamp
-			},
 			/**
 			 * 提交新增问卷表单
 			 * @param name FormName
@@ -165,21 +202,24 @@
 							let target = []
 							params.code = this.getCurCode
 							// 如果个人问卷的班级是校本班级 那么也要把scope置为school
-							params.scope = this.$route.name === 'personalSurvey' && this.classType === 'private' ? 'private' : 'school'
+							params.scope = this.$route.name === 'personalSurvey' && this.classType ===
+								'private' ? 'private' : 'school'
 							params.name = this.qnForm.name
-							params.startTime = this.qnForm.startTime
-							params.endTime = this.qnForm.endTime
+							params.startTime = this.publishModel === '1' ? new Date(this.qnForm.startTime)
+								.getTime() : -1
+							params.endTime = new Date(this.qnForm.endTime).getTime()
 							params.description = this.qnForm.description
 							// 新增参数
 							params.owner = this.$route.name === 'personalSurvey' ? 'teacher' : 'school'
 							params.creatorId = this.$store.state.userInfo.TEAMModelId
-							params.school = params.scope === 'school' ?  this.$store.state.userInfo.schoolCode : null
-							
+							params.school = params.scope === 'school' ? this.$store.state.userInfo
+								.schoolCode : null
+
 							// 如果是编辑状态 则直接复制ID 如果是新增 则直接赋值新ID
 							if (this.isEdit && this.editInfo.id && this.editInfo.code) {
 								params.id = this.editInfo.id
 								params.createTime = this.editInfo.createTime
-							}else{
+							} else {
 								params.id = this.$tools.guid()
 							}
 							params.classes = this.qnForm.classes
@@ -187,6 +227,7 @@
 							resolve(params)
 						} else {
 							this.$Message.error(this.$t('survey.form.noCompleteTip'))
+							reject(500)
 						}
 					})
 				})
@@ -204,7 +245,7 @@
 					}).then(res => {
 						if (!res.error && res.courses) {
 							this.$store.dispatch('user/getSchoolProfile').then(schoolProfile => {
-							    // let schoolClasses =  schoolProfile.school_classes
+								// let schoolClasses =  schoolProfile.school_classes
 								r(res.courses)
 							}).catch(err => {
 								r([])
@@ -223,16 +264,6 @@
 				return html.replace(r, "");
 			},
 
-			/**
-			 * 重置表单
-			 * @param name
-			 */
-			handleCancel() {
-				this.qnFormEdit = false
-				this.doRender(this.editInfo)
-
-			},
-
 			/**
 			 * 重置表单
 			 * @param name
@@ -243,18 +274,6 @@
 
 			},
 
-			/** 附件上传之前钩子 限制附件上传个数 */
-			handleBeforeUpload() {
-				const check = this.uploadList.length < 5;
-				if (!check) {
-					this.$Notice.warning({
-						title: '最多只能上传5个附件'
-					});
-				}
-				return check;
-			},
-
-
 
 			/** 
 			 * 回显问卷详情
@@ -262,34 +281,35 @@
 			 */
 			async doRender(item) {
 				console.log(item)
-				if(!this.classRooms.length){
+				if (!this.classRooms.length) {
 					this.classRooms = await this.getClassrooms(this.userInfo.TEAMModelId)
 				}
 				this.qnForm = {
 					name: item.name,
 					classes: item.classes || [],
-					startTime: item.endTime ? item.startTime : '',
-					endTime: item.endTime ? item.endTime : '',
+					startTime: item.startTime ? new Date(item.startTime) : '',
+					endTime: item.endTime ? new Date(item.endTime) : '',
 					description: item.description,
-					rangeTime: item.endTime ? [item.startTime,item.endTime] : null
+					rangeTime: item.endTime ? [item.startTime, item.endTime] : null
 				}
+				this.isImmediate = false
 				this.currentState = item.state
 				this.$nextTick(() => {
 					this.curQnItem = JSON.parse(JSON.stringify(item))
-					if(item.classes.length){
+					if (item.classes.length) {
 						let isExist = this.classRooms.filter(i => i.id === item.classes[0])
 						this.classType = isExist ? isExist[0].scope : 'private'
 					}
 				})
 				this.descriptionEditor.txt.html(item.description)
 			},
-			
+
 			/* 根据班级ID获取班级名称 */
-			getTargetName(classId){
-				if(this.classRooms.length){
+			getTargetName(classId) {
+				if (this.classRooms.length) {
 					let targetIndex = this.classRooms.map(i => i.id).indexOf(classId)
-					return targetIndex > -1 ?  this.classRooms[targetIndex].name : this.$t('survey.noMatchData')
-				}else{
+					return targetIndex > -1 ? this.classRooms[targetIndex].name : this.$t('survey.noMatchData')
+				} else {
 					this.getClassrooms(this.userInfo.TEAMModelId).then(res => {
 						return res.filter(i => i.id === classId)[0].name
 					})
@@ -315,11 +335,12 @@
 				return this.qnForm.startTime
 			},
 			getCurCode() {
-				return this.$route.name === 'personalSurvey' ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode
+				return this.$route.name === 'personalSurvey' ? this.$store.state.userInfo.TEAMModelId : this.$store.state
+					.userInfo.schoolCode
 			},
 			getCurScope() {
 				return this.$route.name === 'personalSurvey' ? 'private' : 'school'
-			}
+			},
 		},
 		watch: {
 			editItem: {
@@ -347,4 +368,3 @@
 <style lang="less">
 	@import "./BaseQnForm.less";
 </style>
-

+ 13 - 1
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.less

@@ -61,12 +61,24 @@
 		
         .qn-item{
 			position: relative;
+			display: flex;
             margin: 10px 0;
             font-size: 16px;
             font-weight: bold;
 			padding: 20px;
-			cursor: move;
 			user-select: none;
+			cursor: move;
+			
+			&-content{
+				flex: 1;
+			}
+			
+			&-charts{
+				width: 20%;
+				display: flex;
+				flex-direction: column;
+				justify-content: flex-end;
+			}
 			
 			.qn-stem p{
 				display: inline-block;

+ 46 - 37
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue

@@ -12,45 +12,52 @@
 			<draggable class="list-group" tag="div" v-model="items" v-bind="dragOptions" @start="drag = true" @end="onDragEnd" v-else>
 				<transition-group type="transition" :name="!drag ? 'flip-list' : null">
 					<div class="qn-item animated fadeInUp" v-for="(item,index) in items" :key="index">
-						<!-- 题干 -->
-						<p class="qn-stem">
-							<span style="color: red;" v-show="item.required">* </span>
-							<span>{{ index + 1 }}. </span>
-							<span v-html="item.question"></span>
-							<span>( {{ typeList[item.type] }} )</span>
-						</p>
-						<!-- 单选题-选项 -->
-						<RadioGroup v-model="radioModel" v-if="item.type === 'single' || item.type === 'judge'">
-							<Radio v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled></Radio>
-						</RadioGroup>
-						<!-- 多选题-选项 -->
-						<CheckboxGroup v-model="multipleModel" v-if="item.type === 'multiple'">
-							<Checkbox v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled>
-							</Checkbox>
-						</CheckboxGroup>
-						<!-- 数据分析 -->
-						<transition name="indexFade">
-						      <div>
-								  <BaseQnBar :barId="'bar' + index" :barData="item.result || []" v-if="curIndexList.includes(index) && item.type !== 'subjective'"></BaseQnBar>
-								  <BaseAnsList v-if="curIndexList.includes(index) && item.type === 'subjective'" :ansList="item.result.details"></BaseAnsList>
-							  </div>
-						</transition>
-						<!-- 工具栏 -->
-						<div class="qn-tools">
-							<div class="qn-tools-item" @click="onItemEdit(item,index)" v-if="editable">
-								<Icon type="md-create" />
-								<span>{{ $t('survey.questionaire.edit') }}</span>
-							</div>
-							<div class="qn-tools-item" @click="onItemDelete(index)"  v-if="editable">
-								<Icon type="md-trash" />
-								<span>{{ $t('survey.questionaire.remove') }}</span>
-							</div>
-							<!-- <div class="qn-tools-item" @click="onItemAnalysis(index)"> -->
-							<div class="qn-tools-item" @click="onItemAnalysis(index,item)" v-if="currentQn.progress === 'finish'">
-								<Icon type="md-podium" />
-								<span>{{ $t('survey.questionaire.analysisData') }}</span>
+						<div class="qn-item-content">
+							<!-- 题干 -->
+							<p class="qn-stem">
+								<span style="color: red;" v-show="item.required">* </span>
+								<span>{{ index + 1 }}. </span>
+								<span v-html="item.question"></span>
+								<span>( {{ typeList[item.type] }} )</span>
+							</p>
+							<!-- 单选题-选项 -->
+							<RadioGroup v-model="radioModel" v-if="item.type === 'single' || item.type === 'judge'">
+								<Radio v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled></Radio>
+							</RadioGroup>
+							<!-- 多选题-选项 -->
+							<CheckboxGroup v-model="multipleModel" v-if="item.type === 'multiple'">
+								<Checkbox v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled>
+								</Checkbox>
+							</CheckboxGroup>
+							
+							
+							<!-- 数据分析 -->
+							<transition name="indexFade">
+							      <div>
+									  <BaseQnBar :barId="'bar' + index" :barData="item.result || []" v-if="curIndexList.includes(index) && item.type !== 'subjective'"></BaseQnBar>
+									  <BaseAnsList v-if="curIndexList.includes(index) && item.type === 'subjective'" :ansList="item.result.details"></BaseAnsList>
+								  </div>
+							</transition>
+							<!-- 工具栏 -->
+							<div class="qn-tools">
+								<div class="qn-tools-item" @click="onItemEdit(item,index)" v-if="editable">
+									<Icon type="md-create" />
+									<span>{{ $t('survey.questionaire.edit') }}</span>
+								</div>
+								<div class="qn-tools-item" @click="onItemDelete(index)"  v-if="editable">
+									<Icon type="md-trash" />
+									<span>{{ $t('survey.questionaire.remove') }}</span>
+								</div>
+								<!-- <div class="qn-tools-item" @click="onItemAnalysis(index)"> -->
+								<div class="qn-tools-item" @click="onItemAnalysis(index,item)" v-if="currentQn.progress === 'finish'">
+									<Icon type="md-podium" />
+									<span>{{ $t('survey.questionaire.analysisData') }}</span>
+								</div>
 							</div>
 						</div>
+						<div class="qn-item-charts">
+							<BaseMiniBar :barId="'minibar' + index"></BaseMiniBar>
+						</div>
 					</div>
 				</transition-group>
 			</draggable>
@@ -79,12 +86,14 @@
 	import BaseJudge from "./BaseJudge.vue"
 	import BaseSubjective from "./BaseSubjective.vue"
 	import BaseQnBar from "./BaseQnBar.vue"
+	import BaseMiniBar from "./BaseMiniBar.vue"
 	import BaseAnsList from "@/components/questionnaire/BaseAnsList.vue";
 	
 	export default {
 		components: {
 			draggable,
 			BaseQnBar,
+			BaseMiniBar,
 			BaseSingle,
 			BaseMultiple,
 			BaseJudge,

+ 4 - 18
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseLine.vue

@@ -11,9 +11,7 @@
                 y: []
             }
         },
-        created() {
-
-        },
+        created() {},
         mounted() {
             let item = this.echartsData
             if (item) {
@@ -27,14 +25,6 @@
                 this.y = arr
                 this.drawLine()
             }
-            
-            let myLine = this.$echarts.init(document.getElementById(this.ids), 'chalk')
-            this.initWidth = document.getElementById(this.ids).offsetWidth
-            let resize = {
-                width: 500,
-                height: 400
-            }
-            myLine.resize(resize)
         },
         methods: {
             drawLine() {
@@ -44,14 +34,12 @@
                 // 指定图表的配置项和数据
                 var option = {
                     title: {
-                        text: 'R1-R6作答曲线',
+                        text: this.$t('totalAnalysis.R1R6LineTitle'),
                         textStyle: {
                             align: 'center',
                             color: '#333',
                             fontSize: 14
                         },
-                        top: '3%',
-                        left: '10%'
                     },
                     tooltip: {
                         trigger: 'axis',
@@ -71,10 +59,8 @@
                         }
                     },
                     gird: {
-                        left: '3%',
-                        right: '4%',
-                        bottom: '3%',
-                        containLabel: true
+                        containLabel: true,
+						top:'22%'
                     },
                     xAxis: [
                         {

+ 18 - 25
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseRateLine.vue

@@ -11,17 +11,12 @@
             }
         },
         mounted() {
-            this.drawLine()
-            let myLine = this.$echarts.init(document.getElementById(this.ids), 'chalk')
-            this.initWidth = document.getElementById(this.ids).offsetWidth
-            let resize = {
-                width: 500,
-                height: 400
-            }
-            myLine.resize(resize)
+			if(this.echartsData.length){
+				this.drawLine(this.echartsData)
+			}
         },
         methods: {
-            drawLine() {
+            drawLine(data) {
 				let that = this
                 // 基于准备好的dom,初始化echarts实例
                 let myLine = this.$echarts.init(document.getElementById(this.ids), 'chalk')
@@ -29,14 +24,12 @@
                 // 指定图表的配置项和数据
                 var option = {
                     title: {
-                        text: '选项选答率分析',
+                        text: this.$t('totalAnalysis.rateLineTitle'),
                         textStyle: {
                             align: 'center',
                             color: '#333',
                             fontSize: 14
                         },
-                        top: '3%',
-                        left: '10%'
                     },
                     tooltip: {
                         trigger: 'axis',
@@ -57,12 +50,7 @@
                         textStyle: {
                             color: '#969696'
                         },
-                        top: 35
-                    },
-                    gird: {
-                        left: '3%',
-                        right: '4%',
-                        containLabel: true
+                        top: 0
                     },
                     xAxis: [
                         {
@@ -87,7 +75,7 @@
                                 color: '#989898', // 默认取轴线的颜色,
                                 fontSize: 14
                             },
-                            data: this.echartsData.map(item => item.option)
+                            data: data.map(item => item.option)
                         }
                     ],
                     yAxis: [
@@ -103,14 +91,19 @@
                                 lineStyle: {
                                     color: '#969696'
                                 }
-                            }
+                            },
+							axisLabel: {
+							    formatter: function(value) {
+							        return value + '%'
+							    }
+							},
                         }
                     ],
                     series: [
                         {
                             name:  that.$t('totalAnalysis.myTable.answerRate'),
                             type: 'line',
-                            data: this.echartsData.map(item => item.rate),
+                            data: data.map(item => item.rate),
                             color: '#F58080',
                             lineStyle: {
                                 normal: {
@@ -162,7 +155,7 @@
                         {
                             name: that.$t('totalAnalysis.myTable.RHRate'),
                             type: 'line',
-                            data: this.echartsData.map(item => item.PH),
+                            data: data.map(item => item.PH),
                             lineStyle: {
                                 normal: {
                                     width: 2,
@@ -202,7 +195,7 @@
                         {
                             name: that.$t('totalAnalysis.myTable.RLRate'),
                             type: 'line',
-                            data: this.echartsData.map(item => item.PL),
+                            data: data.map(item => item.PL),
                             lineStyle: {
                                 normal: {
                                     width: 2,
@@ -251,9 +244,9 @@
         watch: {
             echartsData: {
                 handler(n) {
-                    console.log(n)
+					n.length && this.drawLine(n)
                 }
-            }
+            },
         }
     }
 </script>

+ 52 - 52
TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue

@@ -19,11 +19,32 @@
 				</Select>
 			</FormItem>
 
-			<FormItem :label="$t('vote.form.time')" prop="rangeTime">
-				<!-- <DatePicker type="datetime" :class="!voteFormEdit ? 'vote-form-disabled':''" :editable="isDateEdit" placeholder="请选择投票结束时间" v-model="voteForm.endTime"  :options="endTimeOptions"></DatePicker> -->
+			<!-- <FormItem :label="$t('vote.form.time')" prop="rangeTime">
 				<DatePicker type="datetimerange" transfer @on-change="onChangeRange" @on-open-change="onOpenChange" :options="options3" format="yyyy-MM-dd HH:mm"
 				 :class="!voteFormEdit ? 'vote-form-disabled':''" :editable="isDateEdit" :value="[voteForm.startTime,voteForm.endTime]"
 				 :placeholder="$t('vote.form.endTimePlace')"></DatePicker>
+			</FormItem> -->
+			
+			<FormItem :label="$t('learnActivity.createEv.publishType')" prop="publishModel" v-show="voteFormEdit">
+				<Checkbox v-model="isImmediate">{{$t('global.publishType1')}}</Checkbox>
+			</FormItem>
+			
+			<FormItem :label="$t('learnActivity.createEv.startTime')" v-if="!isImmediate || !voteFormEdit"
+				prop="startTime">
+				<DatePicker v-show="voteFormEdit" type="datetime" :options="startOption" format="yyyy/MM/dd HH:mm"
+					v-model="voteForm.startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')"
+					style="width:100%" @on-change="onChangeSTime"></DatePicker>
+				<div v-show="!voteFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff">
+					{{ $tools.formatTime(voteForm.startTime,'yyyy-MM-dd hh:mm') }}
+				</div>
+			</FormItem>
+			
+			<FormItem :label="$t('learnActivity.createEv.endTime')"  prop="endTime">
+				<DatePicker v-show="voteFormEdit" type="datetime" :options="endOption" format="yyyy/MM/dd HH:mm" v-model="voteForm.endTime"
+					split-panels @on-change="onChangeEndTime" :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%"></DatePicker>
+				<div v-show="!voteFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff">
+					{{ $tools.formatTime(voteForm.endTime,'yyyy-MM-dd hh:mm') }}
+				</div>
 			</FormItem>
 
 			<FormItem :label="$t('vote.form.description')" prop="description">
@@ -95,6 +116,7 @@
 			}
 		},
 		data(vm) {
+			 const _this = this
 			return {
 				classType: 'private',
 				curVoteItem: null,
@@ -116,6 +138,7 @@
 				},
 				voteOptions: [...new Array(2).keys()], // 默认四个选项,
 				voteOptionsContent: [],
+				isImmediate: true,
 				voteForm: {
 					name: '',
 					classes: [],
@@ -147,16 +170,6 @@
 						return date && date.valueOf() < Date.now() - 86400000;
 					}
 				},
-				startTimeOptions: {
-					disabledDate: date => {
-						return date && date.valueOf() < Date.now() - 86400000;
-					}
-				},
-				endTimeOptions: {
-					disabledDate: date => {
-						return date && date.valueOf() < this.getDisableDays;
-					}
-				},
 				ruleValidate: {
 					name: [{
 						required: true,
@@ -176,25 +189,29 @@
 						required: true,
 						message: vm.$t('vote.form.ruleClasses')
 					}],
-					endTime: [{
+					startTime: [{
 						required: true,
 						type: 'date',
-						message:vm.$t('vote.form.ruleTime'),
+						message: this.$t('learnActivity.createEv.errTips8'),
 						trigger: 'change'
 					}],
-					startTime: [{
+					endTime: [{
 						required: true,
 						type: 'date',
-						message: vm.$t('vote.form.ruleTime'),
+						message: this.$t('learnActivity.createEv.errTips9'),
 						trigger: 'change'
-					}],
-					rangeTime: [{
-						required: true,
-						message: vm.$t('vote.form.ruleDate'),
-						trigger: 'change',
-						type: 'array'
 					}]
-
+				},
+				startOption: {
+					disabledDate(date) {
+					    return date && date.valueOf() < Date.now() - 86400000
+					}
+				},
+				endOption: {
+					disabledDate(date) {
+						let data = _this.voteForm.startTime ? _this.voteForm.startTime : Date.now()
+					    return data && data > date.valueOf() + 86400000
+					}
 				}
 			}
 		},
@@ -209,37 +226,20 @@
 			onClassTypeChange(val) {
 				this.voteForm.classes = []
 			},
-			onChangeRange(arr) {
-				console.log(arr)
-				if (arr[0] === '') {
-					this.voteForm.rangeTime = null
-					this.ruleValidate.rangeTime[0].message = this.$t('vote.form.ruleDate')
-				} else if (this.getTimestampByString(arr[0]) < Date.now()) {
-					this.voteForm.rangeTime = null
-					this.ruleValidate.rangeTime[0].message = this.$t('vote.form.ruleStartTime')
-				} else {
-					this.voteForm.startTime = this.getTimestampByString(arr[0])
-					this.voteForm.endTime = this.getTimestampByString(arr[1])
-					this.voteForm.rangeTime = arr
-					this.ruleValidate.rangeTime[0].message = this.$t('vote.form.ruleDate')
+			
+			onChangeSTime(val) {
+				let endTime = this.voteForm.endTime || Date.now()
+				if (new Date(val).getTime() >= new Date(endTime).getTime()) {
+					this.voteForm.endTime = null
 				}
 			},
 			
-			/* 如果是第一次点击 则设置默认值为当前时间 默认结束为一天后的当前时间 */
-			onOpenChange(flag){
-				if(flag && !this.voteForm.rangeTime){
-					this.voteForm.startTime = Date.now()
-					this.voteForm.endTime = Date.now() + 86400000
-					this.voteForm.rangeTime = [Date.now(),Date.now() + 86400000]
+			onChangeEndTime(val){
+				if (val.indexOf('00:00') > 0) {
+				    val = val.replace('00:00', '23:59')
+					this.voteForm.endTime = val
 				}
 			},
-
-			getTimestampByString(str) {
-				str = str.substring(0, 19);
-				str = str.replace(/-/g, '/'); //必须把日期'-'转为'/'
-				var timestamp = new Date(str).getTime();
-				return timestamp
-			},
 			/**
 			 * 提交新增投票表单
 			 * @param name FormName
@@ -514,9 +514,8 @@
 					name: item.name,
 					code: item.code,
 					classes: item.classes || [],
-					startTime: item.startTime,
-					endTime: item.endTime,
-					rangeTime: item.endTime ? [item.startTime, item.endTime] : null,
+					startTime: item.startTime ? new Date(item.startTime) : '',
+					endTime: item.endTime ? new Date(item.endTime) : '',
 					description: item.description,
 					secret: item.secret ? ['secret'] : [],
 					repeat: item.repeat ? ['repeat'] : [],
@@ -525,6 +524,7 @@
 					voteNum: item.voteNum || 1,
 					isReset: []
 				}
+				this.isImmediate = false
 				this.descriptionEditor.txt.html(item.description)
 				this.voteOptionsContent = item.options
 				this.voteOptions = item.options.map((item, index) => index)

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

@@ -56,7 +56,7 @@ export default {
 		ruleClasses:'问卷对象不能为空',
 		ruleTime:'请设置起止时间',
 		ruleDate:'日期不能为空',
-		ruleStartTime:'开始时间不能早于当前时间'
+		ruleStartTime:'结束时间不能早于开始时间'
 	},
 	questionaire:{
 		noItemData:'暂无题目数据',

+ 7 - 1
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/totalAnalysis.js

@@ -4,6 +4,8 @@ export default {
 		tab1:'统计数据',
 		tab2:'评测数据',
 	},
+	rateLineTitle:'选项选答率分析',
+	R1R6LineTitle:'R1-R6作答曲线',
 	lostStu:'缺考人数',
 	showAnalysis:'数据分析',
 	allSubjects:'全科',
@@ -267,9 +269,13 @@ export default {
 		rank:'排名统计',
 		option:'选项',
 		answerRate:'选答率',
+		answerCount:'选答人数',
 		RHRate:'高分组选答率',
 		RLRate:'低分组选答率',
 		tip:'* 绿色代表进线,蓝色代表踩线'
-	}
+	},
+	paperSubject:'试卷科目',
+	paperItemsCount:'试卷题数',
+	backUp:'返回上级'
 
 }

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

@@ -56,7 +56,7 @@ export default {
 		ruleClasses: '問卷對象不能為空',
 		ruleTime: '請設定起止時間',
 		ruleDate: '日期不能為空',
-		ruleStartTime: '開始時間不能早於當前時間'
+		ruleStartTime: '結束時間不能早於開始時間'
 	},
 	questionaire: {
 		noItemData: '暫無題目數據',

+ 31 - 25
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/totalAnalysis.js

@@ -3,15 +3,17 @@ export default {
 		title: '學情分析儀錶盤',
 		tab1: '統計資料',
 		tab2: '評測數據',
-		noData:'暫無有效數據返回!'
+		noData: '暫無有效數據返回!'
 	},
-	lostStu:'缺考人數',
-	showAnalysis:'資料分析',
-	allSubjects:'全科',
-	allClasses:'所有班級',
-	all:'全部',
-	classBaseInfo:'班級基本數據',
-	scoreRate:'得分率分佈圖',
+	rateLineTitle:'選項選答率分析',
+	R1R6LineTitle:'R1-R6作答曲線',
+	lostStu: '缺考人數',
+	showAnalysis: '資料分析',
+	allSubjects: '全科',
+	allClasses: '所有班級',
+	all: '全部',
+	classBaseInfo: '班級基本數據',
+	scoreRate: '得分率分佈圖',
 	// EvaluationList.vue
 	text1: '歷次考試匯總',
 	text2: '次數',
@@ -85,7 +87,7 @@ export default {
 	module5: '認知層次掌握',
 	exportTable: '匯出表格',
 	currentSubject: '當前科目',
-	goExamList:'查看更多評測',
+	goExamList: '查看更多評測',
 
 	// AchievementAnalysis.vue
 	ach_title1: '得分率統計',
@@ -254,22 +256,26 @@ export default {
 	ql_text13: '返回',
 	ql_text14: '連線題',
 	ql_text15: '改錯題',
-	
-	baseExport:{
-		title:'選擇要匯出的表格',
-		checkAll:'全選',
-		doExport:'匯出',
-		noCheckTip:'請選擇要匯出的表格!'
+
+	baseExport: {
+		title: '選擇要匯出的表格',
+		checkAll: '全選',
+		doExport: '匯出',
+		noCheckTip: '請選擇要匯出的表格!'
+	},
+	myTable: {
+		inner: '進',
+		outer: '踩',
+		rank: '排名統計',
+		option: '選項',
+		answerRate: '選答率',
+		answerCount: '選答人數',
+		RHRate: '高分組選答率',
+		RLRate: '低分組選答率',
+		tip: '*綠色代表進線,藍色代表踩線'
 	},
-	myTable:{
-		inner:'進',
-		outer:'踩',
-		rank:'排名統計',
-		option:'選項',
-		answerRate:'選答率',
-		RHRate:'高分組選答率',
-		RLRate:'低分組選答率',
-		tip:'*綠色代表進線,藍色代表踩線'
-	}
+	paperSubject: '試卷科目',
+	paperItemsCount: '試卷題數',
+	backUp: '返回上級'
 
 }

+ 519 - 358
TEAMModelOS/ClientApp/src/router/routes.js

@@ -89,368 +89,529 @@ export const routes = [
 			middleware: ['login', 'role:admin|teacher'], // 强制登录(会自动跳转到登录页),角色为管理员或教师
 		},
 		children: [{
-				name: 'totalIndex',
-				path: '/totalIndex',
-				component: resolve => require(['@/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue'], resolve),
-			},
-			{
-				name: 'total',
-				path: 'total',
-				component: resolve => require(['@/view/student-analysis/total-analysis/index.vue'], resolve),
-				children: [{
-						path: '/total',
-						component: resolve => require([
-							'@/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue'
-						], resolve)
-					},
-					{
-						path: '/total/evaluationList',
-						component: resolve => require(['@/view/student-analysis/total-analysis/EvaluationList/EvaluationList.vue'],
-							resolve),
-					},
-					{
-						path: '/total/achievement',
-						component: resolve => require([
-							'@/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue'
-						], resolve),
-					},
-					{
-						path: '/total/achievement/entryTables',
-						component: resolve => require(['@/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue'],
-							resolve),
-					},
-					{
-						path: '/total/achievement/earlyWarning',
-						component: resolve => require(['@/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue'],
-							resolve)
-					},
-					{
-						path: '/total/scatter',
-						component: resolve => require(['@/view/student-analysis/total-analysis/ScatterAnalysis/ScatterAnalysis.vue'],
-							resolve),
-					},
-					{
-						path: '/total/knowledge',
-						component: resolve => require([
-							'@/view/student-analysis/total-analysis/KnowledgeAnalysis/KnowledgeAnalysis.vue'
-						], resolve)
-					},
-					{
-						path: '/total/knowledge/details',
-						component: resolve => require(['@/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue'],
-							resolve)
-					},
-					{
-						path: '/total/cognitionLevel',
-						component: resolve => require(['@/view/student-analysis/total-analysis/LevelAnalysis/LevelAnalysis.vue'],
-							resolve)
-					},
-					{
-						path: '/total/cognitionLevel/details',
-						component: resolve => require(['@/view/student-analysis/total-analysis/LevelAnalysis/ScoreDetails.vue'],
-							resolve)
-					},
-					{
-						path: '/total/test',
-						component: resolve => require(['@/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue'],
-							resolve)
-					},
-					{
-						path: '/total/questionList',
-						component: resolve => require(['@/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue'],
-							resolve)
-					}
-				]
-			},
-			//校园基础数据管理
-			{
-				name: 'system',
-				path: 'system',
+			name: 'totalIndex',
+			path: '/totalIndex',
+			component: resolve => require(['@/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue'], resolve),
+			meta: {
+				activeName: 'totalIndex'
+			}
+		},
+		{
+			name: 'total',
+			path: 'total',
+			component: resolve => require(['@/view/student-analysis/total-analysis/index.vue'], resolve),
+			children: [{
+				path: '/total',
+				component: resolve => require([
+					'@/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue'
+				], resolve),
 				meta: {
-					middleware: ['login', 'ability:admin,schoolSetting-read|schoolSetting-upd']
-				},
-				component: resolve => require(['@/view/schoolmgmt/SystemSetting/SystemSetting.vue'], resolve)
+					activeName: 'totalIndex'
+				}
 			},
-			//班级教室管理
 			{
-				name: 'classroom',
-				path: 'classroom',
+				path: '/total/evaluationList',
+				component: resolve => require(['@/view/student-analysis/total-analysis/EvaluationList/EvaluationList.vue'],
+					resolve),
 				meta: {
-					middleware: ['login', 'ability:admin,classroom-read|classroom-upd']
-				},
-				component: resolve => require(['@/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue'], resolve)
+					activeName: 'totalIndex'
+				}
 			},
-			//学生账号管理
 			{
-				name: 'studentAccount',
-				path: 'studentAccount',
-				component: resolve => require(['@/view/student-account/Index.vue'], resolve),
+				path: '/total/achievement',
+				component: resolve => require([
+					'@/view/student-analysis/total-analysis/AchievementAnalysis/AchievementAnalysis.vue'
+				], resolve),
 				meta: {
-					middleware: ['login', 'ability:admin,student-read|student-upd']
-				},
-
+					activeName: 'totalIndex'
+				}
 			},
-			//教师账号
 			{
-				path: 'teachermgmt',
-				name: 'teachermgmt',
+				path: '/total/achievement/entryTables',
+				component: resolve => require(['@/view/student-analysis/total-analysis/AchievementAnalysis/EntryTables.vue'],
+					resolve),
 				meta: {
-					middleware: ['login', 'ability:admin,teacher-read|teacher-upd']
-				},
-				component: () => import('@/view/teachermgmt/Index.vue')
-			},
-			{
-				path: 'evaluation',
-				name: 'evaluation',
-				redirect: '/home/evaluation/testPaperList',
-				component: resolve => require(['@/view/evaluation/index/index.vue'], resolve),
-				children: [{
-						path: 'newSchoolExercise',
-						name: 'newSchoolExercise',
-						component: resolve => require(['@/view/evaluation/index/CreateExercises.vue'], resolve)
-					},
-					{
-						path: 'newPrivateExercise',
-						name: 'newPrivateExercise',
-						component: resolve => require(['@/view/evaluation/index/CreateExercises.vue'], resolve)
-					},
-					{
-						path: 'testPaper',
-						name: 'testPaper',
-						component: resolve => require(['@/view/evaluation/index/TestPaper.vue'], resolve)
-					},
-					{
-						path: 'testPaperList',
-						name: 'testPaperList',
-						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
-					},
-					{
-						path: 'schoolBank',
-						name: 'schoolBank',
-						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
-					},
-					{
-						path: 'personalBank',
-						name: 'personalBank',
-						component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve)
-					}
-				]
+					activeName: 'totalIndex'
+				}
 			},
 			{
-				path: 'newSchoolPaper',
-				name: 'newSchoolPaper',
-				component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve)
-			},
-			{
-				path: 'newPrivatePaper',
-				name: 'newPrivatePaper',
-				component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve)
+				path: '/total/achievement/earlyWarning',
+				component: resolve => require(['@/view/student-analysis/total-analysis/AchievementAnalysis/EarlyWarning.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
 			{
-				path: 'myCourse',
-				name: 'myCourse',
-				component: resolve => require(['@/view/newcourse/MyCourse.vue'], resolve)
+				path: '/total/scatter',
+				component: resolve => require(['@/view/student-analysis/total-analysis/ScatterAnalysis/ScatterAnalysis.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
-			//自定义名单管理页面
 			{
-				path: 'MgtStuList',
-				name: 'MgtStuList',
-				component: resolve => require(['@/view/newcourse/MgtStuList.vue'], resolve)
+				path: '/total/knowledge',
+				component: resolve => require([
+					'@/view/student-analysis/total-analysis/KnowledgeAnalysis/KnowledgeAnalysis.vue'
+				], resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
-			
-			//我的课程查看评测详细数据
 			{
-				path: 'EvDetail',
-				name: 'EvDetail',
-				component: resolve => require(['@/view/newcourse/EvDetail.vue'], resolve)
+				path: '/total/knowledge/details',
+				component: resolve => require(['@/view/student-analysis/total-analysis/KnowledgeAnalysis/ScoreDetails.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
-
-			//课程管理
 			{
-				path: 'ManageCourse',
-				name: 'ManageCourse',
-				component: resolve => require(['@/view/newcourse/ManageCourse.vue'], resolve)
+				path: '/total/cognitionLevel',
+				component: resolve => require(['@/view/student-analysis/total-analysis/LevelAnalysis/LevelAnalysis.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
-			//新版课程管理
 			{
-				path: 'NewCusMgt',
-				name: 'NewCusMgt',
-				component: resolve => require(['@/view/newcourse/NewCusMgt.vue'], resolve)
+				path: '/total/cognitionLevel/details',
+				component: resolve => require(['@/view/student-analysis/total-analysis/LevelAnalysis/ScoreDetails.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 			},
-			//课程时间管理
 			{
-				path: 'CourseTime',
-				name: 'CourseTime',
-				component: resolve => require(['@/view/newcourse/CourseTime.vue'], resolve)
-			},
+				path: '/total/test',
+				component: resolve => require(['@/view/student-analysis/total-analysis/TestAnalysis/TestAnalysis.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
 
-			//排课管理新版
-			{
-				path: 'NewCoursePlan',
-				name: 'NewCoursePlan',
-				component: resolve => require(['@/view/newcourse/NewCoursePlan.vue'], resolve)
 			},
-			//课程表版本排课
 			{
-				path: 'CoursePlan',
-				name: 'CoursePlan',
-				component: resolve => require(['@/view/newcourse/CoursePlan.vue'], resolve)
-			},
-			// 新课纲管理
-			{
-				path: 'syllabus',
-				name: 'syllabus',
-				component: resolve => require(['@/view/syllabus/newSyllabus/Index.vue'], resolve)
-			},
-			// 新课纲管理
-			{
-				path: 'personalSyllabus',
-				name: 'personalSyllabus',
-				component: resolve => require(['@/view/syllabus/newSyllabus/Index.vue'], resolve)
-			},
-			//校本资源管理
-			{
-				path: 'schoolcontent',
-				name: 'schoolcontent',
-				component: resolve => require(['@/view/teachcontent/index.vue'], resolve)
-			},
-			//个人内容管理
-			{
-				path: 'personalcontent',
-				name: 'personalcontent',
-				component: resolve => require(['@/view/teachcontent/index.vue'], resolve)
-			},
-			// 知识点管理
-			{
-				path: 'knowledge',
-				name: 'knowledge',
-				component: resolve => require(['@/view/knowledge-point/index/Index.vue'], resolve)
-			},
-			// 创建校本评测
-			{
-				path: 'createSchoolEva',
-				name: 'createSchoolEva',
-				component: resolve => require(['@/view/learnactivity/CreateSchoolEva.vue'], resolve)
-			},
-			// 创建个人评测
-			{
-				path: 'createPrivEva',
-				name: 'createPrivEva',
-				component: resolve => require(['@/view/learnactivity/CreatePrivEva.vue'], resolve)
-			},
-			//创建学习单元
-			{
-				path: 'createLearnUnit',
-				name: 'createLearnUnit',
-				component: resolve => require(['@/view/selflearn/CreateLearnUnit.vue'], resolve)
-			},
-			//创建作业活动
-			//{
-			//    path: 'createHomeWork',
-			//    name: 'createHomeWork',
-			//    component: resolve => require(['@/view/selflearning/CreateHomeWork.vue'], resolve)
-			//},
-			//创建编序式学习
-			{
-				path: 'createOrderLearn',
-				name: 'createOrderLearn',
-				component: resolve => require(['@/view/selflearn/CreateOrderLearn.vue'], resolve)
-			},
-			//管理评测页面(学校)
-			{
-				path: 'schoolEvaluation',
-				name: 'schoolEvaluation',
-				component: resolve => require(['@/view/learnactivity/MgtSchoolEva.vue'], resolve)
-			},
-			//管理评测页面(个人)
-			{
-				path: 'privateEvaluation',
-				name: 'privateEvaluation',
-				component: resolve => require(['@/view/learnactivity/MgtPrivEva.vue'], resolve)
-			},
-			//管理活动记录页面
-			{
-				path: 'manageRecord',
-				name: 'manageRecord',
-				component: resolve => require(['@/view/learnactivity/ManageRecord.vue'], resolve)
+				path: '/total/questionList',
+				component: resolve => require(['@/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue'],
+					resolve),
+				meta: {
+					activeName: 'totalIndex'
+				}
+			}
+			]
+		},
+		//校园基础数据管理
+		{
+			name: 'system',
+			path: 'system',
+			meta: {
+				middleware: ['login', 'ability:admin,schoolSetting-read|schoolSetting-upd'],
+				activeName: 'system'
 			},
-			//管理问卷调查
-			{
-				path: 'manageQuestionnaire',
-				name: 'manageQuestionnaire',
-				component: resolve => require(['@/view/questionnaire/ManageQuestionnaire.vue'], resolve)
+			component: resolve => require(['@/view/schoolmgmt/SystemSetting/SystemSetting.vue'], resolve)
+		},
+		//班级教室管理
+		{
+			name: 'classroom',
+			path: 'classroom',
+			meta: {
+				middleware: ['login', 'ability:admin,classroom-read|classroom-upd'],
+				activeName: 'classroom'
 			},
-			//管理问卷调查
-			{
-				path: 'personalSurvey',
-				name: 'personalSurvey',
-				component: resolve => require(['@/view/questionnaire/ManageQuestionnaire.vue'], resolve)
+			component: resolve => require(['@/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue'], resolve)
+		},
+		//学生账号管理
+		{
+			name: 'studentAccount',
+			path: 'studentAccount',
+			component: resolve => require(['@/view/student-account/Index.vue'], resolve),
+			meta: {
+				middleware: ['login', 'ability:admin,student-read|student-upd'],
+				activeName: 'studentAccount'
 			},
-			//新版自主学习
-			{
-				path: 'SelfLearn',
-				name: 'selfLearn',
-				component: resolve => require(['@/view/selflearn/SelfLearn.vue'], resolve)
+
+		},
+		//教师账号
+		{
+			path: 'teachermgmt',
+			name: 'teachermgmt',
+			meta: {
+				middleware: ['login', 'ability:admin,teacher-read|teacher-upd']
 			},
-			{
-				path: 'manageHomeWork',
-				name: 'manageHomeWork',
-				component: resolve => require(['@/view/homework/ManageHomeWork.vue'], resolve)
+			component: () => import('@/view/teachermgmt/Index.vue'),
+			meta: {
+				activeName: 'teachermgmt'
 			},
-			{
-				path: 'manageVote',
-				name: 'manageVote',
-				component: resolve => require(['@/view/vote/ManageVote.vue'], resolve)
+		},
+		{
+			path: 'evaluation',
+			name: 'evaluation',
+			redirect: '/home/evaluation/testPaperList',
+			meta: {
+				activeName: 'schoolBank'
 			},
-			{
-				path: 'personalVote',
-				name: 'personalVote',
-				component: resolve => require(['@/view/vote/ManageVote.vue'], resolve)
+			component: resolve => require(['@/view/evaluation/index/index.vue'], resolve),
+			children: [{
+				path: 'newSchoolExercise',
+				name: 'newSchoolExercise',
+				component: resolve => require(['@/view/evaluation/index/CreateExercises.vue'], resolve),
+				meta: {
+					activeName: 'schoolBank'
+				},
 			},
-			//主页
 			{
-				path: 'homePage',
-				name: 'homePage',
-				component: resolve => require(['@/view/homepage/HomePage.vue'], resolve)
+				path: 'newPrivateExercise',
+				name: 'newPrivateExercise',
+				component: resolve => require(['@/view/evaluation/index/CreateExercises.vue'], resolve),
+				meta: {
+					activeName: 'personalBank'
+				},
 			},
-			//班级管理
 			{
-				path: 'manageClass',
-				name: 'manageClass',
-				component: resolve => require(['@/view/classmgt/ManageClass.vue'], resolve)
+				path: 'testPaper',
+				name: 'testPaper',
+				component: resolve => require(['@/view/evaluation/index/TestPaper.vue'], resolve),
+				meta: {
+					activeName: 'schoolBank'
+				},
 			},
-			//用户反馈
 			{
-				path: 'feedback',
-				name: 'feedback',
-				component: resolve => require(['@/view/feedback/Feedback.vue'], resolve)
+				path: 'testPaperList',
+				name: 'testPaperList',
+				component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve),
+				meta: {
+					activeName: 'schoolBank'
+				},
 			},
-			//设置
 			{
-				path: 'settings',
-				name: 'settings',
-				component: resolve => require(['@/view/settings/Index.vue'], resolve)
+				path: 'schoolBank',
+				name: 'schoolBank',
+				component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve),
+				meta: {
+					activeName: 'schoolBank'
+				},
 			},
-			//课堂记录
 			{
-				path: 'classRecord',
-				name: 'classRecord',
-				component: resolve => require(['@/view/classrecord/ClassRecord.vue'], resolve)
-			},
+				path: 'personalBank',
+				name: 'personalBank',
+				component: resolve => require(['@/view/evaluation/bank/index.vue'], resolve),
+				meta: {
+					activeName: 'personalBank'
+				}
+			}
+			]
+		},
+		{
+			path: 'newSchoolPaper',
+			name: 'newSchoolPaper',
+			component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve),
+			meta: {
+				activeName: 'schoolBank'
+			}
+		},
+		{
+			path: 'newPrivatePaper',
+			name: 'newPrivatePaper',
+			component: resolve => require(['@/view/evaluation/index/CreatePaper.vue'], resolve),
+			meta: {
+				activeName: 'personalBank'
+			}
+		},
+		{
+			path: 'myCourse',
+			name: 'myCourse',
+			component: resolve => require(['@/view/newcourse/MyCourse.vue'], resolve),
+			meta: {
+				activeName: 'myCourse',
+				isKeep: true
+			}
+		},
+		//自定义名单管理页面
+		{
+			path: 'MgtStuList',
+			name: 'MgtStuList',
+			component: resolve => require(['@/view/newcourse/MgtStuList.vue'], resolve),
+			meta: {
+				activeName: 'myCourse'
+			}
+		},
 
-			//Louise的智能教室使用分析儀表板
-			{
-				path: 'scboard',
-				name: 'scboard',
-				component: resolve => require(['@/view/scboard/Index.vue'], resolve)
-			},
+		//我的课程查看评测详细数据
+		{
+			path: 'EvDetail',
+			name: 'EvDetail',
+			component: resolve => require(['@/view/newcourse/EvDetail.vue'], resolve),
+			meta: {
+				activeName: 'myCourse'
+			}
+		},
 
-			//Louise的教師儲存空間授權管理分頁
-			{
-				path: 'serviceDriveAuth',
-				name: 'serviceDriveAuth',
-				component: resolve => require(['@/view/serviceDriveAuth/Index.vue'], resolve)
+		//课程管理(废弃)
+		{
+			path: 'ManageCourse',
+			name: 'ManageCourse',
+			component: resolve => require(['@/view/newcourse/ManageCourse.vue'], resolve)
+		},
+		//新版课程管理
+		{
+			path: 'NewCusMgt',
+			name: 'NewCusMgt',
+			component: resolve => require(['@/view/newcourse/NewCusMgt.vue'], resolve),
+			meta: {
+				activeName: 'NewCusMgt'
+			}
+		},
+		//课程时间管理(废弃)
+		{
+			path: 'CourseTime',
+			name: 'CourseTime',
+			component: resolve => require(['@/view/newcourse/CourseTime.vue'], resolve)
+		},
+
+		//排课管理新版(废弃)
+		{
+			path: 'NewCoursePlan',
+			name: 'NewCoursePlan',
+			component: resolve => require(['@/view/newcourse/NewCoursePlan.vue'], resolve)
+		},
+		//课程表版本排课
+		{
+			path: 'CoursePlan',
+			name: 'CoursePlan',
+			component: resolve => require(['@/view/newcourse/CoursePlan.vue'], resolve),
+			meta: {
+				activeName: 'NewCusMgt'
+			}
+		},
+		// 新课纲管理
+		{
+			path: 'syllabus',
+			name: 'syllabus',
+			component: resolve => require(['@/view/syllabus/newSyllabus/Index.vue'], resolve),
+			meta: {
+				activeName: 'syllabus'
+			}
+		},
+		// 新课纲管理
+		{
+			path: 'personalSyllabus',
+			name: 'personalSyllabus',
+			component: resolve => require(['@/view/syllabus/newSyllabus/Index.vue'], resolve),
+			meta: {
+				activeName: 'personalSyllabus'
+			}
+		},
+		//校本资源管理
+		{
+			path: 'schoolcontent',
+			name: 'schoolcontent',
+			component: resolve => require(['@/view/teachcontent/index.vue'], resolve),
+			meta: {
+				activeName: 'schoolcontent'
 			}
+		},
+		//个人内容管理
+		{
+			path: 'personalcontent',
+			name: 'personalcontent',
+			component: resolve => require(['@/view/teachcontent/index.vue'], resolve),
+			meta: {
+				activeName: 'personalcontent'
+			}
+		},
+		// 知识点管理
+		{
+			path: 'knowledge',
+			name: 'knowledge',
+			component: resolve => require(['@/view/knowledge-point/index/Index.vue'], resolve),
+			meta: {
+				activeName: 'knowledge'
+			}
+		},
+		// 创建校本评测
+		{
+			path: 'createSchoolEva',
+			name: 'createSchoolEva',
+			component: resolve => require(['@/view/learnactivity/CreateSchoolEva.vue'], resolve),
+			meta: {
+				activeName: 'schoolEvaluation'
+			}
+		},
+		// 创建个人评测
+		{
+			path: 'createPrivEva',
+			name: 'createPrivEva',
+			component: resolve => require(['@/view/learnactivity/CreatePrivEva.vue'], resolve),
+			meta: {
+				activeName: 'privateEvaluation'
+			}
+		},
+		//创建学习单元
+		{
+			path: 'createLearnUnit',
+			name: 'createLearnUnit',
+			component: resolve => require(['@/view/selflearn/CreateLearnUnit.vue'], resolve),
+			meta: {
+				activeName: 'selfLearn'
+			}
+		},
+		//创建作业活动
+		//{
+		//    path: 'createHomeWork',
+		//    name: 'createHomeWork',
+		//    component: resolve => require(['@/view/selflearning/CreateHomeWork.vue'], resolve)
+		//},
+		//创建编序式学习
+		{
+			path: 'createOrderLearn',
+			name: 'createOrderLearn',
+			component: resolve => require(['@/view/selflearn/CreateOrderLearn.vue'], resolve),
+			meta: {
+				activeName: 'selfLearn'
+			}
+		},
+		//管理评测页面(学校)
+		{
+			path: 'schoolEvaluation',
+			name: 'schoolEvaluation',
+			component: resolve => require(['@/view/learnactivity/MgtSchoolEva.vue'], resolve),
+			meta: {
+				activeName: 'schoolEvaluation'
+			}
+		},
+		//管理评测页面(个人)
+		{
+			path: 'privateEvaluation',
+			name: 'privateEvaluation',
+			component: resolve => require(['@/view/learnactivity/MgtPrivEva.vue'], resolve),
+			meta: {
+				activeName: 'privateEvaluation'
+			}
+		},
+		//管理活动记录页面(暂未使用)
+		{
+			path: 'manageRecord',
+			name: 'manageRecord',
+			component: resolve => require(['@/view/learnactivity/ManageRecord.vue'], resolve)
+		},
+		//管理问卷调查
+		{
+			path: 'manageQuestionnaire',
+			name: 'manageQuestionnaire',
+			component: resolve => require(['@/view/questionnaire/ManageQuestionnaire.vue'], resolve),
+			meta: {
+				activeName: 'manageQuestionnaire'
+			}
+		},
+		//管理问卷调查
+		{
+			path: 'personalSurvey',
+			name: 'personalSurvey',
+			component: resolve => require(['@/view/questionnaire/ManageQuestionnaire.vue'], resolve),
+			meta: {
+				activeName: 'personalSurvey'
+			}
+		},
+		//新版自主学习
+		{
+			path: 'SelfLearn',
+			name: 'selfLearn',
+			component: resolve => require(['@/view/selflearn/SelfLearn.vue'], resolve),
+			meta: {
+				activeName: 'selfLearn'
+			}
+		},
+		{
+			path: 'manageHomeWork',
+			name: 'manageHomeWork',
+			component: resolve => require(['@/view/homework/ManageHomeWork.vue'], resolve),
+			meta: {
+				activeName: 'manageHomeWork'
+			}
+		},
+		{
+			path: 'manageVote',
+			name: 'manageVote',
+			component: resolve => require(['@/view/vote/ManageVote.vue'], resolve),
+			meta: {
+				activeName: 'manageVote'
+			}
+		},
+		{
+			path: 'personalVote',
+			name: 'personalVote',
+			component: resolve => require(['@/view/vote/ManageVote.vue'], resolve),
+			meta: {
+				activeName: 'personalVote'
+			}
+		},
+		//主页
+		{
+			path: 'homePage',
+			name: 'homePage',
+			component: resolve => require(['@/view/homepage/HomePage.vue'], resolve),
+			meta: {
+				activeName: 'homePage'
+			}
+		},
+		//班级管理
+		{
+			path: 'manageClass',
+			name: 'manageClass',
+			component: resolve => require(['@/view/classmgt/ManageClass.vue'], resolve),
+			meta: {
+				activeName: 'manageClass'
+			}
+		},
+		//用户反馈
+		{
+			path: 'feedback',
+			name: 'feedback',
+			component: resolve => require(['@/view/feedback/Feedback.vue'], resolve),
+			meta: {
+				activeName: 'feedback'
+			}
+		},
+		//设置
+		{
+			path: 'settings',
+			name: 'settings',
+			component: resolve => require(['@/view/settings/Index.vue'], resolve),
+			meta: {
+				activeName: 'settings'
+			}
+		},
+		//课堂记录
+		{
+			path: 'classRecord',
+			name: 'classRecord',
+			component: resolve => require(['@/view/classrecord/ClassRecord.vue'], resolve),
+			meta: {
+				activeName: 'myCourse'
+			}
+		},
+
+		//Louise的智能教室使用分析儀表板
+		{
+			path: 'scboard',
+			name: 'scboard',
+			component: resolve => require(['@/view/scboard/Index.vue'], resolve),
+			meta: {
+				activeName: 'scboard'
+			}
+		},
+
+		//Louise的教師儲存空間授權管理分頁
+		{
+			path: 'serviceDriveAuth',
+			name: 'serviceDriveAuth',
+			component: resolve => require(['@/view/serviceDriveAuth/Index.vue'], resolve),
+			meta: {
+				activeName: 'serviceDriveAuth'
+			}
+		}
 		]
 	},
 	//学生端
@@ -466,48 +627,48 @@ export const routes = [
 		children: [{
 			name: "homeView",
 			path: "homeView",
-				component: resolve => require(['@/components/student-web/HomeView/HomeView'], resolve),
-			},
-			{
-				name: "courseList",
-				path: "courseList",
-				component: resolve => require(['@/components/student-web/HomeView/CourseListView'], resolve),
-			},
-			{
-				name: "setting",
-				path: "setting",
-				component: resolve => require(['@/components/student-web/SettingView/SettingView'], resolve),
-			},
-			{
-				name: "eventView",
-				path: "eventView",
-				component: resolve => require(['@/components/student-web/EventView/EventView'], resolve),
-			},
-			{
-				name: "eventView/:name",
-				path: "eventView/:name",
-				component: resolve => require(['@/components/student-web/EventView/EventView'], resolve),
-			},
-			{
-				name: "eventLatest",
-				path: "eventLatest",
-				component: resolve => require(['@/components/student-web/EventView/EventOverView/EventLatest'], resolve),
-			},
-			{
-				name: "studyView",
-				path: "studyView",
-				component: resolve => require(['@/components/student-web/StudyView/StudyView'], resolve),
-			},
-			{
-				name: "hiteachView",
-				path: "hiteachView",
-				component: resolve => require(['@/components/student-web/HiteachView/HiteachView'], resolve),
-			},
-			{
-				name: "informView",
-				path: "informView",
-				component: resolve => require(['@/components/student-web/InformView/InformView'], resolve),
-			}
+			component: resolve => require(['@/components/student-web/HomeView/HomeView'], resolve),
+		},
+		{
+			name: "courseList",
+			path: "courseList",
+			component: resolve => require(['@/components/student-web/HomeView/CourseListView'], resolve), //是元件不用''
+		},
+		{
+			name: "setting",
+			path: "setting",
+			component: resolve => require(['@/components/student-web/SettingView/SettingView'], resolve), //是元件不用'
+		},
+		{
+			name: "eventView",
+			path: "eventView",
+			component: resolve => require(['@/components/student-web/EventView/EventView'], resolve),
+		},
+		{
+			name: "eventView/:name",
+			path: "eventView/:name",
+			component: resolve => require(['@/components/student-web/EventView/EventView'], resolve),
+		},
+		{
+			name: "eventLatest",
+			path: "eventLatest",
+			component: resolve => require(['@/components/student-web/EventView/EventOverView/EventLatest'], resolve),
+		},
+		{
+			name: "studyView",
+			path: "studyView",
+			component: resolve => require(['@/components/student-web/StudyView/StudyView'], resolve),
+		},
+		{
+			name: "hiteachView",
+			path: "hiteachView",
+			component: resolve => require(['@/components/student-web/HiteachView/HiteachView'], resolve),
+		},
+		{
+			name: "informView",
+			path: "informView",
+			component: resolve => require(['@/components/student-web/InformView/InformView'], resolve),
+		}
 		]
 	}
 ]

+ 13 - 11
TEAMModelOS/ClientApp/src/utils/public.js

@@ -651,7 +651,7 @@ export default {
 		}
 		return true;
 	},
-
+	/* 学情认知层次模块数据转换 */
 	getLevelStuPercent(val, subjectIndex, index) {
 		let result = []
 		val.students.forEach(stu => {
@@ -667,15 +667,15 @@ export default {
 		})
 		return result
 	},
-
+	/* 学情认知层次年级班级得分率数据转换 */
 	getLevelClassPercent(val, subjectIndex, index) {
 		let result = []
 		val.classes.forEach(classItem => {
-			result.push(classItem.subjects[subjectIndex].field[index])
+			result.push(classItem.subjects[subjectIndex].field.map((score,index) => Number(score / val.fieldwrong[subjectIndex].value[index][1]) * 100)[index])
 		})
 		return result
 	},
-
+	/* 学情认知层次年级班级得分率数据转换 */
 	getLevelPercent(val, subjectIndex) {
 		let stuResult = {}
 		let classResult = {}
@@ -683,10 +683,10 @@ export default {
 			stuResult[item] = this.getLevelStuPercent(val, subjectIndex, index)
 			classResult[item] = this.getLevelClassPercent(val, subjectIndex, index)
 		})
-		stuResult.grade = val.fieldAllPer[subjectIndex].value
+		stuResult.grade = val.fieldAllPer[subjectIndex].value.map((score,index) => Number(score / val.fieldwrong[subjectIndex].value[index][1]) * 100)
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
-		classResult.className = []
+		classResult.className = val.classes.map(i => i.className)
 		let obj = {
 			stuResult: stuResult,
 			classResult: classResult
@@ -710,15 +710,16 @@ export default {
 		})
 		return result
 	},
-
+	/* 学情知识点班级得分率数据转换 */
 	getKnowClassPercent(val, subjectIndex, index) {
 		let result = []
 		val.classes.forEach(classItem => {
-			result.push(classItem.subjects[subjectIndex].point[index])
+			// 取当前班级在每个知识点的得分 除以知识点的总分 得到每个班在该知识点的得分率 index=>知识点下标
+			result.push(classItem.subjects[subjectIndex].point.map((score,pointIndex) => Number(score / val.wrong[subjectIndex].value[pointIndex][1]) * 100)[index])
 		})
 		return result
 	},
-
+	/* 学情知识点年级班级得分率数据转换 */
 	getKnowPercent(val, subjectIndex) {
 		let stuResult = {}
 		let classResult = {}
@@ -726,10 +727,11 @@ export default {
 			stuResult[item] = this.getKnowStuPercent(val, subjectIndex, index)
 			classResult[item] = this.getKnowClassPercent(val, subjectIndex, index)
 		})
-		stuResult.grade = val.knowAllper[subjectIndex].value
+		// 取当前年级在每个知识点的得分 除以知识点的总分 得到年级在该知识点的得分率
+		stuResult.grade = val.knowAllper[subjectIndex].value.map((score,index) => Number(score / val.wrong[subjectIndex].value[index][1]) * 100)
 		stuResult.keys = val.knowKey
 		classResult.keys = val.knowkey
-		classResult.className = []
+		classResult.className = val.classes.map(i => i.className)
 		let obj = {
 			stuResult: stuResult,
 			classResult: classResult

+ 193 - 190
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -4,225 +4,228 @@
         <BaseLayout>
             <!-- 头部右侧个人中心部分 -->
             <div class="header-right-box fl-around" slot="header-content">
-                <Icon custom="iconfont icon-home" :color="routerName == 'homePage' ? '#1CC0F3':'#d0d0d0'" @click="toHome"/>
-				<BaseNotification></BaseNotification>
-                <Icon type="ios-settings" :color="routerName == 'settings' ? '#1CC0F3':'#d0d0d0'" @click="toSettings"/>
+                <Icon custom="iconfont icon-home" :color="routerName == 'homePage' ? '#1CC0F3':'#d0d0d0'" @click="toHome" />
+                <BaseNotification></BaseNotification>
+                <Icon type="ios-settings" :color="routerName == 'settings' ? '#1CC0F3':'#d0d0d0'" @click="toSettings" />
                 <!-- 问题答疑页面暂未开发 暂时注释 -->
-				<!-- <Icon type="md-help-circle" :color="routerName == 'feedback' ? '#1CC0F3':'#d0d0d0'" @click="toFeedback"/> -->
-				<BaseUserPoptip @logout="basicMenu('quit')"></BaseUserPoptip>
+                <!-- <Icon type="md-help-circle" :color="routerName == 'feedback' ? '#1CC0F3':'#d0d0d0'" @click="toFeedback"/> -->
+                <BaseUserPoptip @logout="basicMenu('quit')"></BaseUserPoptip>
             </div>
             <div id="content" class="custom-scroll-bar" slot="content">
-                <router-view :key="this.$route.name"></router-view>
+                <router-view v-if="!$route.meta.isKeep" :key="this.$route.name"></router-view>
+                <keep-alive>
+                    <router-view v-if="$route.meta.isKeep" :key="this.$route.name"></router-view>
+                </keep-alive>
             </div>
         </BaseLayout>
     </div>
 </template>
 
 <script>
-    export default {
-        name: 'headers',
-        props: ['parentToChild', 'identityselect'],
-        components: { },
-        computed: {
+export default {
+    name: 'headers',
+    props: ['parentToChild', 'identityselect'],
+    components: {},
+    computed: {
+
+    },
+    data() {
+        return {
+            isShowMock: false,
+            isOpenDrawer: false,
+            routerName: '',
+            isLoading: false
+        }
+    },
+    created() {
+        //刷新重置vuex
+        console.log('进入大云...')
+        console.log(this.$store)
+
+        //  window.addEventListener('beforeunload',() => {
+        //     if(this.$store.state.user.school_profile.school_base){
+        //         schoolStr = encodeURIComponent(JSON.stringify(this.$store.state.user.school_profile.school_base), "utf-8")
+        //         localStorage.setItem('school_profile', schoolStr)
+        //     }
+        // })
+
+        let user = JSON.parse(decodeURIComponent(localStorage.userInfo, "utf-8"))
+        let user_profile = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"))
+        if (user_profile.schools) {
+            user_profile.schools = user_profile.schools.filter((item) => {
+                return item.status == 'join'
+            })
+        } else {
+            user_profile.schools = []
+        }
+        if (user_profile.schools.length) {
+            this.$store.commit('setUserInfo', {
+                TEAMModelId: user.id,
+                name: user.name,
+                schoolCode: user_profile.defaultschool || user_profile.schools[0].schoolId
+            })
+        } else {
+            this.$store.commit('setUserInfo', {
+                TEAMModelId: user.id,
+                name: user.name,
+                schoolCode: this.$GLOBAL.DEFAULT_SCHOOL_CODE
+            })
+        }
 
-        },
-        data() {
-            return {
-				isShowMock:false,
-                isOpenDrawer: false,
-                routerName: '',
-                isLoading: false
-            }
-        },
-        created() {
-            //刷新重置vuex
-            console.log('进入大云...')
-            console.log(this.$store)
-
-            //  window.addEventListener('beforeunload',() => {
-            //     if(this.$store.state.user.school_profile.school_base){
-            //         schoolStr = encodeURIComponent(JSON.stringify(this.$store.state.user.school_profile.school_base), "utf-8")
-            //         localStorage.setItem('school_profile', schoolStr)
-            //     }
-            // })
-            
-            let user = JSON.parse(decodeURIComponent(localStorage.userInfo, "utf-8"))
-            let user_profile = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"))
-            if (user_profile.schools) {
-                user_profile.schools = user_profile.schools.filter((item) => {
-                    return item.status == 'join'
-                })
-            } else {
-                user_profile.schools = []
-            }
-            if (user_profile.schools.length) {
-                this.$store.commit('setUserInfo', {
-                    TEAMModelId: user.id,
-                    name: user.name,
-                    schoolCode: user_profile.defaultschool || user_profile.schools[0].schoolId
-                })
-            } else {
-                this.$store.commit('setUserInfo', {
-                    TEAMModelId: user.id,
-                    name: user.name,
-                    schoolCode: this.$GLOBAL.DEFAULT_SCHOOL_CODE
-                })
-            }
 
 
-            
+    },
+    methods: {
+        toHome() {
+            this.$router.push({ path: '/home/homePage' })
         },
-        methods: {
-            toHome() {
-                this.$router.push({ path: '/home/homePage' })
-            },
-			toSettings(){
-				this.$router.push({ path: '/home/settings' })
-			},
-            toFeedback() {
-                this.$router.push({ path: '/home/feedback' })
-            },
-            closeMenu() {
-                this.isOpenDrawer = false
-            },
-            basicMenu(name) {
-                if (name == 'quit') {
+        toSettings() {
+            this.$router.push({ path: '/home/settings' })
+        },
+        toFeedback() {
+            this.$router.push({ path: '/home/feedback' })
+        },
+        closeMenu() {
+            this.isOpenDrawer = false
+        },
+        basicMenu(name) {
+            if (name == 'quit') {
                 //     localStorage.removeItem('access_token')
                 //     localStorage.removeItem('expires_in')
                 //     localStorage.removeItem('userInfo')
                 //     localStorage.removeItem('userAccess')
                 //     localStorage.removeItem('user_details')
-				this.$store.commit('user/resetSchoolProfile')
-                    this.$User.logout()
-                    this.$router.push({
-                        path: '/login'
-                    })
-                }
-            }
-        },
-        mounted() {
-			
-			if(localStorage.getItem('noSave') && JSON.parse(localStorage.getItem('noSave')).length){
-				this.$tools.deleteNoSave(JSON.parse(localStorage.getItem('noSave')))
-			}else{
-				localStorage.setItem('noSave','[]')
-			}
-			
-			this.$EventBus.$off('onGlobalLoading')
-			this.$EventBus.$on('onGlobalLoading', val => {
-				this.isLoading = val
-            })
-            
-			this.$EventBus.$off('noSave')
-			this.$EventBus.$on('noSave', val => {
-				let curNoSaveArr = JSON.parse(localStorage.getItem('noSave'))
-				curNoSaveArr.push(val)
-				localStorage.setItem('noSave',JSON.stringify(curNoSaveArr))
-			})
-           
-        },
-        watch: {
-            $route: {
-                handler(val, oldval) {
-                    this.routerName = val.name
-                },
-                // 深度观察监听
-                deep: true,
-                //立即执行
-                immediate: true
+                this.$store.commit('user/resetSchoolProfile')
+                this.$User.logout()
+                this.$router.push({
+                    path: '/login'
+                })
             }
         }
-    }
-</script>
-
-<style scoped>
-    .header-right-box {
-        width: 400px;
-        margin: 12px;
-        line-height: 1.5;
-        float: right;
-    }
+    },
+    mounted() {
 
-        .header-right-box .ivu-icon {
-            font-size: 22px;
-            color: #d0d0d0;
-            cursor: pointer;
+        if (localStorage.getItem('noSave') && JSON.parse(localStorage.getItem('noSave')).length) {
+            this.$tools.deleteNoSave(JSON.parse(localStorage.getItem('noSave')))
+        } else {
+            localStorage.setItem('noSave', '[]')
         }
 
-        .header-right-box img {
-            width: 40px;
-            border-radius: 50%;
-            border: 2px solid #595959;
+        this.$EventBus.$off('onGlobalLoading')
+        this.$EventBus.$on('onGlobalLoading', val => {
+            this.isLoading = val
+        })
+
+        this.$EventBus.$off('noSave')
+        this.$EventBus.$on('noSave', val => {
+            let curNoSaveArr = JSON.parse(localStorage.getItem('noSave'))
+            curNoSaveArr.push(val)
+            localStorage.setItem('noSave', JSON.stringify(curNoSaveArr))
+        })
+
+    },
+    watch: {
+        $route: {
+            handler(val, oldval) {
+                this.routerName = val.name
+            },
+            // 深度观察监听
+            deep: true,
+            //立即执行
+            immediate: true
         }
-
-    .fl-around {
-        display: flex;
-        align-items: center;
-        justify-content: space-around;
     }
+}
+</script>
+
+<style scoped>
+.header-right-box {
+    width: 400px;
+    margin: 12px;
+    line-height: 1.5;
+    float: right;
+}
+
+.header-right-box .ivu-icon {
+    font-size: 22px;
+    color: #d0d0d0;
+    cursor: pointer;
+}
+
+.header-right-box img {
+    width: 40px;
+    border-radius: 50%;
+    border: 2px solid #595959;
+}
+
+.fl-around {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+}
 </style>
 
 <style>
-
-    html, body {
-        height: 100%;
-        width:100%;
-        margin: 0px;
-        padding: 0px;
-    }
-
-    #main {
-        width: 100%;
-        height: 100%;
-    }
-
-        #main .layout {
-            border: none;
-            border-radius: 0px;
-        }
-
-    #content {
-        height: 100%;
-        /*background: #2B2B2E;*/
-		overflow: hidden;
-    }
-
-    /*重绘滚动条样式*/
-    .scrollstyle::-webkit-scrollbar {
-        width: 5px;
-    }
-
-    .ivu-drawer-body::-webkit-scrollbar-track {
-        display: none;
-    }
-
-    .scrollstyle::-webkit-scrollbar-thumb {
-        border-radius: 10px;
-        background: #94998a;
-    }
-
-    .scrollstyle::-webkit-scrollbar-button {
-        display: none;
-    }
+html,
+body {
+    height: 100%;
+    width: 100%;
+    margin: 0px;
+    padding: 0px;
+}
+
+#main {
+    width: 100%;
+    height: 100%;
+}
+
+#main .layout {
+    border: none;
+    border-radius: 0px;
+}
+
+#content {
+    height: 100%;
+    /*background: #2B2B2E;*/
+    overflow: hidden;
+}
+
+/*重绘滚动条样式*/
+.scrollstyle::-webkit-scrollbar {
+    width: 5px;
+}
+
+.ivu-drawer-body::-webkit-scrollbar-track {
+    display: none;
+}
+
+.scrollstyle::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    background: #94998a;
+}
+
+.scrollstyle::-webkit-scrollbar-button {
+    display: none;
+}
 </style>
 
 <style lang="less">
-    @import '../css/dark-iview-modal.less';
-    @import '../css/dark-iview-tabs.less';
-    @import '../css/dark-iview-collapse.less';
-    @import '../css/dark-iview-form.less';
-    @import '../css/dark-iview-upload.less';
-    @import '../css/dark-iview-table.less';
-    @import '../css/dark-iview-split.less';
-    @import '../css/dark-iview-page.less';
-    @import '../css/custom-animate.less';
-    @import '../css/dark-wang-editor.less';
-    @import '../css/dark-iview-loading.less';
-    @import '../css/disabled-iview-form.less';
-    @import '../css/common-style.less';
-    @import '../css/dark-iview-drawer.less';
-    @import '../css/dark-iview-card.less';
-    @import '../css/dark-iview-poptip.less';
-    @import '../css/dark-iview-checkbox.less';
-    @import '../css/dark-el-cascader.less';
+@import "../css/dark-iview-modal.less";
+@import "../css/dark-iview-tabs.less";
+@import "../css/dark-iview-collapse.less";
+@import "../css/dark-iview-form.less";
+@import "../css/dark-iview-upload.less";
+@import "../css/dark-iview-table.less";
+@import "../css/dark-iview-split.less";
+@import "../css/dark-iview-page.less";
+@import "../css/custom-animate.less";
+@import "../css/dark-wang-editor.less";
+@import "../css/dark-iview-loading.less";
+@import "../css/disabled-iview-form.less";
+@import "../css/common-style.less";
+@import "../css/dark-iview-drawer.less";
+@import "../css/dark-iview-card.less";
+@import "../css/dark-iview-poptip.less";
+@import "../css/dark-iview-checkbox.less";
+@import "../css/dark-el-cascader.less";
 </style>

+ 50 - 8
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue

@@ -24,7 +24,7 @@
 
 
 			<transition name="slide">
-				<div v-show="collapseList.indexOf(children.indexOf(item)) > -1" class="toggle-area">
+				<div v-if="collapseList.includes(children.indexOf(item))" class="toggle-area">
 					<!-- 答案展示部分 -->
 					<div class="item-explain">
 						<span class="explain-title">【{{$t('evaluation.answer')}}】</span>
@@ -67,7 +67,19 @@
 					<div class="item-explain" v-if="isShowAnalysis">
 						<span class="explain-title">【{{ $t('totalAnalysis.showAnalysis') }}】</span>
 						<div class="item-explain-details">
-							<OptionsTable></OptionsTable>
+							<AnalysisItemTable :analysisJson="analysisJson[index]"></AnalysisItemTable>
+							</br>
+							<OptionsTable v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'" 
+							:options="item.option.map(i => i.code)" :optionRate="optionRate[index]" :answer="item.answer"></OptionsTable>
+							</br>
+							<Row>
+							 <Col span="12" v-if="item.type === 'single' || item.type === 'multiple' || item.type === 'judge'">
+								<BaseRateLine :ids="'cR1' + item.id" :echartsData="getOptionLineData(item,index)"></BaseRateLine>
+							 </Col>
+							 <Col span="12">
+								<BaseLine :ids="'cr' + item.id" :echartsData="analysisJson[index]"></BaseLine>
+							 </Col>
+							</Row>
 						</div>
 					</div>
 				</div>
@@ -78,10 +90,13 @@
 </template>
 <script>
 	import '@/utils/Math.uuid'
+	import AnalysisItemTable from '@/components/evaluation/AnalysisItemTable'
 	import OptionsTable from '@/components/evaluation/OptionsTable'
+	import BaseLine from '@/components/student-analysis/total/BaseLine.vue'
+	import BaseRateLine from '@/components/student-analysis/total/BaseRateLine.vue'
 	export default {
 		name: 'BaseChild',
-		components: { OptionsTable },
+		components: { AnalysisItemTable,OptionsTable,BaseRateLine,BaseLine },
 		props: {
 			children: {
 				type: Array,
@@ -91,6 +106,18 @@
 				type: Number,
 				default: 0
 			},
+			analysisJson:{
+				type:Array,
+				default:() => {
+					return []
+				}
+			},
+			optionRate:{
+				type:Array,
+				default:() => {
+					return []
+				}
+			},
 			isShowScore: {
 				type: Boolean,
 				default: false
@@ -118,9 +145,23 @@
 
 		},
 		methods: {
-			/* 给小题配分 */
-			doDistribution() {
-
+			getOptionLineData(item,index){
+				let result = []
+				console.log(this.optionRate)
+				let n = this.optionRate[index]
+				let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
+				let phCount = Math.floor(total * 0.27) //取高分组人数
+				let plCount = Math.ceil(total * 0.27) //取低分组人数
+				item.option.map(i => i.code).forEach(key => {
+					result.push({
+						option:key,
+						rate:n.record[key] ? ((n.record[key] / total) * 100).toFixed(1) : 0,
+						PH: n.ph[key] ? ((n.ph[key] / phCount) * 100).toFixed(1) : 0,
+						PL: n.pl[key] ? ((n.pl[key] / plCount) * 100).toFixed(1) : 0,
+					})
+				})
+				console.log(result)
+				return result
 			},
 			
 			onQuestionToggle(index, id, e) {
@@ -162,13 +203,14 @@
 				handler(n) {
 
 				}
-			}
+			},
 		}
 
 	}
 </script>
+
 <style lang="less" scoped>
-	@import "../index/CommonExercise.less";
+	@import "../../../components/evaluation/ExerciseList.less";
 </style>
 <style lang="less" scoped>
 	.child-wrap {

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

@@ -40,17 +40,20 @@
                                 </el-cascader>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.publishType')" prop="publish">
-                                <RadioGroup v-model="evaluationInfo.publish" style="color:white;">
+                                <!-- <RadioGroup v-model="evaluationInfo.publish" style="color:white;">
                                     <Radio :label="item.value" :key="index" v-for="(item,index) in $GLOBAL.PUBLISH_TYPE()" style="width:120px;">
                                         <span>{{ item.label }}</span>
                                     </Radio>
-                                </RadioGroup>
+                                </RadioGroup> -->
+                                <Checkbox v-model="evaluationInfo.publish" :true-value="$GLOBAL.PUBLISH_TYPE()[0].value" :false-value="$GLOBAL.PUBLISH_TYPE()[1].value" @on-change="publishChange">
+                                    <span style="color:white;margin-left:5px;user-select: none;">{{$GLOBAL.PUBLISH_TYPE()[0].label}}</span>
+                                </Checkbox>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.startTime')" v-if="evaluationInfo.publish == 1" prop="startTime">
-                                <DatePicker type="datetime" format="yyyy/MM/dd HH:mm" v-model="startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')" style="width:100%" @on-change="getDate($event,0)"></DatePicker>
+                                <DatePicker :options="dateOpt" type="datetime" format="yyyy/MM/dd HH:mm" v-model="startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')" style="width:100%" @on-change="getDate($event,0)"></DatePicker>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.endTime')" prop="endTime">
-                                <DatePicker type="datetime" format="yyyy/MM/dd HH:mm" v-model="endTime" split-panels :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%" @on-change="getDate($event,1)"></DatePicker>
+                                <DatePicker :options="dateOpt1" type="datetime" format="yyyy/MM/dd HH:mm" v-model="endTime" split-panels :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%" @on-change="getDate($event,1)"></DatePicker>
                             </FormItem>
                         </Form>
                     </vuescroll>
@@ -220,6 +223,17 @@ export default {
             schoolBase: {
                 period: []
             },
+            dateOpt: {
+                disabledDate(date) {
+                    return date && date.valueOf() < Date.now() - 86400000
+                }
+            },
+            dateOpt1: {
+                disabledDate(date) {
+                    let  d = _this.evaluationInfo.startTime ? _this.evaluationInfo.startTime : Date.now()
+                    return d && d > date.valueOf() + 86400000
+                }
+            },
             courseList: [],
             schoolTree: [],
             privateTree: [],
@@ -281,6 +295,12 @@ export default {
         }
     },
     methods: {
+        publishChange(data){
+            if(data == 0){
+                this.startTime = new Date()
+                this.evaluationInfo.startTime = Date.now()
+            }
+        },
         //根据id获取stulist信息
         getListInfo(ids) {
             let requestData = {
@@ -576,6 +596,10 @@ export default {
             if (flag == 0) {
                 this.startTime = value
                 this.evaluationInfo.startTime = new Date(value).getTime()
+                if (this.evaluationInfo.startTime >= this.evaluationInfo.endTime) {
+                    this.endTime = undefined
+                    this.evaluationInfo.endTime = undefined
+                }
             } else if (flag == 1) {
                 this.endTime = value
                 this.evaluationInfo.endTime = new Date(value).getTime()
@@ -646,8 +670,8 @@ export default {
                 // range: this.mode,
                 source: this.evaluationInfo.source,
                 classes: this.evaluationInfo.classes,
-                publish: this.evaluationInfo.publish,
-                startTime: this.evaluationInfo.publish == 0 ? Math.round(new Date()) : this.evaluationInfo.startTime,
+                // publish: this.evaluationInfo.publish,//后端去掉此字段,立即发布由后端获取时间
+                startTime: this.evaluationInfo.publish == 0 ? -1 : this.evaluationInfo.startTime, //立即发布由后端获取时间
                 endTime: this.evaluationInfo.endTime,
                 scope: this.evaluationInfo.scope,
                 createDate: Math.round(new Date()),
@@ -786,7 +810,7 @@ export default {
     created() {
         // 处理默认时间
         this.startTime = new Date()
-        this.evaluationInfo.startTime = new Date()
+        this.evaluationInfo.startTime = new Date().getTime()
         this.endTime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1)
         this.evaluationInfo.endTime = new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1
 
@@ -807,7 +831,6 @@ export default {
         let routerData = this.$route.params.evaluationInfo
         if (routerData !== undefined) {
             this.isEdit = true
-            console.log(routerData)
             this.startTime = new Date(routerData.startTime)
             this.endTime = new Date(routerData.endTime)
             routerData.paperInfo = []

+ 37 - 12
TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue

@@ -44,17 +44,20 @@
                                 </el-cascader>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.publishType')" prop="publish">
-                                <RadioGroup v-model="evaluationInfo.publish" style="color:white;">
+                                <!-- <RadioGroup v-model="evaluationInfo.publish" style="color:white;">
                                     <Radio :label="item.value" :key="index" v-for="(item,index) in $GLOBAL.PUBLISH_TYPE()" style="width:120px;">
                                         <span>{{ item.label }}</span>
                                     </Radio>
-                                </RadioGroup>
+                                </RadioGroup> -->
+                                <Checkbox v-model="evaluationInfo.publish" :true-value="$GLOBAL.PUBLISH_TYPE()[0].value" :false-value="$GLOBAL.PUBLISH_TYPE()[1].value" @on-change="publishChange">
+                                    <span style="color:white;margin-left:5px;user-select: none;">{{$GLOBAL.PUBLISH_TYPE()[0].label}}</span>
+                                </Checkbox>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.startTime')" v-if="evaluationInfo.publish == 1" prop="startTime">
-                                <DatePicker type="datetime" format="yyyy/MM/dd HH:mm" v-model="startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')" style="width:100%" @on-change="getDate($event,0)"></DatePicker>
+                                <DatePicker :options="dateOpt" type="datetime" format="yyyy/MM/dd HH:mm" v-model="startTime" split-panels :placeholder="$t('learnActivity.createEv.sTimeHolder')" style="width:100%" @on-change="getDate($event,0)"></DatePicker>
                             </FormItem>
                             <FormItem :label="$t('learnActivity.createEv.endTime')" prop="endTime">
-                                <DatePicker type="datetime" format="yyyy/MM/dd HH:mm" v-model="endTime" split-panels :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%" @on-change="getDate($event,1)"></DatePicker>
+                                <DatePicker :options="dateOpt1" type="datetime" format="yyyy/MM/dd HH:mm" v-model="endTime" split-panels :placeholder="$t('learnActivity.createEv.eTimeHolder')" style="width:100%" @on-change="getDate($event,1)"></DatePicker>
                             </FormItem>
                         </Form>
                     </vuescroll>
@@ -114,6 +117,7 @@ export default {
         ManualPaper,
     },
     data() {
+        let _this = this
         return {
             schoolClasses: [],
             props: {
@@ -124,6 +128,17 @@ export default {
             schoolBase: {
                 period: []
             },
+            dateOpt: {
+                disabledDate(date) {
+                    return date && date.valueOf() < Date.now() - 86400000
+                }
+            },
+            dateOpt1: {
+                disabledDate(date) {
+                    let  d = _this.evaluationInfo.startTime ? _this.evaluationInfo.startTime : Date.now()
+                    return d && d > date.valueOf() + 86400000
+                }
+            },
             startTime: '',
             endTime: '',
             privClassList: [],
@@ -151,9 +166,9 @@ export default {
                 'examType.id': [
                     { required: true, message: this.$t('learnActivity.createEv.errTips5'), trigger: 'change' }
                 ],
-                // targets: [
-                //     { required: true, message: this.$t('learnActivity.createEv.errTips6'), trigger: 'change' }
-                // ],
+                targets: [
+                    { required: true, message: this.$t('learnActivity.createEv.errTips6'), type: 'array', trigger: 'change' }
+                ],
                 publish: [
                     { required: true, message: this.$t('learnActivity.createEv.errTips7'), trigger: 'change' }
                 ],
@@ -191,6 +206,12 @@ export default {
         }
     },
     methods: {
+        publishChange(data){
+            if(data == 0){
+                this.startTime = new Date()
+                this.evaluationInfo.startTime = Date.now()
+            }
+        },
         //设置学科名称
         setSubjectName() {
             this.evaluationInfo.subjects = this.curSubjects.filter(item => {
@@ -291,7 +312,7 @@ export default {
         /**
          * 将日期控件时间格式转成时间戳
          * @param value
-         * @param date
+         * @param flag 0 开始时间 1 结束时间
          */
         getDate(value, flag) {
             if (value.indexOf('00:00') > 0) {
@@ -300,6 +321,10 @@ export default {
             if (flag == 0) {
                 this.startTime = value
                 this.evaluationInfo.startTime = new Date(value).getTime()
+                if (this.evaluationInfo.startTime > this.evaluationInfo.endTime) {
+                    this.endTime = undefined
+                    this.evaluationInfo.endTime = undefined
+                }
             } else if (flag == 1) {
                 this.endTime = value
                 this.evaluationInfo.endTime = new Date(value).getTime()
@@ -490,13 +515,13 @@ export default {
                 range: this.mode,
                 source: this.evaluationInfo.source,
                 classes: this.evaluationInfo.classes,
-                publish: this.evaluationInfo.publish,
-                startTime: this.evaluationInfo.publish == 0 ? Math.round(new Date()) : this.evaluationInfo.startTime,
+                // publish: this.evaluationInfo.publish,//后端去掉此字段,立即发布由后端获取时间
+                startTime: this.evaluationInfo.publish == 0 ? -1 : this.evaluationInfo.startTime,//立即发布由后端获取时间
                 endTime: this.evaluationInfo.endTime,
                 scope: this.mode,
                 createDate: Math.round(new Date()),
                 // blobcntr: this.$store.state.userInfo.schoolCode //后面新增字段 (废弃)
-                owner:'school' //后面新增字段
+                owner: 'school' //后面新增字段
             }
 
             this.$api.learnActivity.SaveExamInfo(requestData).then(
@@ -617,7 +642,7 @@ export default {
     created() {
         // 处理默认时间
         this.startTime = new Date()
-        this.evaluationInfo.startTime = new Date()
+        this.evaluationInfo.startTime = new Date().getTime()
         this.endTime = new Date(new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1)
         this.evaluationInfo.endTime = new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1
 

+ 2 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.less

@@ -103,7 +103,7 @@
 }
 .scoring-exercise-wrap .exercise-item {
     position: relative;
-    margin-top: 20px;
+    margin-top: 10px;
     font-size: 14px;
     padding: 0px;
     min-height: 85px;
@@ -261,7 +261,7 @@
 	.compose-box{
 		.child-item{
 			position: relative;
-			margin-top:20px;
+			margin-top:10px;
 			display: flex;
             min-height: 85px;
 			&-question{

+ 4 - 8
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -123,7 +123,7 @@
                                     <!--其余题型答案-->
                                     <div v-else-if="studentAnswer.answers[getScoreIndex(typeIndex,index)]" :id="'answer'+ getScoreIndex(typeIndex,index)">
                                         <div>
-                                            <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index)].join(',')"></span>
+                                            <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index)].toString()"></span>
                                         </div>
                                     </div>
                                 </div>
@@ -243,9 +243,9 @@
                                             <span v-for="(answerItem,answerIndex) in studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)]" :key="'an'+ (index+answerIndex+childIndex)" v-html="answerItem" style="display:inline-block;"></span>
                                         </div>
                                         <!--其余题型答案-->
-                                        <div v-else-if="studentAnswer.answers[typeIndex + index + childIndex]" :id="'answer'+ getScoreIndex(typeIndex,index,childIndex)">
+                                        <div v-else-if="studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)]" :id="'answer'+ getScoreIndex(typeIndex,index,childIndex)">
                                             <div>
-                                                <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)].join(',')"></span><br />
+                                                <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)].toString()"></span><br />
                                             </div>
                                         </div>
                                     </div>
@@ -403,7 +403,7 @@ export default {
                 answerIframe.style.width = '850px'
                 answerIframe.contentWindow.document.body.style.margin = '0px 20px'
                 answerIframe.contentWindow.document.body.style.padding = '10px'
-                answerIframe.contentWindow.document.body.style.minWidth = '400px'
+                answerIframe.contentWindow.document.body.style.minWidth = '600px'
                 answerIframe.contentWindow.document.body.style.minHeight = '240px'
                 answerIframe.contentWindow.document.body.style.height = 'fit-content'
                 answerIframe.contentWindow.document.body.style.width = 'fit-content'
@@ -465,7 +465,6 @@ export default {
         //快速定位题目
         goToQuestion(index) {
             this.activeIndex = index
-            console.log(index)
             this.$el.querySelector('#qustion' + index).scrollIntoView({
                 behavior: "smooth",  // 平滑过渡
                 block: "center"  // 上边框与视窗顶部平齐。默认值
@@ -585,7 +584,6 @@ export default {
         },
         paperInfo: {
             handler(newPaper) {
-                console.log('newPaper', newPaper)
                 if (newPaper && newPaper.item) {
                     this.dataLoading = true
                     let that = this
@@ -616,7 +614,6 @@ export default {
         },
         studentAnswer: {
             async handler(newValue, oldValue) {
-                console.log('获取答案', JSON.stringify(newValue))
                 if (!this.studentAnswer.status) {
                     if (newValue.answers.length) {
                         try {
@@ -644,7 +641,6 @@ export default {
                             } else {
                                 this.$set(this.studentAnswer, 'answers', [])
                             }
-                            console.log(this.studentAnswer)
                         } catch (e) {
                             console.log('error', e)
                         }

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

@@ -104,7 +104,7 @@ export default {
                     key: "name",
                     fixed: "left",
                     align: "center",
-                    minWidth: 150,
+                    width: 150,
                 },
                 {
                     title: this.$t('learnActivity.score.column2'),

+ 1 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue

@@ -110,7 +110,7 @@ export default {
                     key: "name",
                     fixed: "left",
                     align: "center",
-                    minWidth: 150,
+                    width: 150,
                 },
                 {
                     title: this.$t('learnActivity.score.column2'),
@@ -154,8 +154,6 @@ export default {
                 default:
                     break
             }
-            console.log('1', this.studentScore[0].name)
-            console.log(2, this.originData[0].name)
             this.pageChange(1)
         },
         // 页面size变化

+ 5 - 1
TEAMModelOS/ClientApp/src/view/newcourse/EvDetail.vue

@@ -1,5 +1,6 @@
 <template>
     <div class="evaluation-detail-wrap">
+        <Loading v-show="pageLoading"></Loading>
         <!--顶部菜单-->
         <div class="evaluation-detail-bar">
             <span :class="curBarIndex == 0 ? 'evalustion-bar-item line-bottom-active line-bottom':'evalustion-bar-item line-bottom'" @click="curBarIndex = 0">
@@ -43,6 +44,7 @@ export default {
     },
     data() {
         return {
+            pageLoading:false,
             showBack: false,
             curBarIndex: 0,
             curSubIndex: 0,
@@ -82,6 +84,7 @@ export default {
                 code: code
             }
             this.isLoading = true
+            this.pageLoading = true
             this.$api.learnActivity.FindExamInfos(requestData).then(
                 async res => {
                     if (!res.error) {
@@ -109,7 +112,8 @@ export default {
                     this.$Message.error('API ERROR!')
                 }
             ).finally(() => {
-                this.isLoading = false;
+                this.isLoading = false
+                this.pageLoading = false
             })
         }
     },

+ 1 - 1
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -994,7 +994,7 @@ export default {
             let acId = this.acList[index].id
             let acCode = this.acList[index].code
             let owner = this.acList[index].owner
-            // 记录页面当前状态
+            // 记录页面当前状态 通过配置keep-alive来设置是否保存路由状态,不需要session记录数据
             // sessionStorage.setItem('myCusType', this.listType)
             // sessionStorage.setItem('myCusTabName', this.tabName)
             switch (this.curAcType) {

+ 33 - 24
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -31,7 +31,7 @@
 										<p class="qn-item-name">{{ item.name }}</p>
 										<div class="qn-item-info">
 											<span class="qn-item-nums">
-												<Icon type="md-time" size="14" style="margin-right: 5px" />{{ $tools.formatTime(item.startTime) }}</span>
+												<Icon type="md-time" size="14" style="margin-right: 5px" />{{ $tools.formatTime(item.startTime,'yyyy-MM-dd hh:mm') }}</span>
 											<span class="qn-item-status" :style="{ background: item.progress === 'pending' ? '#0BADD4'  : item.progress === 'going' ? '#12a568' : '#949594', }">
 												{{ item.progress === "pending" ? $t('survey.pending') : item.progress === "going"  ? $t('survey.going') : $t('survey.finish')  }}
 											</span>
@@ -181,7 +181,8 @@
 				curTab:'progress',
 				noFinishStudents:[],
 				allSsList:[],
-				isFromRecord:false
+				isFromRecord:false,
+				hasModify:false
 			};
 		},
 		created() {
@@ -213,8 +214,8 @@
 					let defaultQn = {
 						name: this.$t('survey.defaultName'),
 						classes: [],
-						endTime: "",
-						startTime: "",
+						endTime: new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1,
+						startTime:new Date().getTime(),
 						description: "",
 						rangeTime: [],
 						isReset: [],
@@ -300,7 +301,7 @@
 			 * @param index
 			 */
 			async onQnClick(item, index) {
-				if (this.activeQnIndex === index && this.currentQn.id && this.currentQn.id === item.id) return
+				if (this.activeQnIndex === index && this.currentQn.id && this.currentQn.id === item.id && !this.hasModify) return
 				console.log(item, index);
 				/* 判断是否有新增但是无效的ITEM  如果有 则清空 需要重新添加 */
 				let hasNewQn = this.qnList.filter((i) => !i.id).length;
@@ -324,6 +325,7 @@
 				this.activeQnIndex = hasNewQn ? this.qnList.indexOf(item) : index;
 				this.$refs.qnForm.qnFormEdit = false;
 				this.editable = false;
+				this.hasModify = false
 			},
 
 			/* 获取问卷所有试题的选项内容 */
@@ -339,25 +341,32 @@
 			async onSaveQn() {
 				this.isBtnLoading = true;
 				let isQnFormEdit = this.$refs.qnForm.qnFormEdit; // 判断当前表单是否为编辑状态
-				let qnBaseInfo = isQnFormEdit ? await this.$refs.qnForm.handleSubmit("qnForm") : this.currentQn;
-				let qnItems = this.$refs.qnPaper.items || [];
-				// 将问卷试题内容保存到blob 用blobUrl来替换quesitons字段
-				qnBaseInfo.answers = this.getSurveyAns(qnItems)
-				qnBaseInfo.blob = await this.doUploadBlob(qnBaseInfo, qnItems);
-				// 开始保存问卷
-				this.saveorUpdataQn(qnBaseInfo)
-					.then((res) => {
-						this.$Message.success(this.$t('survey.doSuc'));
-						this.editable = false;
-						this.onAddSuccess();
-					})
-					.catch((error) => {
-						this.$Message.error(`${error}`);
-					}).finally(data => {
-						this.$refs.qnForm.qnFormEdit = false;
-						this.isLoading = false;
-						this.isBtnLoading = false;
-					});
+				try{
+					let qnBaseInfo = isQnFormEdit ? await this.$refs.qnForm.handleSubmit("qnForm") : this.currentQn;
+					let qnItems = this.$refs.qnPaper.items || [];
+					// 将问卷试题内容保存到blob 用blobUrl来替换quesitons字段
+					qnBaseInfo.answers = this.getSurveyAns(qnItems)
+					qnBaseInfo.blob = await this.doUploadBlob(qnBaseInfo, qnItems);
+					// 开始保存问卷
+					this.saveorUpdataQn(qnBaseInfo)
+						.then((res) => {
+							this.$Message.success(this.$t('survey.doSuc'));
+							this.editable = false;
+							this.hasModify = true
+							this.onAddSuccess();
+						})
+						.catch((error) => {
+							this.$Message.error(`${error}`);
+						}).finally(data => {
+							this.$refs.qnForm.qnFormEdit = false;
+							this.isLoading = false;
+							this.isBtnLoading = false;
+						});
+				}catch(e){
+					this.isLoading = false;
+					this.isBtnLoading = false;
+				}
+				
 			},
 			
 			/* 上传index.json */

+ 14 - 6
TEAMModelOS/ClientApp/src/view/selflearn/SelfLearn.less

@@ -11,14 +11,13 @@
     display: flex;
     flex-direction: row;
     .order-learn-list-box {
-        width: 400px;
+        width: 100%;
         height: 100%;
-        border-right: 1px solid @borderColor;
-        padding-left: 15px;
+        padding-left: 10px;
     }
 
     .order-learn-main {
-        width: ~"calc(100% - 400px)";
+        width: 100%;
         height: 100%;
         padding-left: 15px;
     }
@@ -33,7 +32,12 @@
     }
 
 }
-
+.learn-list-header{
+    height: 45px;
+    line-height: 45px;
+    color: white;
+    border-bottom: 1px solid @borderColor;
+}
 .order-learn-main {
     .main-bar-wrap {
         width: 100%;
@@ -72,7 +76,6 @@
     }
 }
 .to-create-icon {
-    float: right;
     margin-right: 15px;
     margin-top: 8px;
     cursor: pointer;
@@ -90,4 +93,9 @@
     display: inline-block;
     line-height: 45px;
     height:45px;
+}
+.learn-action-wrap{
+    float: right;
+    height: 45px;
+    line-height: 45px;
 }

+ 390 - 342
TEAMModelOS/ClientApp/src/view/selflearn/SelfLearn.vue

@@ -1,400 +1,448 @@
 <template>
-    <div class="manage-order-learn">
+    <div class="manage-order-learn dark-iview-split">
         <Loading v-if="isLoading" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
-        <div class="order-learn-list-box">
-            <div class="dark-iview-tabs-line" style="padding-top:10px;height:100%;">
-                <Tabs v-model="listType" @on-click="toggleList" style="height:100%;">
-                    <div slot="extra">
-                        <Icon type="md-add" class="to-create-icon" @click="createData" title="新增" />
-                        <Icon type="md-trash" :color="editIconStatus ? 'white':'#808080'" :style="{'cursor': editIconStatus ? 'pointer':'not-allowed'}" class="to-create-icon" @click="deleteData" title="删除" />
+        <Split v-model="split1">
+            <div slot="left" class="order-learn-list-box">
+                <div class="learn-list-header">
+                    <Dropdown class="sort-dropdown" trigger="click" placement="bottom-start" @on-click="function(e){ listType = e }" @on-visible-change="dropdownStates">
+                        <span style="cursor: pointer;">
+                            <b class="title">{{ typeLabel }}</b>
+                            <Icon type="ios-arrow-down" style="margin-left:8px;"></Icon>
+                        </span>
+                        <DropdownMenu slot="list" v-for="(item,index) in typeLsit" :value="item.value" :key="index">
+                            <DropdownItem :name="item.value">{{ item.label }}</DropdownItem>
+                        </DropdownMenu>
+                    </Dropdown>
+                    <div class="learn-action-wrap">
                         <Icon type="md-create" :color="editIconStatus ? 'white':'#808080'" :style="{'cursor': editIconStatus ? 'pointer':'not-allowed'}" class="to-create-icon" @click="editInfo" title="编辑" />
+                        <Icon type="md-trash" :color="editIconStatus ? 'white':'#808080'" :style="{'cursor': editIconStatus ? 'pointer':'not-allowed'}" class="to-create-icon" @click="deleteData" title="删除" />
+                        <Icon type="md-add" class="to-create-icon" @click="createData" title="新增" />
                     </div>
-                    <TabPane label="学习单元" name="unit" style="height:calc(100% - 40px);">
-                        <vuescroll>
-                            <UnitList :class="listType == 1 ? 'animated fadeIn':''" @selectIndex="selectOrderLearn" :unitList="unitList"></UnitList>
-                        </vuescroll>
-                    </TabPane>
-                    <TabPane label="编序式学习" name="order" style="height:calc(100% - 40px);">
-                        <vuescroll>
-                            <OrderLearnList :class="listType == 0 ? 'animated fadeIn':''" @selectIndex="selectOrderLearn" :orderLearnList="orderLearnList"></OrderLearnList>
-                        </vuescroll>
-                    </TabPane>
-
-                </Tabs>
-            </div>
-        </div>
-        <div class="order-learn-main">
-            <div class="main-bar-wrap">
-                <span :class="currentTabIndex == 1 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(1)">学习数据</span>
-                <span :class="currentTabIndex == 0 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(0)">学习内容</span>
-            </div>
-            <div class="order-learn-main-body dark-iview-split" v-if="listType == 'order' && orderLearnList[currentLearnIndex]">
-                <OrderLearnInfo v-if="currentTabIndex == 0" :orderLearnInfo="orderLearnList[currentLearnIndex]"></OrderLearnInfo>
-                <ActivityInfo ref="activityInfo" v-else :learnContent="learnContent" :classList="classList"></ActivityInfo>
-            </div>
-            <div class="order-learn-main-body dark-iview-split" v-else-if="listType == 'unit' && unitList[currentUnitIndex]">
-                <UnitInfo v-if="currentTabIndex == 0" :unitInfo="unitList[currentUnitIndex]"></UnitInfo>
-                <ActivityInfo ref="activityInfo" v-else :learnContent="learnContent" :classList="classList"></ActivityInfo>
+                </div>
+                <div class="dark-iview-tabs-line" style="padding-top:10px;height:100%;">
+                    <vuescroll>
+                        <UnitList v-show="listType == 'unit'" :class="listType == 'unit' ? 'animated fadeIn':''" @selectIndex="selectOrderLearn" :unitList="unitList"></UnitList>
+                        <OrderLearnList v-show="listType == 'order'" :class="listType == 'order' ? 'animated fadeIn':''" @selectIndex="selectOrderLearn" :orderLearnList="orderLearnList"></OrderLearnList>
+                    </vuescroll>
+                </div>
             </div>
-            <div v-else>
-                <EmptyData style="padding-top:150px;"></EmptyData>
+            <div slot="right" class="order-learn-main">
+                <div class="main-bar-wrap">
+                    <span :class="currentTabIndex == 1 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(1)">学习数据</span>
+                    <span :class="currentTabIndex == 0 ? 'main-header-tab line-bottom line-bottom-active':'main-header-tab line-bottom'" @click="selectTab(0)">学习内容</span>
+                </div>
+                <div class="order-learn-main-body dark-iview-split" v-if="listType == 'order' && orderLearnList[currentLearnIndex]">
+                    <OrderLearnInfo v-if="currentTabIndex == 0" :orderLearnInfo="orderLearnList[currentLearnIndex]"></OrderLearnInfo>
+                    <ActivityInfo ref="activityInfo" v-else :learnContent="learnContent" :classList="classList"></ActivityInfo>
+                </div>
+                <div class="order-learn-main-body dark-iview-split" v-else-if="listType == 'unit' && unitList[currentUnitIndex]">
+                    <UnitInfo v-if="currentTabIndex == 0" :unitInfo="unitList[currentUnitIndex]"></UnitInfo>
+                    <ActivityInfo ref="activityInfo" v-else :learnContent="learnContent" :classList="classList"></ActivityInfo>
+                </div>
+                <div v-else>
+                    <EmptyData style="padding-top:150px;"></EmptyData>
+                </div>
             </div>
-        </div>
-        <Modal v-model="editStatus"
-               :title="listType == 'order' ? '编辑编序式教材' : '编辑自学单元'"
-               @on-ok="confirmEdit">
+        </Split>
+
+        <Modal v-model="editStatus" :title="listType == 'order' ? '编辑编序式教材' : '编辑自学单元'" @on-ok="confirmEdit">
             <p>确认跳转到<span style="padding:0px 5px;">{{ listType == 'order' ? '编序式教材':'自学单元'}}</span>编辑页面?</p>
         </Modal>
     </div>
 </template>
 <script>
-    import QuestionList from '@/components/learnactivity/QuestionList.vue'
-    import ContentFileList from '@/components/selflearn/ContentFileList.vue'
-    import OrderLearnList from './OrderLearnList.vue'
-    import UnitList from './UnitList.vue'
-    import OrderLearnInfo from './OrderLearnInfo.vue'
-    import UnitInfo from './UnitInfo.vue'
-    import ActivityInfo from './ActivityInfo.vue'
+import QuestionList from '@/components/learnactivity/QuestionList.vue'
+import ContentFileList from '@/components/selflearn/ContentFileList.vue'
+import OrderLearnList from './OrderLearnList.vue'
+import UnitList from './UnitList.vue'
+import OrderLearnInfo from './OrderLearnInfo.vue'
+import UnitInfo from './UnitInfo.vue'
+import ActivityInfo from './ActivityInfo.vue'
 
-    export default {
-        components: {
-            QuestionList, ContentFileList, OrderLearnList, UnitList, OrderLearnInfo, UnitInfo, ActivityInfo
-        },
-        data() {
-            return {
-                year: '',
-                semester: '',
-                requestIds: [],
-                classList: [],
-                currentTabIndex: 1,
-                listType: 'unit',//order: 编序式教材 unit:学习单元
-                isLoading: false,
-                sasString: '',
-                editStatus: false,
-                orderLearnList: [],
-                unitList: [],
-                currentLearnIndex: 0,
-                currentUnitIndex: 0
+export default {
+    components: {
+        QuestionList, ContentFileList, OrderLearnList, UnitList, OrderLearnInfo, UnitInfo, ActivityInfo
+    },
+    data() {
+        return {
+            split1: 0.2,
+            year: '',
+            semester: '',
+            requestIds: [],
+            classList: [],
+            currentTabIndex: 1,
+            listType: 'unit',//order: 编序式教材 unit:学习单元
+            isLoading: false,
+            sasString: '',
+            editStatus: false,
+            orderLearnList: [],
+            unitList: [],
+            currentLearnIndex: 0,
+            currentUnitIndex: 0,
+            typeLsit: [
+                {
+                    label: '学习单元',
+                    value: 'unit'
+                },
+                {
+                    label: '编序式学习',
+                    value: 'order'
+                }
+            ]
+        }
+    },
+    computed: {
+        typeLabel: function () {
+            let pId = this.listType
+            let name = ''
+            if (pId) {
+                let temp = this.typeLsit.filter(item => {
+                    return pId == item.value
+                })
+                if (temp.length > 0) name = temp[0].label
             }
+            return name
         },
-        computed: {
-            editIconStatus() {
-                if (this.listType == 'order') {
-                    if (this.orderLearnList.length > 0) {
-                        return true
-                    } else {
-                        return false
-                    }
+        editIconStatus() {
+            if (this.listType == 'order') {
+                if (this.orderLearnList.length > 0) {
+                    return true
                 } else {
-                    if (this.unitList.length > 0) {
-                        return true
-                    } else {
-                        return false
-                    }
+                    return false
                 }
-            },
-            learnContent() {
-                if (this.listType == 'order') {
-                    if (this.orderLearnList.length > 0) {
-                        return this.orderLearnList[this.currentLearnIndex]
-                    } else {
-                        return {}
-                    }
+            } else {
+                if (this.unitList.length > 0) {
+                    return true
                 } else {
-                    if (this.unitList.length > 0) {
-                        return this.unitList[this.currentUnitIndex]
-                    } else {
-                        return {}
-                    }
+                    return false
                 }
             }
         },
-        watch: {
-            learnContent: {
-                handler(n, o) {
-                    if (this.requestIds.indexOf(this.learnContent.id) == -1) {
-                        this.findTask()
-                    }
-                },
-                deep: true
+        learnContent() {
+            if (this.listType == 'order') {
+                if (this.orderLearnList.length > 0) {
+                    return this.orderLearnList[this.currentLearnIndex]
+                } else {
+                    return {}
+                }
+            } else {
+                if (this.unitList.length > 0) {
+                    return this.unitList[this.currentUnitIndex]
+                } else {
+                    return {}
+                }
             }
-        },
-        methods: {
-            setStartTime(date, data) {
-                this.activityInfo.startTime = new Date(date).getTime()
-            },
-            setEndTime(date, data) {
-                this.activityInfo.endTime = new Date(date).getTime()
+        }
+    },
+    watch: {
+        learnContent: {
+            handler(n, o) {
+                if (this.requestIds.indexOf(this.learnContent.id) == -1) {
+                    this.findTask()
+                }
             },
+            deep: true
+        }
+    },
+    methods: {
+        dropdownStates(flag) {
+            if (!flag) this.toggleList()
+        },
+        setStartTime(date, data) {
+            this.activityInfo.startTime = new Date(date).getTime()
+        },
+        setEndTime(date, data) {
+            this.activityInfo.endTime = new Date(date).getTime()
+        },
 
-            /**
-             * 发布活动
-            */
-            publishActivity() {
-                this.publishStatus = true
-            },
+        /**
+         * 发布活动
+        */
+        publishActivity() {
+            this.publishStatus = true
+        },
 
-            selectTab(index) {
-                this.currentTabIndex = index
-            },
-            createData() {
-                if (this.listType == 'order') {
-                    this.$router.push({
-                        name: 'createOrderLearn'
-                    })
-                } else {
-                    this.$router.push({
-                        name: 'createLearnUnit'
-                    })
-                }
-            },
-            /**
-             * 删除编序式教材或自学单元
-             * */
-            deleteData() {
-                let name = this.listType == 'order' ? this.orderLearnList[this.currentLearnIndex].name : this.unitList[this.currentUnitIndex].name
-                this.$Modal.confirm({
-                    title: this.listType == 'unit' ? '删除学习单元' : '删除编序式学习',
-                    content: '确认删除' + name + '吗?',
-                    onOk: () => {
-                        //this.confirmDelete()
-                        this.$Message.warning('暂未对接删除API')
-                    }
+        selectTab(index) {
+            this.currentTabIndex = index
+        },
+        createData() {
+            if (this.listType == 'order') {
+                this.$router.push({
+                    name: 'createOrderLearn'
                 })
-            },
-            /**
-             * 确认删除编序式教材或自学单元
-             * */
-            confirmDelete() {
-                if (this.listType == 'order') {
-                    let requestData = {
-                        id: this.orderLearnList[this.currentLearnIndex].id,
-                        pk: this.orderLearnList[this.currentLearnIndex].code
-                    }
-                    this.$api.learnActivity.DeleteLeanProcess(requestData).then(
-                        res => {
-                            if (res.error == null) {
-                                let index = this.currentLearnIndex
-                                this.currentLearnIndex = 0
-                                this.orderLearnList.splice(index, 1)
-                                this.$Message.success('删除成功!')
+            } else {
+                this.$router.push({
+                    name: 'createLearnUnit'
+                })
+            }
+        },
+        /**
+         * 删除编序式教材或自学单元
+         * */
+        deleteData() {
+            let name = this.listType == 'order' ? this.orderLearnList[this.currentLearnIndex].name : this.unitList[this.currentUnitIndex].name
+            this.$Modal.confirm({
+                title: this.listType == 'unit' ? '删除学习单元' : '删除编序式学习',
+                content: '确认删除' + name + '吗?',
+                onOk: () => {
+                    //this.confirmDelete()
+                    this.$Message.warning('暂未对接删除API')
+                }
+            })
+        },
+        /**
+         * 确认删除编序式教材或自学单元
+         * */
+        confirmDelete() {
+            if (this.listType == 'order') {
+                let requestData = {
+                    id: this.orderLearnList[this.currentLearnIndex].id,
+                    pk: this.orderLearnList[this.currentLearnIndex].code
+                }
+                this.$api.learnActivity.DeleteLeanProcess(requestData).then(
+                    res => {
+                        if (res.error == null) {
+                            let index = this.currentLearnIndex
+                            this.currentLearnIndex = 0
+                            this.orderLearnList.splice(index, 1)
+                            this.$Message.success('删除成功!')
 
-                            } else {
-                                this.$Message.success('删除失败!')
-                            }
-                        },
-                        err => {
+                        } else {
                             this.$Message.success('删除失败!')
                         }
-                    )
-                } else {
-                    let requestData = {
-                        id: this.unitList[this.currentUnitIndex].id,
-                        pk: this.unitList[this.currentUnitIndex].code
+                    },
+                    err => {
+                        this.$Message.success('删除失败!')
                     }
-                    this.$api.learnActivity.DeleteUnit(requestData).then(
-                        res => {
-                            if (res.error == null) {
-                                let index = this.currentUnitIndex
-                                this.currentUnitIndex = 0
-                                this.unitList.splice(index, 1)
-                                this.$Message.success('删除成功!')
-                            } else {
-                                this.$Message.success('删除失败!')
-                            }
-                        },
-                        err => {
+                )
+            } else {
+                let requestData = {
+                    id: this.unitList[this.currentUnitIndex].id,
+                    pk: this.unitList[this.currentUnitIndex].code
+                }
+                this.$api.learnActivity.DeleteUnit(requestData).then(
+                    res => {
+                        if (res.error == null) {
+                            let index = this.currentUnitIndex
+                            this.currentUnitIndex = 0
+                            this.unitList.splice(index, 1)
+                            this.$Message.success('删除成功!')
+                        } else {
                             this.$Message.success('删除失败!')
                         }
-                    )
-                }
-            },
-            /**
-             * 切换列表类型
-             * */
-            toggleList() {
-                if (this.listType == 'order') {
-                    this.findOrderLearn()
-                } else {
-                    this.findUnit()
-                }
-            },
-            //查询学习任务
-            findTask() {
-                if (this.learnContent.id) {
-                    this.$api.learnActivity.findTask({
-                        id: this.learnContent.id
-                    }).then(
-                        (res) => {
-                            if (res.error == null) {
-                                let resData = res.tasks
-                                for (let index in resData) {
-                                    for (let i in this.classList) {
-                                        if (this.classList[i].classroomCode == resData[index].code) {
-                                            this.$set(this.classList[i], [resData[index].id], resData[index])
-                                            break
-                                        }
+                    },
+                    err => {
+                        this.$Message.success('删除失败!')
+                    }
+                )
+            }
+        },
+        /**
+         * 切换列表类型
+         * */
+        toggleList() {
+            if (this.listType == 'order') {
+                this.findOrderLearn()
+            } else {
+                this.findUnit()
+            }
+        },
+        //查询学习任务
+        findTask() {
+            if (this.learnContent.id) {
+                this.$api.learnActivity.findTask({
+                    id: this.learnContent.id
+                }).then(
+                    (res) => {
+                        if (res.error == null) {
+                            let resData = res.tasks
+                            for (let index in resData) {
+                                for (let i in this.classList) {
+                                    if (this.classList[i].classroomCode == resData[index].code) {
+                                        this.$set(this.classList[i], [resData[index].id], resData[index])
+                                        break
                                     }
                                 }
-                                this.requestIds.push(this.learnContent.id)
-                            } else {
-                                this.$Message.error('API error!')
                             }
-                        },
-                        (err) => {
+                            this.requestIds.push(this.learnContent.id)
+                        } else {
                             this.$Message.error('API error!')
                         }
-                    )
-                }
-            },
-            goToCreate() {
-                if (this.listType == 'order') {
-                    this.$router.push({
-                        name: 'createOrderLearn'
-                    })
-                } else {
-                    this.$router.push({
-                        name: 'createLearnUnit'
-                    })
-                }
+                    },
+                    (err) => {
+                        this.$Message.error('API error!')
+                    }
+                )
+            }
+        },
+        goToCreate() {
+            if (this.listType == 'order') {
+                this.$router.push({
+                    name: 'createOrderLearn'
+                })
+            } else {
+                this.$router.push({
+                    name: 'createLearnUnit'
+                })
+            }
 
-            },
-            /**
-             * 查找教师课程下的班级(班级)
-             * */
-            findClassroom() {
-                if (this.classList.length == 0) {
-                    this.$api.learnActivity.FindClassroomByTeacherId({
-                        code: this.$store.state.userInfo.schoolCode,
-                        id: this.$store.state.userInfo.TEAMModelId
-                    }).then(
-                        res => {
-                            if (!res.error) {
-                                this.classList = res.courses
-                                if (this.classList.length > 0) {
-                                    this.findTask()
-                                    setTimeout(() => {
-                                        this.$refs['activityInfo'].getClassroomStudent()
-                                    }, 1000)
-                                }
-                            } else {
-                                this.$Message.error('API ERROR!')
+        },
+        /**
+         * 查找教师课程下的班级(班级)
+         * */
+        findClassroom() {
+            if (this.classList.length == 0) {
+                this.$api.learnActivity.FindClassroomByTeacherId({
+                    code: this.$store.state.userInfo.schoolCode,
+                    id: this.$store.state.userInfo.TEAMModelId
+                }).then(
+                    res => {
+                        if (!res.error) {
+                            this.classList = res.courses
+                            if (this.classList.length > 0) {
+                                this.findTask()
+                                setTimeout(() => {
+                                    this.$refs['activityInfo'].getClassroomStudent()
+                                }, 1000)
                             }
-                        },
-                        err => {
+                        } else {
                             this.$Message.error('API ERROR!')
                         }
-                    ).finally(() => {
-                        setTimeout(() => {
-                            this.isLoading = false
-                        },500)
-                    })
+                    },
+                    err => {
+                        this.$Message.error('API ERROR!')
+                    }
+                ).finally(() => {
+                    setTimeout(() => {
+                        this.isLoading = false
+                    }, 500)
+                })
+            }
+        },
+        downloadFile(item) {
+            window.location.href = item.blobUrl + this.sasString
+        },
+        confirmEdit() {
+            if (this.listType == 'order') {
+                let orderLearnInfo = this.orderLearnList[this.currentLearnIndex]
+                this.$router.push({
+                    name: 'createOrderLearn',
+                    params: {
+                        orderLearnInfo
+                    }
+                })
+            } else {
+                //编辑最小单元
+                let unitInfo = this.unitList[this.currentUnitIndex]
+                this.$router.push({
+                    name: 'createLearnUnit',
+                    params: {
+                        unitInfo
+                    }
+                })
+            }
+
+        },
+        editInfo() {
+            this.editStatus = true
+        },
+        selectOrderLearn(index) {
+            if (this.listType == 'order') {
+                this.currentStepIndex = 0
+                this.currentLearnIndex = index
+            } else {
+                this.currentUnitIndex = index
+            }
+            this.$refs['activityInfo'].checkFindRecord()
+        },
+        /**
+         * 查询编序式教材列表
+         * */
+        findOrderLearn() {
+            if (this.orderLearnList.length == 0) {
+                let requestData = {
+                    code: this.$store.state.userInfo.TEAMModelId
                 }
-            },
-            downloadFile(item) {
-                window.location.href = item.blobUrl + this.sasString
-            },
-            confirmEdit() {
-                if (this.listType == 'order') {
-                    let orderLearnInfo = this.orderLearnList[this.currentLearnIndex]
-                    this.$router.push({
-                        name: 'createOrderLearn',
-                        params: {
-                            orderLearnInfo
-                        }
-                    })
-                } else {
-                    //编辑最小单元
-                    let unitInfo = this.unitList[this.currentUnitIndex]
-                    this.$router.push({
-                        name: 'createLearnUnit',
-                        params: {
-                            unitInfo
+                this.$api.learnActivity.FindOrderLearn(requestData).then(
+                    res => {
+                        if (res.error == null) {
+                            this.orderLearnList = res.result.data
+                        } else {
+                            this.$Message.error('API ERROR!')
                         }
-                    })
-                }
+                    },
+                    err => {
 
-            },
-            editInfo() {
-                this.editStatus = true
-            },
-            selectOrderLearn(index) {
-                if (this.listType == 'order') {
-                    this.currentStepIndex = 0
-                    this.currentLearnIndex = index
-                } else {
-                    this.currentUnitIndex = index
-                }
-                this.$refs['activityInfo'].checkFindRecord()
-            },
-            /**
-             * 查询编序式教材列表
-             * */
-            findOrderLearn() {
-                if (this.orderLearnList.length == 0) {
-                    let requestData = {
-                        code: this.$store.state.userInfo.TEAMModelId
                     }
-                    this.$api.learnActivity.FindOrderLearn(requestData).then(
-                        res => {
-                            if (res.error == null) {
-                                this.orderLearnList = res.result.data
-                            } else {
-                                this.$Message.error('API ERROR!')
-                            }
-                        },
-                        err => {
+                )
+            }
 
-                        }
-                    )
+        },
+        /**
+         * 查询最小单元列表
+         * */
+        findUnit() {
+            if (this.unitList.length == 0) {
+                let requestData = {
+                    code: this.$store.state.userInfo.TEAMModelId
                 }
-
-            },
-            /**
-             * 查询最小单元列表
-             * */
-            findUnit() {
-                if (this.unitList.length == 0) {
-                    let requestData = {
-                        code: this.$store.state.userInfo.TEAMModelId
-                    }
-                    this.$api.learnActivity.FindUnit(requestData).then(
-                        res => {
-                            if (!res.error) {
-                                this.unitList = res.units
-                            } else {
-                                this.$Message.error('API ERROR!')
-                            }
-                        },
-                        err => {
+                this.$api.learnActivity.FindUnit(requestData).then(
+                    res => {
+                        if (!res.error) {
+                            this.unitList = res.units
+                        } else {
                             this.$Message.error('API ERROR!')
                         }
-                    )
-                }
-
+                    },
+                    err => {
+                        this.$Message.error('API ERROR!')
+                    }
+                )
             }
-        },
-        created() {
-            //this.findOrderLearn()
-            this.isLoading = true
-            this.findUnit()
-            this.findClassroom()
+
         }
+    },
+    created() {
+        //this.findOrderLearn()
+        this.isLoading = true
+        this.findUnit()
+        this.findClassroom()
     }
+}
 </script>
 <style lang="less" scoped>
-    @import "./SelfLearn.less";
+@import "./SelfLearn.less";
 </style>
-<style>
-    .order-learn-content-wrap #loadingBox {
-        margin-top: 88px !important;
-    }
+<style lang="less">
+.order-learn-content-wrap #loadingBox {
+    margin-top: 88px !important;
+}
 
-    .publish-modal .ivu-picker-confirm-time {
-        color: #515a6e;
-    }
+.publish-modal .ivu-picker-confirm-time {
+    color: #515a6e;
+}
 
-    .order-learn-list-box .ivu-tabs-content {
-        height: 100%;
+.order-learn-list-box .ivu-tabs-content {
+    height: 100%;
+}
+.sort-dropdown {
+    .title {
+        color: white;
+        font-size: 14px;
+    }
+    .ivu-select-dropdown {
+        background-color: #2d2d2d;
+        border-radius: 2px;
+        border: 1px #464646 solid;
+        .ivu-dropdown-menu {
+            li {
+                color: #ccc;
+                font-size: 12px !important;
+                &:hover {
+                    color: #2d2d2d;
+                }
+            }
+        }
     }
+}
 </style>

+ 1 - 0
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/KnowledgeAnalysis/KnowledgeAnalysis.vue

@@ -81,6 +81,7 @@
 				        sortable: 'custom',
 				        key: item.className,
 				        render: (h, params) => {
+							console.log(origin)
 				            return h('span', ((Number(origin[params.row.name][index]))).toFixed(2) + '%')
 				        },
 				        minWidth: 150

+ 262 - 399
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.vue

@@ -1,323 +1,175 @@
 <template>
-    <div class="question-list-container" ref="questionContainer">
-        <!-- 左侧题目列表清单 -->
-        <div class="ql-left-box">
-            <!--<p style="font-size:28px;text-align:center;margin:20px 0">芳草小学2019年5月期中考试数学试卷</p>
+	<div class="question-list-container" ref="questionContainer">
+		<!-- 左侧题目列表清单 -->
+		<div class="ql-left-box">
+			<!--<p style="font-size:28px;text-align:center;margin:20px 0">芳草小学2019年5月期中考试数学试卷</p>
             <p style="font-size:16px;text-align:center">考试时间:120分钟&nbsp;&nbsp;&nbsp;出卷人:张纪中</p>-->
 
-            <!-- <span class="btn-back" @click="handleBackTo" ref="btnBack"><Icon type="ios-arrow-back" />{{$t('totalAnalysis.ql_text13')}}</span> -->
-            <Loading :top="300" v-show="dataLoading" type="3"></Loading>
-			<ExerciseList :propsList="questionList" :examScope="examScope" isAnalysis  @pageScroll="doScroll" ref="exList" isShowAnalysis></ExerciseList>
-        </div>
+			<!-- <span class="btn-back" @click="handleBackTo" ref="btnBack"><Icon type="ios-arrow-back" />{{$t('totalAnalysis.ql_text13')}}</span> -->
+			<Loading :top="300" v-show="dataLoading" type="3"></Loading>
+			<ExerciseList :propsList="questionList" :flatIds="flatList.length ? flatList.map(i => i.id) : []" :examScope="examScope"
+			 :analysisJson="paperAnalysisJson" :optionRate="paperOptionRateArr" isAnalysis
+				@pageScroll="doScroll" ref="exList" isShowAnalysis></ExerciseList>
+		</div>
 
-        <!-- 右侧题目列表题型概览 -->
-        <div class='ql-right-box' ref="rightBox" :style="{width: isOpen ? '17%' : '18%'}">
-			<Button type="info" @click="handleBackTo" style="width: 100%;height: 50px;margin-bottom: 15px;border-radius: 0;">返回上级</Button>
+		<!-- 右侧题目列表题型概览 -->
+		<div class='ql-right-box' ref="rightBox" :style="{width: isOpen ? '17%' : '18%'}">
+			<Button type="info" @click="handleBackTo"
+				style="width: 100%;height: 50px;margin-bottom: 15px;border-radius: 0;">{{ $t('totalAnalysis.backUp')}}</Button>
 			<div style="background-color: #fff;">
 				<div class="ql-right-score">
-					<p style="margin-top: 20px;">试卷科目:{{ $store.state.totalAnalysis.currentSubject }}</p>
-					<p style="margin-top: 10px;">试卷题数:{{ questionList.length }}</p>
-				    <p style="margin-top: 10px;">{{$t('totalAnalysis.ql_text1')}} :<span>{{sumArr(questionList.map(item => item.score))}} {{$t('totalAnalysis.ql_text8')}}</span></p> 
+					<p style="margin-top: 20px;">{{ $t('totalAnalysis.paperSubject')}}:{{ $store.state.totalAnalysis.currentSubject }}</p>
+					<p style="margin-top: 10px;">{{ $t('totalAnalysis.paperItemsCount')}}:{{ questionList.length }}</p>
+					<p style="margin-top: 10px;">{{$t('totalAnalysis.ql_text1')}}
+						:<span>{{sumArr(questionList.map(item => item.score))}} {{$t('totalAnalysis.ql_text8')}}</span>
+					</p>
 				</div>
-				
+
 				<div class="ql-right-list">
-				        <div>
-				            <div class="ql-right-part" v-if="SingleList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text2')}}({{sumArr(SingleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-				                    <span class="ql-right-item" v-for="(item,index) in SingleList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-				                </div>
-				            </div>
-				            <div class="ql-right-part" v-if="MultipleList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text3')}}({{sumArr(MultipleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-				                    <span class="ql-right-item" v-for="(item,index) in MultipleList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-				                </div>
-				            </div>
-				            <div class="ql-right-part" v-if="JudgeList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text4')}}({{sumArr(JudgeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-				                    <span class="ql-right-item" v-for="(item,index) in JudgeList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-				                </div>
-				            </div>
-				            <div class="ql-right-part" v-if="CompleteList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text5')}}({{sumArr(CompleteList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-				                    <span class="ql-right-item" v-for="(item,index) in CompleteList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-				                </div>
-				            </div>
-				            <div class="ql-right-part" v-if="SubjectiveList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text6')}}({{sumArr(SubjectiveList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-				                    <span class="ql-right-item" v-for="(item,index) in SubjectiveList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-				                </div>
-				            </div>
-							<div class="ql-right-part" v-if="ConnectorList.length">
-							    <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text14')}}({{sumArr(ConnectorList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-							    <div class="ql-right-items">
-							        <span class="ql-right-item" v-for="(item,index) in ConnectorList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-							    </div>
+					<div>
+						<div class="ql-right-part" v-if="SingleList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text2')}}({{sumArr(SingleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in SingleList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
+							</div>
+						</div>
+						<div class="ql-right-part" v-if="MultipleList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text3')}}({{sumArr(MultipleList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in MultipleList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
+							</div>
+						</div>
+						<div class="ql-right-part" v-if="JudgeList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text4')}}({{sumArr(JudgeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in JudgeList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
+							</div>
+						</div>
+						<div class="ql-right-part" v-if="CompleteList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text5')}}({{sumArr(CompleteList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in CompleteList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
+							</div>
+						</div>
+						<div class="ql-right-part" v-if="SubjectiveList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text6')}}({{sumArr(SubjectiveList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in SubjectiveList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
 							</div>
-							<div class="ql-right-part" v-if="CorrectList.length">
-							    <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text15')}}({{sumArr(CorrectList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-							    <div class="ql-right-items">
-							        <span class="ql-right-item" v-for="(item,index) in CorrectList" :key="index" @click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"  :data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
-							    </div>
+						</div>
+						<div class="ql-right-part" v-if="ConnectorList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text14')}}({{sumArr(ConnectorList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in ConnectorList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
 							</div>
-				            <div class="ql-right-part" v-if="ComposeList.length">
-				                <span class="ql-right-part-title"><span class="ql-line"></span>{{$t('totalAnalysis.ql_text7')}}({{sumArr(ComposeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
-				                <div class="ql-right-items">
-									<!-- 如果是综合题 则需要把小题题序放出来 -->
-									<span v-for="(item,index) in ComposeList" :key="index" style="background-color: none;" class="ql-right-items">
-										<span class="ql-right-item" v-for="(child,childIndex) in item.children" :key="childIndex" @click="handleItemClick(item,$event)" :ref="'indexRef' + (flatList.indexOf(child))"  :data-order="flatList.indexOf(child)">{{ fillIndexOrder(flatList.indexOf(child)) }} ({{getIndexOrder(item)}} - {{ childIndex + 1 }})</span>
-									</span>
-				                </div>
-				            </div>
-				        </div>
+						</div>
+						<div class="ql-right-part" v-if="CorrectList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text15')}}({{sumArr(CorrectList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<span class="ql-right-item" v-for="(item,index) in CorrectList" :key="index"
+									@click="handleItemClick(item,$event)" :ref="'indexRef' + flatList.indexOf(item)"
+									:data-order="flatList.indexOf(item)">{{getIndexOrder(item)}}</span>
+							</div>
+						</div>
+						<div class="ql-right-part" v-if="ComposeList.length">
+							<span class="ql-right-part-title"><span
+									class="ql-line"></span>{{$t('totalAnalysis.ql_text7')}}({{sumArr(ComposeList.map(item => item.score))}}{{$t('totalAnalysis.ql_text8')}})</span>
+							<div class="ql-right-items">
+								<!-- 如果是综合题 则需要把小题题序放出来 -->
+								<span v-for="(item,index) in ComposeList" :key="index" style="background-color: none;"
+									class="ql-right-items">
+									<span class="ql-right-item" v-for="(child,childIndex) in item.children"
+										:key="childIndex" @click="handleItemClick(item,$event)"
+										:ref="'indexRef' + (flatList.indexOf(child))"
+										:data-order="flatList.indexOf(child)">{{ fillIndexOrder(flatList.indexOf(child)) }}
+										({{getIndexOrder(item)}} - {{ childIndex + 1 }})</span>
+								</span>
+							</div>
+						</div>
+					</div>
 				</div>
 			</div>
-            
-        </div>
-    </div>
+
+		</div>
+	</div>
 </template>
 
 <script>
-    import BaseLine from '@/components/student-analysis/total/BaseLine.vue'
-    import BaseRateLine from '@/components/student-analysis/total/BaseRateLine.vue'
-    import ExerciseList from '@/components/evaluation/ExerciseList.vue'
-    export default {
-        components: {
-            BaseRateLine, BaseLine,ExerciseList
-        },
-        data() {
-            return {
-				examScope:null,
-                dataLoading: false,
-				isOpen:true,
-                activeCollapseIndex: [],
-                isFixed: false,
-                isLoadingEcharts: false,
-                isShowAnswerExplain: false,
-                tableData: [],
-                optionsData: [],
-                collapseList: [],
-                questionList: [],
-				flatList:[],
-                SingleList: [],
-                MultipleList: [],
-                JudgeList: [],
-                CompleteList: [],
-                SubjectiveList: [],
-                ConnectorList: [],
-                CorrectList: [],
-                ComposeList: [],
-                diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
-                dataColumns: [
-                    {
-                        title: '知识点',
-                        key: 'knowledgePoint',
-                        align: 'center',
-                        width: 150
-                    },
-                    {
-                        title: '落点区域',
-                        key: 'areaName',
-                        align: 'center'
-                    },
-                    {
-                        title: '配分',
-                        key: 'score',
-                        align: 'center'
-                    },
-                    {
-                        title: '难易度',
-                        key: 'diff',
-                        align: 'center'
-                    },
-                    {
-                        title: '鉴别度',
-                        key: 'identify',
-                        align: 'center',
-                        render: function (h, params) {
-                            return h('span', (Number(params.row.identify)).toFixed(2))
-                        }
-                    },
-                    {
-                        title: '正答率',
-                        align: 'center',
-                        key: 'classScoreRate'
-                    },
-                    {
-                        title: '高分组正答率',
-                        align: 'center',
-                        key: 'PH',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.PH)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: '低分组正答率',
-                        align: 'center',
-                        key: 'PL',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.PL)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R1',
-                        align: 'center',
-                        key: 'R1',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R1)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R2',
-                        key: 'R2',
-                        align: 'center',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R2)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R3',
-                        align: 'center',
-                        key: 'R3',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R3)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R4',
-                        align: 'center',
-                        key: 'R4',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R4)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R5',
-                        align: 'center',
-                        key: 'R5',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R5)) * 100).toFixed(0) + '%')
-                        }
-                    },
-                    {
-                        title: 'R6',
-                        align: 'center',
-                        key: 'R6',
-                        render: function (h, params) {
-                            return h('span', ((Number(params.row.R6)) * 100).toFixed(0) + '%')
-                        }
-                    }
-                ],
-                optionColumns: [
-                    {
-                        title: '选项',
-                        key: 'option',
-                        align: 'center',
-                        width: 150
-                    },
-                    {
-                        title: '选答人数',
-                        key: 'num',
-                        align: 'center'
-                    },
-                    {
-                        title: '选答率',
-                        key: 'rate',
-                        align: 'center',
-                        render: (h, params) => {
-                            return h('div', [
-                                h('Progress', {
-                                    props: {
-                                        percent: params.row.rate,
-                                        strokeColor: params.row.isTrue ? '#14db14' : '#b5bcbe'
-                                    }
-                                })
-                            ])
-                        }
-                    },
-                    {
-                        title: '高分组选答率',
-                        align: 'center',
-                        key: 'PH',
-                        render: function (h, params) {
-                            return h('span', params.row.PH + '%')
-                        }
-                    },
-                    {
-                        title: '低分组选答率',
-                        align: 'center',
-                        key: 'PL',
-                        render: function (h, params) {
-                            return h('span', params.row.PL + '%')
-                        }
-                    }
-                ],
-                scrollTop: 0,
-                fromRoutePath: null
-
-            }
-        },
-        created() {
-            let that = this
-            let parentVm = this.$parent.$parent.$parent
-            parentVm.isShowQuestions = true
+	
+	import ExerciseList from '@/components/evaluation/ExerciseList.vue'
+	export default {
+		components: {
 			
+			ExerciseList
+		},
+		data() {
+			return {
+				examScope: null,
+				dataLoading: false,
+				isOpen: true,
+				activeCollapseIndex: [],
+				isFixed: false,
+				isLoadingEcharts: false,
+				isShowAnswerExplain: false,
+				tableData: [],
+				optionsData: [],
+				collapseList: [],
+				questionList: [],
+				flatList: [],
+				SingleList: [],
+				MultipleList: [],
+				JudgeList: [],
+				CompleteList: [],
+				SubjectiveList: [],
+				ConnectorList: [],
+				CorrectList: [],
+				ComposeList: [],
+				diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
+				scrollTop: 0,
+				fromRoutePath: null,
+				paperAnalysisJson: [],
+				paperOptionRateArr:[]
+			}
+		},
+		created() {
+			let that = this
+			let parentVm = this.$parent.$parent.$parent
+			parentVm.isShowQuestions = true
+
 			let curExam = JSON.parse(localStorage.getItem('curExam'))
 			let curSubjectIndex = curExam.subjects.map(i => i.name).indexOf(this.$store.state.totalAnalysis.currentSubject)
 			console.log(curSubjectIndex)
-			console.log('当前的评测数据',curExam)
+			console.log('当前的评测数据', curExam)
 			this.examScope = curExam.scope
-			console.log('dangqia',this.examScope)
 			let curPaper = curExam.papers[curSubjectIndex]
-			this.initFullPaper(curPaper,curExam)
+			this.initFullPaper(curPaper, curExam)
+		},
 
-            
-            this.optionsData = [
-                {
-                    option: 'A',
-                    isTrue: false,
-                    num: 12,
-                    rate: 40,
-                    PH: 10,
-                    PL: 60
-                },
-                {
-                    option: 'B',
-                    isTrue: false,
-                    num: 6,
-                    rate: 20,
-                    PH: 10,
-                    PL: 23
-                },
-                {
-                    option: 'C',
-                    isTrue: true,
-                    num: 9,
-                    rate: 30,
-                    PH: 70,
-                    PL: 10
-                },
-                {
-                    option: 'D',
-                    isTrue: false,
-                    num: 3,
-                    rate: 10,
-                    PH: 10,
-                    PL: 7
-                }
-            ]
-        },
+		methods: {
 
-        methods: {
-			
-			async initFullPaper(examPaper,exam){
+			async initFullPaper(examPaper, exam) {
 				console.log(examPaper.name)
-				examPaper.examId = exam.code.replace('Exam-','')
-				let fullPaperJson =  await this.$evTools.getFullPaper(examPaper,exam.scope)
+				examPaper.examId = exam.code.replace('Exam-', '')
+				let fullPaperJson = await this.$evTools.getFullPaper(examPaper, exam.scope)
 				this.questionList = fullPaperJson.item
 				this.SingleList = this.questionList.filter(item => item.type === 'single')
 				this.MultipleList = this.questionList.filter(item => item.type === 'multiple')
@@ -328,8 +180,8 @@
 				this.CorrectList = this.questionList.filter(item => item.type === 'correct')
 				this.ComposeList = this.questionList.filter(item => item.type === 'compose')
 				this.dataLoading = false
-				console.log('当前的评测试卷数据',fullPaperJson)
-				
+				console.log('当前的评测试卷数据', fullPaperJson)
+
 				// 如果是试题页面过来带有题序 则获取指定题目并进行滚动
 				let qIndex = this.$route.query.QIndex
 				if (qIndex) {
@@ -339,13 +191,14 @@
 						allItems = allItems.concat(i.type === 'compose' ? i.children : [i])
 					})
 					this.flatList = allItems
-					console.log('拉平后的题目',allItems)
+					console.log('拉平后的题目', allItems)
 					// 获取当前试题的分析数据
-					// let itemAnalysisArr = this.getExerciseList()
+					this.paperAnalysisJson = this.getExerciseList()
 					this.$nextTick(() => {
 						console.log(this.$refs['indexRef' + (qIndex - 1)][0])
 						setTimeout(() => {
-							this.$refs['indexRef' + (qIndex - 1)][0].click() // 根据路由携带的题序 来触发对应题序的点击事件 完成滚动
+							this.$refs['indexRef' + (qIndex - 1)][0]
+							.click() // 根据路由携带的题序 来触发对应题序的点击事件 完成滚动
 						}, 1000)
 					})
 				} else {
@@ -354,9 +207,9 @@
 					})
 				}
 			},
-			
+
 			/* 页面滚动逻辑 */
-			doScroll(scrollDistance){
+			doScroll(scrollDistance) {
 				this.$nextTick(() => {
 					let parentVm = this.$parent.$parent.$parent
 					parentVm.$refs['vs'].scrollTo({
@@ -367,79 +220,78 @@
 					);
 				})
 			},
-			
-            // 指定容器滚动到指定位置
-            scrollToTop(element, to, duration) {
-                if (duration <= 0) return
-                const diff = to - element.scrollTop
-                const perTick = diff / duration * 10
-                this.timer = setTimeout(() => {
-                    element.scrollTop += perTick
-                    if (element.scrollTop === to) return
-                    this.scrollToTop(element, to, duration - 10)
-                }, 10)
-            },
 
-            // 点击右边题序 获取到题目DOM 进行滚动操作
-            handleItemClick(item, e) {
-				console.log(e)
+			// 指定容器滚动到指定位置
+			scrollToTop(element, to, duration) {
+				if (duration <= 0) return
+				const diff = to - element.scrollTop
+				const perTick = diff / duration * 10
+				this.timer = setTimeout(() => {
+					element.scrollTop += perTick
+					if (element.scrollTop === to) return
+					this.scrollToTop(element, to, duration - 10)
+				}, 10)
+			},
+
+			// 点击右边题序 获取到题目DOM 进行滚动操作
+			handleItemClick(item, e) {
 				this.$nextTick(() => {
 					let parentVm = this.$parent.$parent.$parent
 					let currentSpan = e.target || e
 					let allList = document.getElementsByClassName('ql-right-item')
-					let questionList = this.$refs.exList.$el.getElementsByClassName('exercise-item')
+					let questionList = this.$refs.exList.$el.getElementsByClassName('cp-exercise-item')
 					let itemIndex = this.questionList.indexOf(item)
 					let questionDom = questionList[itemIndex]
 					questionDom.style.border = '2px solid #2db7f5'
 					setTimeout(() => {
 						questionDom.style.border = '2px solid transparent'
-					},2000)
+					}, 2000)
 					this.doScroll(questionDom.offsetTop)
 					// 伪数组处理统一背景颜色
 					Array.prototype.slice.call(allList).forEach(item => {
-					    item.style.background = '#2db7f5'
+						item.style.background = '#2db7f5'
 					})
 					// 将当前选中项修改选中色
 					currentSpan.style.background = '#139c51'
 					this.$refs.exList.collapseList = [itemIndex]
 				})
-                
-            },
 
-            // 点击返回
-            handleBackTo() {
-                // this.$refs.btnBack.style.display = 'none'
-                this.$parent.$parent.$parent.isShowQuestions = false
-                this.$router.back(-1)
-            },
+			},
+
+			// 点击返回
+			handleBackTo() {
+				// this.$refs.btnBack.style.display = 'none'
+				this.$parent.$parent.$parent.isShowQuestions = false
+				this.$router.back(-1)
+			},
 
-            // 折叠面板点击事件
-            handleCollapseChange(val) {
-                let questionIndex = val[0]
-                if (questionIndex === '999') return
-                if (questionIndex && this.collapseList.indexOf(questionIndex) === -1) {
-                    this.collapseList.push(questionIndex)
-                    this.activeCollapseIndex = questionIndex
-                } else if (questionIndex === 0) {
-                    this.collapseList.push(questionIndex)
-                    this.activeCollapseIndex = questionIndex
-                } else {
-                    // console.log("加入异常", questionIndex);
-                    // console.log("加入异常", this.collapseList.indexOf(questionIndex));
-                }
-                this.activeCollapseIndex = this.collapseList
-            },
+			// 折叠面板点击事件
+			handleCollapseChange(val) {
+				let questionIndex = val[0]
+				if (questionIndex === '999') return
+				if (questionIndex && this.collapseList.indexOf(questionIndex) === -1) {
+					this.collapseList.push(questionIndex)
+					this.activeCollapseIndex = questionIndex
+				} else if (questionIndex === 0) {
+					this.collapseList.push(questionIndex)
+					this.activeCollapseIndex = questionIndex
+				} else {
+					// console.log("加入异常", questionIndex);
+					// console.log("加入异常", this.collapseList.indexOf(questionIndex));
+				}
+				this.activeCollapseIndex = this.collapseList
+			},
 
-            // 返回题目区域总分 字符串换算
-            sumArr(arr) {
-				if(arr.length){
-					return arr.reduce((a,b) => a + b)
-				}else{
+			// 返回题目区域总分 字符串换算
+			sumArr(arr) {
+				if (arr.length) {
+					return arr.reduce((a, b) => a + b)
+				} else {
 					return 0
 				}
-                
-            },
-			
+
+			},
+
 			/* 获取所有试题的对应分析数据 */
 			getExerciseList() {
 				let analysisJson = JSON.parse(JSON.stringify(this.getAnalysisJson))
@@ -451,81 +303,92 @@
 					analysisJson.paperKey.forEach((key, index) => {
 						obj[key] = exercise[index]
 					})
-			
+
 					analysisJson.classes.forEach(classItem => {
 						obj[classItem.className] = classItem.subjects[curSubjectIndex].item[exerciseIndex]
 					})
 					result.push(obj)
 				})
+				
+				let curSubject = analysisJson.subjects[curSubjectIndex]
+				curSubject.record.forEach((i,itemIndex) => {
+					this.paperOptionRateArr.push({
+						record:curSubject.record.length ? curSubject.record[itemIndex] : {},
+						ph:curSubject.phc.length ? curSubject.phc[itemIndex] : {},
+						pl:curSubject.plc.length ? curSubject.plc[itemIndex] : {}
+					})
+				})
+				
 				return result
 			},
-        },
+		},
 
-        mounted() {
+		mounted() {
 			this.$EventBus.$off('onCollapseChange')
-			this.$EventBus.$on('onCollapseChange',val => {
+			this.$EventBus.$on('onCollapseChange', val => {
 				// 如果侧边栏展开的时候
 				this.isOpen = !val
 			})
-			
-			
-			
-			
 
-        },
 
-        computed: {
-            // 获取最新滚动数据
-            getScrollTop() {
-                let top = this.$store.state.totalAnalysis.scrollTop
-                return top
-            },
-            // 获取最新试题数据
-            getAnalysisJson() {
-            	return this.$store.state.totalAnalysis.analysisJson
-            },
+
+
+
+		},
+
+		computed: {
+			// 获取最新滚动数据
+			getScrollTop() {
+				let top = this.$store.state.totalAnalysis.scrollTop
+				return top
+			},
+			// 获取最新试题数据
+			getAnalysisJson() {
+				return this.$store.state.totalAnalysis.analysisJson
+			},
 			// 替换题序
-			getIndexOrder(){
+			getIndexOrder() {
 				return item => {
-					return this.questionList.indexOf(item) + 1 > 9 ? this.questionList.indexOf(item) + 1 : '0' + (this.questionList.indexOf(item) + 1)
+					return this.questionList.indexOf(item) + 1 > 9 ? this.questionList.indexOf(item) + 1 : '0' + (this
+						.questionList.indexOf(item) + 1)
 				}
 			},
 			// 替换题序
-			fillIndexOrder(index){
+			fillIndexOrder(index) {
 				return index => {
 					return index + 1 > 9 ? index + 1 : '0' + (index + 1)
 				}
 			}
-        },
-        watch: {
-            getScrollTop(val) {
-                this.scrollTop = val
-                // let box = this.$refs.rightBox
-                // let btnBack = this.$refs.btnBack
-                // let t = 232 - this.scrollTop
-                // box.style.top = this.scrollTop >= 129 ? '100px' : (t + 'px')
-                // btnBack.style.top = this.scrollTop >= 129 ? (this.scrollTop - 152) + 'px' : '0px'
-            },
-        }
-    }
+		},
+		watch: {
+			getScrollTop(val) {
+				this.scrollTop = val
+				// let box = this.$refs.rightBox
+				// let btnBack = this.$refs.btnBack
+				// let t = 232 - this.scrollTop
+				// box.style.top = this.scrollTop >= 129 ? '100px' : (t + 'px')
+				// btnBack.style.top = this.scrollTop >= 129 ? (this.scrollTop - 152) + 'px' : '0px'
+			},
+		}
+	}
 </script>
 
 <style src="./QuestionList.css" scoped></style>
 
 <style>
-    .ql-item .ivu-collapse {
-        border: 0;
-    }
+	.ql-item .ivu-collapse {
+		border: 0;
+	}
 
-        .ql-item .ivu-collapse > .ivu-collapse-item > .ivu-collapse-header {
-            color: #06a9bb;
-        }
+	.ql-item .ivu-collapse>.ivu-collapse-item>.ivu-collapse-header {
+		color: #06a9bb;
+	}
 
-            .ql-item .ivu-collapse > .ivu-collapse-item > .ivu-collapse-header > .ivu-icon {
-                vertical-align: unset;
-            }
+	.ql-item .ivu-collapse>.ivu-collapse-item>.ivu-collapse-header>.ivu-icon {
+		vertical-align: unset;
+	}
 
-        .ql-item .ivu-collapse > .ivu-collapse-item {
-            border-top: 0;
-        }
+	.ql-item .ivu-collapse>.ivu-collapse-item {
+		border-top: 0;
+	}
 </style>

+ 3 - 3
TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue

@@ -31,7 +31,7 @@
 										<div class="hw-item-info">
 											<span class="hw-item-nums">
 												<Icon type="md-time" size="14" style="margin-right:5px" />
-												{{ $tools.formatTime(item.startTime) }}
+												{{ $tools.formatTime(item.startTime,'yyyy-MM-dd hh:mm') }}
 											</span>
 											<span class="hw-item-status"
 												:style="{ background: (item.progress === 'pending' ? '#0BADD4' : item.progress === 'going' ? '#088951' : '#949594')}">{{ item.progress === 'pending' ? $t('vote.pending') : item.progress === 'going' ? $t('vote.going') : $t('vote.finish') }}</span>
@@ -184,10 +184,10 @@
 							code: 'B',
 							value: ''
 						}],
-						endTime: '',
 						publishModel: '0',
 						selectMax: 1,
-						startTime: '',
+						endTime: new Date(new Date().toLocaleDateString()).getTime() + 2 * 24 * 60 * 60 * 1000 - 1,
+						startTime:new Date().getTime(),
 						description: '',
 						secret: false,
 						progress: 'pending'

文件差异内容过多而无法显示
+ 3826 - 3823
TEAMModelOS/Controllers/Analysis/AchievementController.cs


文件差异内容过多而无法显示
+ 352 - 701
TEAMModelOS/Controllers/Analysis/AnalysisController.cs


+ 19 - 3
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -477,6 +477,19 @@ namespace TEAMModelOS.Controllers
                 List<Task<string>> tasks = new List<Task<string>>();
                 foreach (ExamClassResult result in examClassResults) {
                     int index = result.studentIds.IndexOf(studentId.ToString());
+                    //存放客观题作答详情
+                    if (result.ans.Count == 0) {
+                        foreach (string cc in result.studentIds)
+                        {
+                            List<List<string>> anc = new List<List<string>>();
+                            foreach (List<string> opc in standard) {                              
+                                anc.Add(new List<string>());
+                            }
+                            result.ans.Add(anc);
+                        }
+                    }
+                    
+                    //List<List<string>> oq = new List<List<string>>();
                     //classResult.studentAnswers[index] = ans;
                     if (index == -1)
                     {
@@ -514,6 +527,7 @@ namespace TEAMModelOS.Controllers
                     //List<(int index ,string content, double count)> acount = new List<(int index,string content, double count)>();
                     for (int i = 0; i < ans.Count; i++)
                     {
+                        //List<string> op = new List<string>();
                         var ac = ans[i].Count;
                         var sc = standard[i].Count;
                         //记录次数
@@ -522,6 +536,7 @@ namespace TEAMModelOS.Controllers
                         //算分处理
                         if (sc > 0)
                         {
+                            result.ans[index][i] = ans[i];
                             if (ac == sc && sc == 1)
                             {
                                 foreach (string right in ans[i])
@@ -626,13 +641,14 @@ namespace TEAMModelOS.Controllers
                                                 break;
                                         }
                                     }
-                                    else {
+                                    else
+                                    {
                                         result.studentScores[newIndex][i] = 0;
                                     }
-                                    
+
                                 }
                             }
-                        }
+                        }                       
                     }
                     /*if (result.studentScores.Contains(-1)) { 
 

+ 5 - 0
TEAMModelOS/Controllers/Common/SurveyController.cs

@@ -75,6 +75,11 @@ namespace TEAMModelOS.Controllers
                 request.code = request.pk + "-" + request.code;
                 long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 request.createTime = now;
+                //如果设置的时间是小于当前时间则立即发布
+                if (request.startTime <= 0)
+                {
+                    request.startTime = now;
+                }
                 if (string.IsNullOrEmpty(request.id))
                 {
                     request.id = Guid.NewGuid().ToString();

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

@@ -73,11 +73,15 @@ namespace TEAMModelOS.Controllers.Learn
                 request.code = request.pk + "-" + request.code;
                 long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 request.createTime = now;
+                //如果设置的时间是小于当前时间则立即发布
+                if (request.startTime <= 0) {
+                    request.startTime = now;
+                }
                 if (string.IsNullOrEmpty(request.id))
                 {
                    
                     request.id = Guid.NewGuid().ToString();
-                    if (request.startTime > now)
+                    if (request.startTime >= now)
                     {
                         request.progress = "pending";
                     }

+ 20 - 7
TEAMModelOS/Controllers/School/CourseController.cs

@@ -193,13 +193,26 @@ namespace TEAMModelOS.Controllers
                 stuList.code = stuList.pk + "-" + stuList.code;
                 if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                 {
-                    //var oldStuList=  await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<StuList>(stuList.id, new PartitionKey(stuList.code));
-                   // if (oldStuList.GetRawResponse().Status == 200)
-                    //{
-                    //}
-                    //else if (oldStuList.GetRawResponse().Status == 404) { 
-                    //}
-                     stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{originCode}"));
+                    if (stuList.students.IsNotEmpty()) {
+                        var query = $"SELECT distinct value(c)  FROM c    where  c.id='{stuList.id}'";
+                        List<StuList> odlStus = new List<StuList>();
+                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: query,
+                                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{originCode}") }))
+                        {
+                            odlStus.Add(item);
+                        }
+                        if (odlStus.Count > 0 && odlStus[0].students.IsNotEmpty())
+                        {
+                            StuList oldStu = odlStus[0];
+                            foreach (var stu in oldStu.students) {
+                                stuList.students.ForEach(x => { 
+                                  //  x.id
+                                });
+                            }
+                        }
+                    }
+                    
+                   stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{originCode}"));
                 }
                 else
                 {

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

@@ -36,7 +36,7 @@ namespace TEAMModelOS.Controllers
         /// </summary>
         /// <param name="request">
         ///加入的班级信息                      ?classes:[{"classid":"S-C-00001","scope":"school"},{"classid":"P-C-00004","scope":"private"}]
-        ///活动类型                            ?"type":"vote"/"exam"/"homework"/"learn"/"survey"" // vote投票 survey问卷 exam评测 learn学习活动 homework作业活动
+        ///活动类型                            ?"type":"Vote"/"Exam"/"Homework"/"Learn"/"Survey"" // Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
         ///时间筛选范围开始时间 默认30天之前   ?"stime":1608274766154  
         ///时间筛选范围结束时间 默认当前时间   ?"etime":1608274766666 
         ///是否展示列表的 Tips                 ? "tips":true/false

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

@@ -117,6 +117,11 @@ namespace TEAMModelOS.Controllers.XTest
         }
 
 
+
+
+
+
+
         [ProducesDefaultResponseType]
         //[AuthToken(Roles = "teacher")]
         [HttpPost("fixExamActivity")]

+ 113 - 0
TEAMModelOS/Properties/ServiceDependencies/TeammodelOS - Web Deploy/profile.arm.json

@@ -0,0 +1,113 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
+  "contentVersion": "1.0.0.0",
+  "metadata": {
+    "_dependencyType": "appService.windows"
+  },
+  "parameters": {
+    "resourceGroupName": {
+      "type": "string",
+      "defaultValue": "TEAMModelChengdu",
+      "metadata": {
+        "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
+      }
+    },
+    "resourceGroupLocation": {
+      "type": "string",
+      "defaultValue": "",
+      "metadata": {
+        "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
+      }
+    },
+    "resourceName": {
+      "type": "string",
+      "defaultValue": "TeammodelOS",
+      "metadata": {
+        "description": "Name of the main resource to be created by this template."
+      }
+    },
+    "resourceLocation": {
+      "type": "string",
+      "defaultValue": "[parameters('resourceGroupLocation')]",
+      "metadata": {
+        "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
+      }
+    }
+  },
+  "variables": {
+    "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+    "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]"
+  },
+  "resources": [
+    {
+      "type": "Microsoft.Resources/resourceGroups",
+      "name": "[parameters('resourceGroupName')]",
+      "location": "[parameters('resourceGroupLocation')]",
+      "apiVersion": "2019-10-01"
+    },
+    {
+      "type": "Microsoft.Resources/deployments",
+      "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+      "resourceGroup": "[parameters('resourceGroupName')]",
+      "apiVersion": "2019-10-01",
+      "dependsOn": [
+        "[parameters('resourceGroupName')]"
+      ],
+      "properties": {
+        "mode": "Incremental",
+        "template": {
+          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+          "contentVersion": "1.0.0.0",
+          "resources": [
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[parameters('resourceName')]",
+              "type": "Microsoft.Web/sites",
+              "apiVersion": "2015-08-01",
+              "tags": {
+                "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
+              },
+              "dependsOn": [
+                "[variables('appServicePlan_ResourceId')]"
+              ],
+              "kind": "app",
+              "properties": {
+                "name": "[parameters('resourceName')]",
+                "kind": "app",
+                "httpsOnly": true,
+                "reserved": false,
+                "serverFarmId": "[variables('appServicePlan_ResourceId')]",
+                "siteConfig": {
+                  "metadata": [
+                    {
+                      "name": "CURRENT_STACK",
+                      "value": "dotnetcore"
+                    }
+                  ]
+                }
+              },
+              "identity": {
+                "type": "SystemAssigned"
+              }
+            },
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[variables('appServicePlan_name')]",
+              "type": "Microsoft.Web/serverFarms",
+              "apiVersion": "2015-08-01",
+              "sku": {
+                "name": "S1",
+                "tier": "Standard",
+                "family": "S",
+                "size": "S1"
+              },
+              "properties": {
+                "name": "[variables('appServicePlan_name')]"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 113 - 0
TEAMModelOS/Properties/ServiceDependencies/teammodelos-dep - Web Deploy/profile.arm.json

@@ -0,0 +1,113 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
+  "contentVersion": "1.0.0.0",
+  "metadata": {
+    "_dependencyType": "appService.windows"
+  },
+  "parameters": {
+    "resourceGroupName": {
+      "type": "string",
+      "defaultValue": "TEAMModelChengdu",
+      "metadata": {
+        "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
+      }
+    },
+    "resourceGroupLocation": {
+      "type": "string",
+      "defaultValue": "",
+      "metadata": {
+        "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support."
+      }
+    },
+    "resourceName": {
+      "type": "string",
+      "defaultValue": "dep",
+      "metadata": {
+        "description": "Name of the main resource to be created by this template."
+      }
+    },
+    "resourceLocation": {
+      "type": "string",
+      "defaultValue": "[parameters('resourceGroupLocation')]",
+      "metadata": {
+        "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
+      }
+    }
+  },
+  "variables": {
+    "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+    "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]"
+  },
+  "resources": [
+    {
+      "type": "Microsoft.Resources/resourceGroups",
+      "name": "[parameters('resourceGroupName')]",
+      "location": "[parameters('resourceGroupLocation')]",
+      "apiVersion": "2019-10-01"
+    },
+    {
+      "type": "Microsoft.Resources/deployments",
+      "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]",
+      "resourceGroup": "[parameters('resourceGroupName')]",
+      "apiVersion": "2019-10-01",
+      "dependsOn": [
+        "[parameters('resourceGroupName')]"
+      ],
+      "properties": {
+        "mode": "Incremental",
+        "template": {
+          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
+          "contentVersion": "1.0.0.0",
+          "resources": [
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[parameters('resourceName')]",
+              "type": "Microsoft.Web/sites",
+              "apiVersion": "2015-08-01",
+              "tags": {
+                "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty"
+              },
+              "dependsOn": [
+                "[variables('appServicePlan_ResourceId')]"
+              ],
+              "kind": "app",
+              "properties": {
+                "name": "[parameters('resourceName')]",
+                "kind": "app",
+                "httpsOnly": true,
+                "reserved": false,
+                "serverFarmId": "[variables('appServicePlan_ResourceId')]",
+                "siteConfig": {
+                  "metadata": [
+                    {
+                      "name": "CURRENT_STACK",
+                      "value": "dotnetcore"
+                    }
+                  ]
+                }
+              },
+              "identity": {
+                "type": "SystemAssigned"
+              }
+            },
+            {
+              "location": "[parameters('resourceLocation')]",
+              "name": "[variables('appServicePlan_name')]",
+              "type": "Microsoft.Web/serverFarms",
+              "apiVersion": "2015-08-01",
+              "sku": {
+                "name": "S1",
+                "tier": "Standard",
+                "family": "S",
+                "size": "S1"
+              },
+              "properties": {
+                "name": "[variables('appServicePlan_name')]"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 4 - 3
TEAMModelOS/appsettings.Development.json

@@ -26,9 +26,10 @@
       "Container": "teammodelos"
     },
     "Cosmos": {
-      "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;",
-      "Database": [ "TEAMModelOS" ],
-      "ScanModel": [ "TEAMModelOS" ]
+      "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
+    },
+    "CosmosDep": {
+      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
     },
     "Redis": {
       "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"

+ 4 - 1
TEAMModelOS/appsettings.json

@@ -27,7 +27,10 @@
       "Container": "teammodelos"
     },
     "Cosmos": {
-      "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"     
+      "ConnectionString": "AccountEndpoint=https://teammodelos.documents.azure.cn:443/;AccountKey=clF73GwPECfP1lKZTCvs8gLMMyCZig1HODFbhDUsarsAURO7TcOjVz6ZFfPqr1HzYrfjCXpMuVD5TlEG5bFGGg==;"
+    },
+    "CosmosDep": {
+      "ConnectionString": "AccountEndpoint=https://cdhabookdep-free.documents.azure.cn:443/;AccountKey=JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A==;"
     },
     "Redis": {
       "ConnectionString": "CoreRedisCN.redis.cache.chinacloudapi.cn:6380,password=LyJWP1ORJdv+poXWofAF97lhCEQPg1wXWqvtzXGXQuE=,ssl=True,abortConnect=False"