Browse Source

Merge branch 'TPE/develop' into TPE/feat/studentOpt

Mickey 4 years ago
parent
commit
7234300041
100 changed files with 4097 additions and 2194 deletions
  1. 150 5
      TEAMModelFunction/MonitorCosmosDB.cs
  2. 22 9
      TEAMModelFunction/ServiceBusTopic.cs
  3. 8 8
      TEAMModelFunction/host.json
  4. 9 4
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs
  5. 75 26
      TEAMModelOS/ClientApp/public/index.html
  6. 4 0
      TEAMModelOS/ClientApp/src/api/courseMgmt.js
  7. 1 1
      TEAMModelOS/ClientApp/src/api/http.js
  8. 11 5
      TEAMModelOS/ClientApp/src/api/learnActivity.js
  9. 2 1
      TEAMModelOS/ClientApp/src/api/login.js
  10. 4 4
      TEAMModelOS/ClientApp/src/api/newData.js
  11. BIN
      TEAMModelOS/ClientApp/src/assets/icon/default_school.png
  12. BIN
      TEAMModelOS/ClientApp/src/assets/icon/logo.png
  13. BIN
      TEAMModelOS/ClientApp/src/assets/icon/no_data_evaluation.png
  14. 46 0
      TEAMModelOS/ClientApp/src/assets/iconfont/demo_index.html
  15. 14 6
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.css
  16. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.eot
  17. 1 1
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.js
  18. 14 0
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.json
  19. 6 0
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.svg
  20. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.ttf
  21. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff
  22. BIN
      TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff2
  23. 14 4
      TEAMModelOS/ClientApp/src/common/BaseLayout.vue
  24. 41 6
      TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue
  25. 41 9
      TEAMModelOS/ClientApp/src/common/BaseUserPoptip.vue
  26. 1 4
      TEAMModelOS/ClientApp/src/common/Loading.vue
  27. 2 3
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue
  28. 1 1
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.less
  29. 11 4
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.vue
  30. 2 3
      TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.vue
  31. 1 0
      TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.less
  32. 97 13
      TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.vue
  33. 3 9
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.vue
  34. 0 688
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperList.less
  35. 719 192
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperList.vue
  36. 688 0
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperLists.less
  37. 394 0
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperLists.vue
  38. 1 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.less
  39. 1 2
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  40. 1 1
      TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseGeniusLine.vue
  41. 8 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTest.vue
  42. 7 12
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestPop.vue
  43. 23 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  44. 162 158
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue
  45. 132 146
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue
  46. 3 3
      TEAMModelOS/ClientApp/src/components/student-web/SmallNavBar.vue
  47. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/index.js
  48. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/en-US/login.js
  49. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/settings.js
  50. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/index.js
  51. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/login.js
  52. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/settings.js
  53. 2 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/index.js
  54. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/settings.js
  55. 4 1
      TEAMModelOS/ClientApp/src/static/Global.js
  56. 8 5
      TEAMModelOS/ClientApp/src/store/index.js
  57. 19 5
      TEAMModelOS/ClientApp/src/store/module/studentWeb.js
  58. 1 0
      TEAMModelOS/ClientApp/src/store/module/totalAnalysis.js
  59. 2 6
      TEAMModelOS/ClientApp/src/utils/evTools.js
  60. 13 1
      TEAMModelOS/ClientApp/src/utils/public.js
  61. 33 12
      TEAMModelOS/ClientApp/src/view/Home.vue
  62. 1 1
      TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue
  63. 12 16
      TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue
  64. 14 4
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue
  65. 10 3
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.less
  66. 15 3
      TEAMModelOS/ClientApp/src/view/evaluation/bank/index.vue
  67. 11 4
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue
  68. 161 80
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue
  69. 8 2
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseFilter.vue
  70. 96 174
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue
  71. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.vue
  72. 93 88
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  73. 1 0
      TEAMModelOS/ClientApp/src/view/evaluation/index/PickExercise.css
  74. 26 4
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.less
  75. 32 26
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue
  76. 1 1
      TEAMModelOS/ClientApp/src/view/feedback/Feedback.vue
  77. 1 1
      TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue
  78. 12 3
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.less
  79. 323 144
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue
  80. 63 31
      TEAMModelOS/ClientApp/src/view/learnactivity/ManageEvaluation.vue
  81. 15 3
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreate.vue
  82. 5 1
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.less
  83. 4 2
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue
  84. 39 33
      TEAMModelOS/ClientApp/src/view/learnactivity/MultiCascader.vue
  85. 30 10
      TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue
  86. 32 9
      TEAMModelOS/ClientApp/src/view/newcourse/NewCoursePlan.vue
  87. 9 1
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.less
  88. 15 9
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  89. 9 5
      TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue
  90. 6 6
      TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/SystemSetting.less
  91. 66 40
      TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/SystemSetting.vue
  92. 14 12
      TEAMModelOS/ClientApp/src/view/selfstudy/ActivityInfo.vue
  93. 1 1
      TEAMModelOS/ClientApp/src/view/selfstudy/CreateLearnUnit.vue
  94. 1 1
      TEAMModelOS/ClientApp/src/view/selfstudy/CreateOrderLearn.vue
  95. 12 11
      TEAMModelOS/ClientApp/src/view/selfstudy/SelfLearn.vue
  96. 16 8
      TEAMModelOS/ClientApp/src/view/settings/Index.vue
  97. 76 20
      TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue
  98. 1 1
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less
  99. 42 68
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue
  100. 0 0
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.css

+ 150 - 5
TEAMModelFunction/MonitorCosmosDB.cs

@@ -1,27 +1,35 @@
 using System;
 using System.Collections.Generic;
 using System.Net.Http;
+using System.Text.Json;
 using System.Threading.Tasks;
+using Azure.Cosmos;
 using Microsoft.Azure.Documents;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Azure.WebJobs.Host;
 using Microsoft.Extensions.Logging;
+using TEAMModelOS.Models.CommonInfo;
+using TEAMModelOS.Models.SchoolInfo;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
 
 namespace TEAMModelFunction
 {
     public class MonitorCosmosDB
     {
-        private readonly IHttpClientFactory _clientFactory;        
+        private readonly IHttpClientFactory _clientFactory;
+        private readonly AzureCosmosFactory _azureCosmos;
 
-        public MonitorCosmosDB( IHttpClientFactory clientFactory)
+        public MonitorCosmosDB( IHttpClientFactory clientFactory,AzureCosmosFactory azureCosmos)
         {
-            _clientFactory = clientFactory;            
-        }
+            _clientFactory = clientFactory;
+            _azureCosmos = azureCosmos;
+    }
 
         [FunctionName("School")]
         public async Task School([CosmosDBTrigger(
             databaseName: "TEAMModelOS",
-            collectionName: "School",
+            collectionName: "Common",
             ConnectionStringSetting = "CosmosConnection",
             LeaseCollectionName = "leases")]IReadOnlyList<Document> input, ILogger log)
         {          
@@ -30,6 +38,143 @@ namespace TEAMModelFunction
                     log.LogInformation("Documents modified " + input.Count);
                     log.LogInformation("First document Id " + input[0].Id);
                 }
+            //input[0]
+            var client = _azureCosmos.GetCosmosClient();
+            List<ExamInfo> exams = new List<ExamInfo>();
+            string pk = input[0].GetPropertyValue<string>("pk");
+            if (!string.IsNullOrEmpty(pk) &&  pk.Equals("Exam")) {
+                string code = input[0].GetPropertyValue<string>("code");
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.id = '{input[0].Id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{code}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+
+                            exams.Add(obj.ToObject<ExamInfo>());
+                        }
+                    }
+                }
+                for (int i = 0; i < exams.Count; i++)
+                {
+                    /*if (exams[i].startTime.CompareTo(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()) < 0 
+                        && exams[i].endTime.CompareTo(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()) > 0 )
+                    {*/
+                    if (exams[i].progress.Equals("going")) { 
+
+                        //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(exams[i], exams[i].id.ToString(), new Azure.Cosmos.PartitionKey($"{exams[i].code}"));
+                        for (int j = 0;j< exams[i].subjects.Count;j++) {
+                            for (int k = 0; k < exams[i].targetClassIds.Count; k++) {                         
+                                ExamClassResult result = new ExamClassResult();
+                                result.code = "ExamClassResult-" + exams[i].school;
+                                result.examId = exams[i].id;
+                                result.id = Guid.NewGuid().ToString();
+                                result.subjectId = exams[i].subjects[j].id;
+                                result.year = exams[i].year;
+                                result.ttl = -1;
+                                result.pk = typeof(ExamClassResult).Name;
+                                result.info.id = exams[i].targetClassIds[k];
+                                var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(exams[i].targetClassIds[k], new Azure.Cosmos.PartitionKey($"Class-{exams[i].school}"));
+                                if (sresponse.Status == 200)
+                                {
+                                    using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
+                                    Classroom classroom = json.ToObject<Classroom>();
+                                    result.info.name = classroom.name;
+                                    List<List<string>> ans = new List<List<string>>();
+                                    List<double> ansPoint = new List<double>();
+                                    foreach (double p in exams[i].papers[j].point) {
+                                        ans.Add(new List<string>());
+                                        ansPoint.Add(0);
+                                    }
+                                    foreach (StudentSimple stu in classroom.students) {
+                                        result.studentIds.Add(stu.id);
+                                        result.studentAnswers.Add(ans);
+                                        result.studentScores.Add(ansPoint);
+                                    }
+                                }                               
+                                result.progress = exams[i].progress;
+                                result.school = exams[i].school;
+                                await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(result, new Azure.Cosmos.PartitionKey($"{result.code}"));
+
+                            }
+                        }
+                    }
+                    if (exams[i].progress.Equals("finish"))
+                    {                       
+                        List<ExamClassResult> examClassResults = new List<ExamClassResult>();
+                        await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{exams[i].id}'"))
+                        {
+                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                            {
+                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                {
+                                    examClassResults.Add(obj.ToObject<ExamClassResult>());
+                                }
+                            }
+                        }
+                        for (int j = 0; j < exams[i].subjects.Count; j++)
+                        {
+                            ExamResult result = new ExamResult();
+                            result.ttl = -1;
+                            result.pk = typeof(ExamResult).Name;
+                            result.code = "ExamResult-" + exams[i].school;
+                            result.school = exams[i].school;
+                            result.id = Guid.NewGuid().ToString();
+                            result.examId = exams[i].id;
+                            result.subjectId = exams[i].subjects[j].id;
+                            result.year = exams[i].year;
+                            result.paper = exams[i].papers[j];
+                            result.point = exams[i].papers[j].point;
+                            result.scope = exams[i].scope;
+                            result.name = exams[i].name;
+                            //result.time
+
+                            //人数总和
+                            int Count = 0;
+                            int m = 0;
+                            List<ClassRange> classRanges = new List<ClassRange>();
+                            foreach (ExamClassResult classResult in examClassResults)
+                            {
+                                //处理班级信息
+                                ClassRange range = new ClassRange();
+                                range.id = classResult.info.id;
+                                range.name = classResult.info.name;
+                                List<int> ran = new List<int>();
+                                int stuCount = classResult.studentIds.Count;
+                                Count += stuCount;
+                                if (m == 0)
+                                {
+                                    ran.Add(0);
+                                    ran.Add(stuCount - 1);
+                                }
+                                else
+                                {
+                                    ran.Add(Count - stuCount);
+                                    ran.Add(Count - 1);
+                                }
+                                m++;
+                                range.range = ran;
+                                classRanges.Add(range);
+                                //处理学生ID
+                                foreach (string id in classResult.studentIds)
+                                {
+                                    result.studentIds.Add(id);
+                                }
+                                foreach (List<double> scores in classResult.studentScores)
+                                {
+                                    result.studentScores.Add(scores);
+                                }
+                            }
+                            result.classes = classRanges;
+                            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").CreateItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{result.school}"));
+                        }
+                    }
+
+                }
+            }
+            
             //_clientFactory.CreateClient().
         }
     }

+ 22 - 9
TEAMModelFunction/ServiceBusTopic.cs

@@ -6,6 +6,7 @@ using Azure.Cosmos;
 using Microsoft.Azure.WebJobs;
 using Microsoft.Azure.WebJobs.Host;
 using Microsoft.Extensions.Logging;
+using TEAMModelOS.Models.SchoolInfo;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 
@@ -19,22 +20,34 @@ namespace TEAMModelFunction
             _azureCosmos = azureCosmos;
         }
         [FunctionName("ServiceBusTopic")]
-        public async Task Run([ServiceBusTrigger("test_topic_ActiveTask", "test_topic_ReciveTask", Connection = "ConnectionBusName")]string mySbMsg, ILogger log)
+        public async Task Run([ServiceBusTrigger("test_topic_ActiveTask", "test_topic_ReciveTask", Connection = "ConnectionBusName")] string mySbMsg, ILogger log)
         {
             log.LogInformation($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
+            Dictionary<string, object> keyValuePairs = mySbMsg.ToObject<Dictionary<string, object>>();
             var client = _azureCosmos.GetCosmosClient();
-            List<object> classes = new List<object>();
-            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c",requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-hbcn") }))
-            {
-                using var json = await JsonDocument.ParseAsync(item.ContentStream);
-                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+            keyValuePairs.TryGetValue("id", out object id);
+            keyValuePairs.TryGetValue("name", out object name);
+            keyValuePairs.TryGetValue("code", out object code);
+            keyValuePairs.TryGetValue("status", out object progress);
+            if (name.ToString().Equals("ExamInfo")) {
+                ExamInfo exam = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"{code}"));
+                exam.progress = progress.ToString();
+                await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(exam, id.ToString(), new PartitionKey($"{code}"));
+                /*List<object> classes = new List<object>();
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-hbcn") }))
                 {
-                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                     {
-                        classes.Add(obj.ToObject<object>());
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+
+                            classes.Add(obj.ToObject<object>());
+                        }
                     }
-                }
+                }*/
             }
+            
         }
     }
 }

+ 8 - 8
TEAMModelFunction/host.json

@@ -1,11 +1,11 @@
 {
-    "version": "2.0",
-    "logging": {
-        "applicationInsights": {
-            "samplingExcludedTypes": "Request",
-            "samplingSettings": {
-                "isEnabled": true
-            }
-        }
+  "version": "2.0",
+  "logging": {
+    "applicationInsights": {
+      "samplingExcludedTypes": "Request",
+      "samplingSettings": {
+        "isEnabled": true
+      }
     }
+  }
 }

+ 9 - 4
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs

@@ -105,18 +105,23 @@ namespace TEAMModelOS.SDK.DI
         }
 
 
-        public static async Task<long> SendLeamMessage<T>(this ServiceBusClient client, string TopicName, string id, string pk, long startTime, int status, string msgId)
+        public static async Task<long> SendLeamMessage<T>(this ServiceBusClient client, string TopicName, string id, string pk, long startTime, string progress, string msgId)
         {
             //微調代碼
             var timer = DateTimeOffset.FromUnixTimeMilliseconds(startTime);
-            if (timer.CompareTo(DateTimeOffset.UtcNow) <= 0) return -1;
+            if (timer.CompareTo(DateTimeOffset.UtcNow) < 0)
+            {
+                progress = "going";
+            } else if (timer.CompareTo(DateTimeOffset.UtcNow) > 0) {
+                progress = "finish";
+            }
             
             //设定开始时间
             Dictionary<string, object> dict = new Dictionary<string, object>() {
                     { "name",typeof(T).Name},
                     { "id",id},
-                    { "pk",pk},
-                    { "status",status}
+                    { "code",pk},
+                    { "status",progress}
                 };
             //var msgId = "1";
             string messageBody = $"Message {dict}";

+ 75 - 26
TEAMModelOS/ClientApp/public/index.html

@@ -1,31 +1,80 @@
 <!DOCTYPE html>
 <html lang="en">
-<head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <link id="theme" type="text/css" rel="stylesheet" href="<%= BASE_URL %>theme/dark-theme.css">
-    <title>vuex-oidc-example</title>
-   <script type="text/javascript" id="MathJax-script" async
-            src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
-    </script>
-    <script>
-        let cloudSetting = localStorage.getItem('cloudSetting')
-        if (cloudSetting) {
-            cloudSetting = JSON.parse(cloudSetting)
-            if (cloudSetting.curTheme && cloudSetting.curTheme == 'light') {
-                document.getElementById('theme').href = '/theme/light-theme.css'
-            }
-        }
-    </script>
+	<head>
+		<meta charset="utf-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width,initial-scale=1.0">
+		<link rel="icon" href="<%= BASE_URL %>favicon.ico">
+		<link id="theme" type="text/css" rel="stylesheet" href="<%= BASE_URL %>theme/dark-theme.css">
+		<title>vuex-oidc-example</title>
+		<script type="text/javascript" id="MathJax-script" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML">
+		</script>
+		<script>
+			let cloudSetting = localStorage.getItem('cloudSetting')
+			if (cloudSetting) {
+				cloudSetting = JSON.parse(cloudSetting)
+				if (cloudSetting.curTheme && cloudSetting.curTheme == 'light') {
+					document.getElementById('theme').href = '/theme/light-theme.css'
+				}
+			}
+			/* 性能监听 */
+			window.addEventListener("load", function() {
+				setTimeout(function() {
+					var e = window.performance;
+					if (e) {
+						var t = e.getEntriesByType("navigation")[0],
+							r = 0;
+						t || (r = (t = e.timing).navigationStart);
+						var n = [{
+							key: "Redirect",
+							desc: "\u7f51\u9875\u91cd\u5b9a\u5411\u7684\u8017\u65f6",
+							value: t.redirectEnd - t.redirectStart
+						}, {
+							key: "AppCache",
+							desc: "\u68c0\u67e5\u672c\u5730\u7f13\u5b58\u7684\u8017\u65f6",
+							value: t.domainLookupStart - t.fetchStart
+						}, {
+							key: "DNS",
+							desc: "DNS\u67e5\u8be2\u7684\u8017\u65f6",
+							value: t.domainLookupEnd - t.domainLookupStart
+						}, {
+							key: "TCP",
+							desc: "TCP\u8fde\u63a5\u7684\u8017\u65f6",
+							value: t.connectEnd - t.connectStart
+						}, {
+							key: "Waiting(TTFB)",
+							desc: "\u4ece\u5ba2\u6237\u7aef\u53d1\u8d77\u8bf7\u6c42\u5230\u63a5\u6536\u5230\u54cd\u5e94\u7684\u65f6\u95f4 / Time To First Byte",
+							value: t.responseStart - t.requestStart
+						}, {
+							key: "Content Download",
+							desc: "\u4e0b\u8f7d\u670d\u52a1\u7aef\u8fd4\u56de\u6570\u636e\u7684\u65f6\u95f4",
+							value: t.responseEnd - t.responseStart
+						}, {
+							key: "HTTP Total Time",
+							desc: "http\u8bf7\u6c42\u603b\u8017\u65f6",
+							value: t.responseEnd - t.requestStart
+						}, {
+							key: "DOMContentLoaded",
+							desc: "dom\u52a0\u8f7d\u5b8c\u6210\u7684\u65f6\u95f4",
+							value: t.domContentLoadedEventEnd - r
+						}, {
+							key: "Loaded",
+							desc: "\u9875\u9762load\u7684\u603b\u8017\u65f6",
+							value: t.loadEventEnd - r
+						}];
+						console && console.log && console.log(n)
+					}
+				}, 0)
+			});
+		</script>
 
-</head>
-<body>
-    <noscript>
-        <strong>We're sorry but vuex-oidc-example doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
-    </noscript>
-    <div id="app"></div>
-</body>
+	</head>
+	<body>
+		<noscript>
+			<strong>We're sorry but vuex-oidc-example doesn't work properly without JavaScript enabled. Please enable it to
+				continue.</strong>
+		</noscript>
+		<div id="app"></div>
+	</body>
 
 </html>

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

@@ -60,6 +60,10 @@ export default {
     //新增个人课程
     upsertPrivateCus: function (data) {
         return post('/school/course/upsert-teacher-course', data)
+    },
+    //更新保存标准课程公告
+    upsertNotice: function (data) {
+        return post('/school/course/upsert-notice', data)
     }
 
 }

+ 1 - 1
TEAMModelOS/ClientApp/src/api/http.js

@@ -181,7 +181,7 @@ export function post(url, params) {
     return new Promise((resolve, reject) => {
         axios.post(url, params)
             .then(response => {
-                if (response && response.data) {
+                if (response) {
                     resolve(response.data)
                 }
             }, err => {

+ 11 - 5
TEAMModelOS/ClientApp/src/api/learnActivity.js

@@ -22,19 +22,25 @@ export default {
      *删除评测信息
      */
     DeleteExamInfo: function (data) {
-        return post('/api/Exam/Delete', data)
+        return post('/school/exam/delete', data)
     },
     /*
      *保存评测
      */
     SaveExamInfo: function (data) {
-        return post('/api/Exam/Save', data)
+        return post('/school/exam/save', data)
     },
     /*
      *查询评测
      */
     FindExamInfo: function (data) {
-        return post('/api/Exam/Find', data)
+        return post('/school/exam/find', data)
+    },
+    /*
+     *查询单个评测
+     */
+    FindExamInfos: function (data) {
+        return post('/school/exam/find-summary', data)
     },
     /*
      *自动组题
@@ -86,7 +92,7 @@ export default {
     },
 
     /*
-    *保存或新增作答记录
+    *保存或新增作答记录(学生作答数据)
     */
     upsertRecord: function (data) {
         return post('/api/Learn/upsertRecord', data)
@@ -225,7 +231,7 @@ export default {
     },
 
 	/*
-	* 保存评测学生作答数据
+	* 保存评测学生作答数据(分数)
 	*/
     UpsertAllRecord: function (data) {
         return post('/api/Exam/upsertAllRecord', data)

+ 2 - 1
TEAMModelOS/ClientApp/src/api/login.js

@@ -130,7 +130,8 @@ export default {
 
 			// 進行API呼叫
 			await this.studLoginbyIES(data).then(res => {
-				if(res.error == 0){
+				if (res.error == 0) {
+					console.log(res)
 					// 儲存大雲Token
 					localStorage.setItem("auth_token", res.auth_token)
 					store.dispatch('user/setSchoolCode', data.school_code)

+ 4 - 4
TEAMModelOS/ClientApp/src/api/newData.js

@@ -12,10 +12,10 @@ var Mock = require("mockjs");
 //課程清單
 var courseList = [];
 
-for (var i = 1; i <= 50; i++) {
+for (var i = 1; i <= 20; i++) {
   //課程清單資料
   var students = [];
-  for (let p = 1; p <= 38; p++) {
+  for (let p = 1; p <= 18; p++) {
     let studentsData = Mock.mock({
       name: Random.cname(),
       group: Random.integer(1, 5),
@@ -46,7 +46,7 @@ for (var i = 1; i <= 50; i++) {
 }
 //活動清單
 var eventList = [];
-for (var j = 1; j <= 70; j++) {
+for (var j = 1; j <= 20; j++) {
   //課前預習的資料
   var previewMission = [];
   var unitQAs = [];
@@ -79,7 +79,7 @@ for (var j = 1; j <= 70; j++) {
   }
   //評量的資料,與問卷的假資料共用
   var lessonTestQAs = [];
-  for (let p = 1; p <= 10; p++) {
+  for (let p = 1; p <= 20; p++) {
     var lessonTestQAContent = Mock.mock({
       qNo: p,
       qDes: Random.cparagraph(1, 8) + "?",

BIN
TEAMModelOS/ClientApp/src/assets/icon/default_school.png


BIN
TEAMModelOS/ClientApp/src/assets/icon/logo.png


BIN
TEAMModelOS/ClientApp/src/assets/icon/no_data_evaluation.png


+ 46 - 0
TEAMModelOS/ClientApp/src/assets/iconfont/demo_index.html

@@ -30,6 +30,18 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe69b;</span>
+                <div class="name">库存分析</div>
+                <div class="code-name">&amp;#xe69b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6eb;</span>
+                <div class="name">学校</div>
+                <div class="code-name">&amp;#xe6eb;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe60f;</span>
                 <div class="name">音频</div>
@@ -410,6 +422,24 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont icon-school-analysis"></span>
+            <div class="name">
+              库存分析
+            </div>
+            <div class="code-name">.icon-school-analysis
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-school"></span>
+            <div class="name">
+              学校
+            </div>
+            <div class="code-name">.icon-school
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont icon-audio3"></span>
             <div class="name">
@@ -934,6 +964,22 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-school-analysis"></use>
+                </svg>
+                <div class="name">库存分析</div>
+                <div class="code-name">#icon-school-analysis</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-school"></use>
+                </svg>
+                <div class="name">学校</div>
+                <div class="code-name">#icon-school</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-audio3"></use>

File diff suppressed because it is too large
+ 14 - 6
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.css


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.eot


File diff suppressed because it is too large
+ 1 - 1
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.js


+ 14 - 0
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.json

@@ -5,6 +5,20 @@
   "css_prefix_text": "icon-",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "14745833",
+      "name": "库存分析",
+      "font_class": "school-analysis",
+      "unicode": "e69b",
+      "unicode_decimal": 59035
+    },
+    {
+      "icon_id": "12593001",
+      "name": "学校",
+      "font_class": "school",
+      "unicode": "e6eb",
+      "unicode_decimal": 59115
+    },
     {
       "icon_id": "16942332",
       "name": "音频",

File diff suppressed because it is too large
+ 6 - 0
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.svg


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.ttf


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff


BIN
TEAMModelOS/ClientApp/src/assets/iconfont/iconfont.woff2


+ 14 - 4
TEAMModelOS/ClientApp/src/common/BaseLayout.vue

@@ -81,7 +81,7 @@
                 isCollapsed: false,
                 menuTree: [
                     {
-                        icon: 'iconfont icon-smart-campus',
+                        icon: 'iconfont icon-school',
                         name: '智慧校园',
                         router: '',
                         role: 'admin',
@@ -201,7 +201,7 @@
                                 permission: 'analysis'
                             },
                             {
-                                icon: 'iconfont icon-xueqing',
+                                icon: 'iconfont icon-school-analysis',
                                 name: '校园分析',
                                 router: '/home/scboard',
                                 tag: '(预览)',
@@ -383,8 +383,14 @@
                 return ["menu-item", this.isCollapsed ? "collapsed-menu" : ""]
             }
         },
-        create() {
-            let local = localStorage.getItem
+        created() {
+            let cloudSetting = localStorage.getItem('cloudSetting')
+            if (cloudSetting) {
+                cloudSetting = JSON.parse(cloudSetting)
+                if (cloudSetting.menuStatus == 'close') {
+                    this.isCollapsed = true
+                }
+            }
         },
         watch: {
             $route: {
@@ -404,6 +410,10 @@
                             break
                         }
                     }
+                    if (!flag) {
+                        this.activeName = ''
+                        this.openNames = []
+                    }
                 },
                 // 深度观察监听
                 deep: true,

+ 41 - 6
TEAMModelOS/ClientApp/src/common/BaseSelectSchool.vue

@@ -1,7 +1,8 @@
 <template>
 	<div class="base-school-select">
-			<Dropdown @on-click="onSchoolSelect">
-				<img class="school-logo" :src="curSchool.logo || 'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png'" />
+			<div v-if="!user.schools.length">暂未加入学校</div>
+			<Dropdown @on-click="onSchoolSelect" v-else>
+				<img class="school-logo" :src="curSchool.logo || defaultLogo" />
 				<a href="javascript:void(0)" :class="['base-user-post', user.schools.length === 1 ? 'single-school' : '']">
 					{{ curSchool.name }}
 					<Icon type="ios-arrow-down"></Icon>
@@ -10,7 +11,7 @@
 					<div v-for="(item,index) in user.schools" :key="index">
 						<DropdownItem :name="index">
 							<div class="school-item">
-								<img :src="item.logo || 'http://sokrates.teammodel.cn/images/app/cn/teammodel/original-black-small.png'" alt="">
+								<img :src="item.logo || defaultLogo" alt="">
 								<span>{{ item.name }}</span>
 							</div>
 						</DropdownItem>
@@ -29,12 +30,14 @@
 				curSchool: {
 					logo:''
 				},
+				defaultLogo:'',
 				user:{
 					schools:[]
 				}
 			}
 		},
 		created() {
+			this.defaultLogo = require('@/assets/icon/default_school.png')
 			// 获取本地存储中的 用户信息
 			let user = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
 			console.log(user)
@@ -51,13 +54,45 @@
 			}
 		},
 		methods: {
-			onSchoolSelect(val){
+			async onSchoolSelect(val){
+				this.$EventBus.$emit('onGlobalLoading',true)
 				this.curSchool = this.user.schools[val]
-				this.$store.commit('setSchoolCode',this.user.schools[val].schoolId)
+				let schoolCode = this.user.schools[val].schoolId
+				let schoolInfo = await this.getTeacherSchoolInfo(schoolCode)
+				this.$store.commit('setSchoolCode',schoolCode)
+				this.$store.commit('schoolBaseInfo/setSchoolInfo',{ period:[] })
+				this.$store.commit('schoolBaseInfo/setClassroomList', undefined)
+				this.$store.dispatch('user/setSchoolCode', schoolCode)
+				this.$store.dispatch('user/setSchoolProfile', schoolInfo)
+				console.log('切换学校为' + schoolCode)
+				console.log(this.$store.state)
+				console.log(JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")))
+				setTimeout(() => {
+					this.$EventBus.$emit('onGlobalLoading',false)
+				},500)
 				this.$router.push({
 					name:'home'
 				})
-			}
+			},
+			
+			/* 获取老师所在学校的信息 */
+			getTeacherSchoolInfo(code) {
+				return new Promise((r,j) => {
+					this.$api.schoolSetting.getTeacherSchoolInfo({
+						id_token: localStorage.getItem('id_token'),
+						school_code: code
+					}).then(
+						(res) => {
+							if (!res.error) {
+								r(res)
+							}
+						},
+						(err) => {
+							this.$Message.error("数据获取失败!")
+						}
+					)
+				})
+			},
 		},
 
 		computed: {

+ 41 - 9
TEAMModelOS/ClientApp/src/common/BaseUserPoptip.vue

@@ -15,7 +15,7 @@
 					</DropdownMenu>
 				</Dropdown>
 			</div>
-			<Poptip class="dark-iview-poptip">
+			<Poptip class="dark-iview-poptip" @on-popper-show="getSize()">
 				<!-- <img :src="user.picture" /> -->
 				<PersonalPhoto style="cursor: pointer;" :name="userInfo.username" :picture="user.picture" :color="userInfo.nameColor"/>
 
@@ -44,7 +44,11 @@
 						</div>
 					</div>
 					<div class="user-storage">
-						<p>个人空间状态:( {{ getSizeVal(sizeInfo.total) }} / {{ getSizeVal($GLOBAL.PRIVATE_SPACE) }} )</p>
+						<p :style="{color: sizeInfo.total > $GLOBAL.PRIVATE_SPACE ? '#ff2929' : '#a5a5a5'}">
+							<span v-if="sizeInfo.total > $GLOBAL.PRIVATE_SPACE">(已满)</span>
+							个人空间状态:
+							{{ getSizeVal(sizeInfo.total) }} / {{ getSizeVal($GLOBAL.PRIVATE_SPACE) }}
+						</p>
                         <div class="user-storage-distribution">
                             <span class="percent-item-span storage-full" :style="{ width: '100%' }" v-if="sizeInfo.total > $GLOBAL.PRIVATE_SPACE"></span>
                             <span class="storage-res" :style='{ width: getPercent(sizeInfo.res) }'></span>
@@ -56,13 +60,13 @@
                             <span class="storage-data" :style='{ width: getPercent(sizeInfo.data) }'></span>
                         </div>
 						<p class="user-storage-text">
-							<span v-if="sizeInfo.res != 0" style="color:#00D523">教材:{{ getSizeVal(sizeInfo.res) }}</span>
-							<span v-if="sizeInfo.image != 0" style="color:#e87b22">图片:{{ getSizeVal(sizeInfo.image) }}</span>
-							<span v-if="sizeInfo.video != 0" style="color:#ff40bc">视频:{{ getSizeVal(sizeInfo.video) }}</span>
-							<span v-if="sizeInfo.audio != 0" style="color:#1fccd5">音频:{{ getSizeVal(sizeInfo.audio) }}</span>
-							<span v-if="sizeInfo.doc != 0" style="color:#1fccd5">文档:{{ getSizeVal(sizeInfo.doc) }}</span>
-							<span v-if="sizeInfo.data != 0" style="color:#1fccd5">题库:{{ getSizeVal(sizeInfo.data) }}</span>
-							<span v-if="sizeInfo.other != 0" style="color:#1fccd5">其他内容:{{ getSizeVal(sizeInfo.other) }}</span>
+							<span v-if="sizeInfo.res != 0" class="text-res">教材:{{ getSizeVal(sizeInfo.res) }}</span>
+							<span v-if="sizeInfo.image != 0" class="text-image">图片:{{ getSizeVal(sizeInfo.image) }}</span>
+							<span v-if="sizeInfo.video != 0" class="text-video">视频:{{ getSizeVal(sizeInfo.video) }}</span>
+							<span v-if="sizeInfo.audio != 0" class="text-audio">音频:{{ getSizeVal(sizeInfo.audio) }}</span>
+							<span v-if="sizeInfo.doc != 0" class="text-doc">文档:{{ getSizeVal(sizeInfo.doc) }}</span>
+							<span v-if="sizeInfo.data != 0" class="text-data">题库:{{ getSizeVal(sizeInfo.data) }}</span>
+							<span v-if="sizeInfo.other != 0" class="text-other">其他内容:{{ getSizeVal(sizeInfo.other) }}</span>
 						</p>
 					</div>
 					<div class="btn-logout" @click="onQuit">登出</div>
@@ -226,6 +230,34 @@
     .storage-other {
         background-color: #E87B22;
     }
+
+    .text-data {
+        color: #F8C006;
+    }
+
+    .text-image {
+        color: #45C84A;
+    }
+
+    .text-video {
+        color: #8E2BDD;
+    }
+
+    .text-audio {
+        color: #E1027B;
+    }
+
+    .text-doc {
+        color: #03C0C2;
+    }
+
+    .text-res {
+        color: #1FFCC5;
+    }
+
+    .text-other {
+        color: #E87B22;
+    }
 </style>
 <style lang="less">
 	.base-user-center {

+ 1 - 4
TEAMModelOS/ClientApp/src/common/Loading.vue

@@ -54,9 +54,6 @@
                     require('@/icons/svg/loading4.svg')
                     this.imgSrc = 'loading4'
                     break
-                case '5':
-                    this.imgSrc = require('@/assets/loading/logo_loading.png')
-                    break
                 default:
                     break
             }
@@ -77,7 +74,7 @@
         flex-direction: row;
         justify-content: center;
         /*background: rgba(103, 103, 103, 0.27);*/
-        z-index: 999;
+        z-index: 1000;
     }
 
     #loadingBox {

+ 2 - 3
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue

@@ -125,10 +125,9 @@
                 relateFileList:[],
                 uploadUrl:'',
                 defaultConfig: {
-                  uploadImgServer: '/api/file/uploadWangEditor', // 图片上传地址
                   showLinkImg: false, // 是否展示网络图片链接上传
-                    uploadFileName: 'files', // 上传图片后台获取的文件名
-                  menus:this.$tools.wangEditorMenu
+                  uploadFileName: 'files', // 上传图片后台获取的文件名
+                  menus:this.$tools.wangEditorMenuSimple
 
                 },
                 hwForm: {

+ 1 - 1
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.less

@@ -189,7 +189,7 @@
         z-index: 1 !important;
 
         .w-e-menu {
-            z-index: 1 !important;
+            z-index: 2 !important;
         }
     }
 

+ 11 - 4
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.vue

@@ -111,7 +111,7 @@
                 uploadUrl:'',
                 defaultConfig: {
                   uploadImgShowBase64: true,
-                  menus: this.$tools.wangEditorMenu,
+                  menus: this.$tools.wangEditorMenuSimple,
                 },
                 voteOptions: [...new Array(2).keys()], // 默认四个选项,
                 voteOptionsContent:[],
@@ -179,6 +179,7 @@
              * @param name FormName
              */
             async handleSubmit(name) {
+				this.isBtnLoading = true
                 this.$refs[name].validate(async (valid) => {
                     if (valid && this.getSimpleText(this.hwForm.description) && this.voteOptionsContent.length) {
                         let params = Object.assign({}, this.defaultParams)
@@ -197,7 +198,7 @@
                         if (this.isEdit && this.editInfo.id && this.editInfo.code) {
                             params.id = this.editInfo.id
 							params.code = this.hwForm.code
-                        }
+                        }                                   
                         params.targetClassIds = this.hwForm.targetClassIds
 						console.log(params)
 						/* 保存BLOB以及COSMOS */
@@ -211,7 +212,12 @@
 						})
                         
                     } else {
-                        this.$Message.error('请将信息填写完整')
+						this.isBtnLoading = false
+						if(this.voteOptionsContent.length){
+							this.$Message.error('请将信息填写完整')
+						}else{
+							this.$Message.error('投票选项个数不能为空!')
+						}
                     }
                 })
             },
@@ -422,7 +428,8 @@
 			/* 根据班级ID获取班级名称 */
             getTargetName(classId){
 				if(this.classRooms.length){
-					return this.classRooms.filter(i => i.id === classId)[0].name
+					let targetIndex = this.classRooms.map(i => i.id).indexOf(classId)
+					return targetIndex > -1 ?  this.classRooms[targetIndex].name : '未匹配数据'
 				}else{
 					this.getClassrooms(this.userInfo.TEAMModelId).then(res => {
 						return res.filter(i => i.id === classId)[0].name

+ 2 - 3
TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.vue

@@ -4,9 +4,7 @@
             <div class="activity-target-header">
                 <span>测试科目:</span>
                 <span v-if="paper.length > 0" v-for="(item,index) in paper" :key="index" :class="index == currentActivityIndex ? 'subject-item subject-item-active':'subject-item'" @click="selectActivity(index)">
-                    {{jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodCode).periodName}}
-                    <span style="margin:0px 2px;">·</span>
-                    {{jsFn.getSubjectName(jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodCode), item.subjectCode)}}
+                    {{ item.subjectName}}
                 </span>
             </div>
             <div class="class-info">
@@ -137,6 +135,7 @@
             },
         },
         mounted() {
+            console.log(this.paper)
             this.getData()
         }
     }

+ 1 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.less

@@ -24,6 +24,7 @@
 .search-box {
     height: 5%;
     margin-top:5px;
+    /*margin-left:5px;*/
     border-bottom: 1px solid @borderColor;
 }
 .student-box {

+ 97 - 13
TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.vue

@@ -2,6 +2,7 @@
     <div class="body">
         <div class="top-bar">
             <div class="type-list">
+                <span class="base-info-item">当前班级:<span class="analysis-info">{{classList[0].name === ''? '请选择评量班级' : classList[0].name}}</span></span>
                 <span class="base-info-item">学生姓名:<span class="analysis-info">{{studentName === ''? '请选择作答学生' : studentName}}</span></span>
                 <span class="base-info-item">已评人数:<span class="analysis-info">{{ isReview }}</span></span>
                 <span class="base-info-item">未评试题:<span class="analysis-info">{{answer.length - reviewIndex}}</span></span>
@@ -13,18 +14,22 @@
             </div>
         </div>
         <div class="content" >
-            <Loading :top="200" v-show="dataLoading" type="1" style="text-align:center"></Loading>
-            <div class="left-box" v-if="!dataLoading">
+            <!--<Loading :top="200"  type="1" style="text-align:center"></Loading>-->
+            <div class="left-box">
                 <div class="student-box">
-                    <div class="search-box dark-iview-input">
-                        <Input placeholder="查询学生姓名..." v-model="inputData" style="width:90%;margin-left:5px;margin-bottom:5px">
+                    <div class="search-box dark-iview-select ">
+                        <Select placeholder="请选择查看班级..." v-model="classData" style="width: 90%; margin-left: 5px; margin-bottom: 5px" @on-change="getClassInfo">
+                            <Icon type="ios-contact" slot="prefix" />
+                            <Option v-for="(item,index) in classList" :value="item.id" :key="index">{{ item.name }}</Option>
+                        </Select>
+                        <!--<Input placeholder="查询学生姓名..." v-model="inputData" style="width:90%;margin-left:5px;margin-bottom:5px">
                         <Icon type="ios-contact" slot="prefix" />
-                        </Input>
+                        </Input>-->
                     </div>
                     <div class="student-list">
                         <vuescroll>
                             <ul>
-                                <li :class="index == selectIndex ?' block-bg-active block-bg':' block-bg'" :key="index" v-for="(item,index) in studentList" @click="getStudentInfo(item,index)">
+                                <li :class="index == selectIndex ?' block-bg-active block-bg':' block-bg'" :key="index" v-for="(item,index) in studentData" @click="getStudentInfo(item,index)">
                                     <div class="student-show">
                                         <span>{{item.name}}</span>
                                         <span :style="{ background: (item.mark === 0 ? '#949594' : item.mark === 1 ? '#0BADD4' : '#1CC0F3')}" class="activity-status">{{item.mark === 0 ? '未开始' : item.mark === 2 ? '已完成' : '未完成'}}</span>
@@ -35,9 +40,9 @@
                     </div>
                 </div>
             </div>
-            <div class="grade-box" v-if="!dataLoading">
+            <div class="grade-box" >
                 <vuescroll>
-                    <ReviewPaper :paper="paperData" :answer="answerInfo" ref="exPaper" style="color:#515a6e;" :isShowTools="isShowTools"> </ReviewPaper>
+                    <ReviewPaper :paper="paperInfo.papers" :answer="answerInfo" ref="exPaper" style="color:#515a6e;" :isShowTools="isShowTools"> </ReviewPaper>
                 </vuescroll>
             </div>
         </div>
@@ -72,7 +77,9 @@
                 answer: [],
                 studentName: '',
                 scoreTotal: 0,
-                studentCode:''
+                studentCode: '',
+                classData: '',
+                classList:[]
             }
         },
         computed:{
@@ -218,8 +225,8 @@
                 return listArr;
             },
             //获取学生测验数据
-
             getStudentData() {
+
                 this.dataLoading = true
                 let requestData = {}
                 requestData.examCode = this.paperInfo.code
@@ -257,6 +264,7 @@
                         }
                     )
                 }
+
             },
             //获取试卷主观题信息
             getPaperInfo() {
@@ -281,10 +289,86 @@
                         )
                     }
                 }
-            }
-        },
+            },
+            getClassInfo() {
+                if (this.classData !== '') {
+                    this.getStudentDataInfo(this.classData)
+                }
+            },
+            getClassData() {
+                console.log()
+                if (this.paperInfo.class.length !== 0) {
+                    this.classList = []
+                    for (let item of this.paperInfo.class) {
+                        for (let items of this.$store.state.schoolBaseInfo.classroomList) {
+                            if (item == items.id) {
+                                this.classList.push(items)
+                            }
+                        }
+                    }
+                    this.getStudentDataInfo(this.classList[0].id)
+                } else {
+                    this.$Message.warning('班级信息有误!')
+                }
+            console.log(this.paperInfo)
+            },
+            getStudentDataInfo(data) {
+                if (data !== undefined) {
+                    let requestData = {
+                        id: data,
+                        school_code: this.$store.state.userInfo.schoolCode
+                    }
+                    if (requestData.id !== "") {
+                        this.$api.schoolSetting.getClassroomStudent(requestData).then(
+                            res => {
+                                if (res.error == null) {
+                                    console.log(res)
+                                    this.studentData = res.classrooms[0].students
+                                    //this.paperData = res.result.data[0]
+                                    //let data = res.result.data[0].item
+                                    //this.paperData.item = []
+                                    //for (let i = 0; i < data.length; i++) {
+                                    //    this.paperData.item.push(data[i])
+                                    //}
+                                } else {
+                                    this.$Message.error('API ERROR!')
+                                }
+                            }
+                        )
+                    }
+                }
+            },
+            //获取学校基本信息
+            getSchoolBaseInfo() {
+                this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(
+                    (res) => {
+                        console.log(this.$store.state)
+                        if (res.code == 2) {
+                            alert('数据为空!')
+                        }
+                    },
+                    (err) => {
+                        this.$Message.error('API error!')
+                    }
+                )
+                this.$store.dispatch('schoolBaseInfo/getClassroom').then(
+                    (res) => {
+                        if (res.code == 2) {
+                            alert('数据为空!')
+                        } else {
+                            this.getClassData()
+
+                        }
+                    },
+                    (err) => {
+                        this.$Message.error('API error!')
+                    }
+                )
+            },
+    },
         mounted() {
-            this.getStudentData()
+            this.getSchoolBaseInfo()
+            //this.getStudentData()
             console.log('修改测试内容')
             console.log(this.paperInfo)
         },

+ 3 - 9
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.vue

@@ -4,7 +4,7 @@
             <!-- 试卷内容 -->
             <div class="paper-content">
                 <div class="paper-body">
-                    <ReviewPaperList :paper="paperInfo"  :answer="answer" ref="exList" :isShowTools="isShowTools" ></ReviewPaperList>
+                    <ReviewPaperList :paper="paperInfo"  :answer="answer" ref="exList"></ReviewPaperList>
                 </div>
             </div>
         </div>
@@ -21,14 +21,6 @@
                 type: Object,
                 default: null
             },
-            isShowTools: {
-                type: Boolean,
-                default: true
-            },
-            isShowBaseInfo: {
-                type: Boolean,
-                default: true
-            },
             answer: {
                 type: Array,
                 default:()=>[]
@@ -47,6 +39,8 @@
             }
         },
         mounted() {
+            console.log(this.paper)
+            console.log(this.answer)
             this.onHandleToggle()
             this.onToggleChange()
 

+ 0 - 688
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperList.less

@@ -1,688 +0,0 @@
-.answer-box{
-    display:inline-flex;
-    margin-left:-5px;
-}
-.answer-score {
-    width: 130px;
-    color: rgb(16, 171, 231);
-}
-.answer-scores {
-    width: 130px;
-    color: rgb(16, 171, 231);
-    padding-top:10px;
-}
-
-.components-el-container .type-name {
-    font-size: 18px;
-    font-weight: bold;
-    margin-top: 20px;
-}
-
-
-.components-el-container .exercise-item .item-tools-t:hover {
-    background: #4a5ae6;
-}
-
-.components-el-container .exercise-item .item-score {
-    margin-right: 10px;
-    color: #fff;
-    background: #01b4ef;
-    padding: 4px 10px;
-    border-radius: 5px;
-}
-
-.type-score-btn {
-    width: 80%;
-    margin-left: 10%;
-    height: 40px;
-    line-height: 40px;
-}
-
-
-.ev-list-container {
-    user-select: none !important;
-    position: relative;
-    font-family: '微軟正黑體', 'Heiti TC' !important;
-}
-
-.ev-list-container .ev-header {
-    background: #fff;
-    padding: 10px;
-    display: flex;
-    align-items: center;
-}
-
-.ev-list-container .ev-title {
-    font-size: 20px;
-    font-weight: bold;
-    margin-left: 5px;
-    vertical-align: middle;
-}
-
-.ev-list-container .ev-length {
-    font-size: 12px;
-    font-weight: bold;
-    margin-left: 30px;
-    display: inline-block;
-    margin-top: 5px;
-    vertical-align: text-top;
-}
-
-.ev-list-container .ivu-divider-horizontal {
-    margin: 15px 0;
-}
- .no-data-text {
-   text-align:center;
-   margin-top:20%;
-}
-
-.ev-list-operation {
-    position: absolute;
-    top: -65px;
-    right: 0;
-    height: 60px;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    justify-content: space-between;
-}
-
-.ev-list-operation .ivu-checkbox-wrapper {
-    font-size: 14px;
-}
-
-.ev-list-operation .ivu-checkbox {
-    margin: 10px;
-}
-
-.ev-list-operation .import-exercise {
-    font-weight: bold;
-    color: rgb(16, 171, 231);
-    font-size: 16px;
-    display: flex;
-}
-
-.ev-list-operation .import-exercise .ivu-btn {
-    margin-right: 10px;
-    border: none !important;
-}
-
-.ev-list-operation .ivu-icon {
-    font-size: 16px;
-    margin-right: 6px;
-    cursor: pointer;
-    vertical-align: initial;
-}
-
-.ev-list-operation .ivu-badge-count {
-    right: 12px;
-}
-
-.ev-list-operation .ivu-checkbox-checked .ivu-checkbox-inner {
-    background: #01b4ef;
-    border-color: #01b4ef;
-}
-
-
-.exercise-backet-wrap .ivu-btn {
-    border: none !important;
-}
-
-.exercise-backet-wrap .exercise-backet-item:not(:first-child) {
-    margin-left: 10px;
-}
-
-.exercise-backet-wrap .exercise-backet-num {
-    font-weight: bold;
-    margin: 0 5px;
-    font-size: 16px;
-    color: rgb(16, 171, 231);
-}
-
-
-
-.ev-content {
-    background: none;
-}
-
-.content-wrap {
-    position: relative;
-    width: 100%;
-    height: auto;
-    display: flex;
-    flex-direction: column;
-}
-
-.content-wrap .exercise-item {
-    width: 100%;
-    height: auto;
-    padding: 10px 20px 10px 20px;
-    margin-top: 10px;
-    font-size: 16px;
-    font-weight: 600;
-    background: #fff;
-    cursor: pointer;
-    /*box-shadow: 6px 5px 5px 2px rgb(214, 214, 214);*/
-}
-
-.content-wrap .exercise-item table, .content-wrap .exercise-item td {
-/*    border: 1px solid rgb(128, 128, 128);*/
-    border-collapse: collapse;
-    text-align: center;
-    padding: 5px 10px;
-}
-
-
-.content-wrap .exercise-item:hover .item-tools-bind {
-    display: unset;
-}
-
-.complete-line {
-    margin: 0 5px;
-    padding: 0 45px;
-/*    border-bottom: 2px solid rgb(128, 128, 128);*/
-}
-
-.exercise-item .item-question {
-    /*display: inline-block;*/
-    /*margin-top:20px;*/
-    position: relative;
-    cursor: pointer;
-}
-
-.exercise-item img {
-    vertical-align: middle;
-}
-
-.exercise-item .item-question .item-btn-toggle {
-    position: absolute;
-    right: 0;
-    top: 0;
-}
-
-.exercise-item .item-question .item-btn-toggle .ivu-icon {
-    font-size: 22px;
-    cursor: pointer;
-}
-
-.exercise-item .item-difficulty {
-    display: inline-block;
-    padding: 2px 10px;
-    background: rgb(16, 171, 231);
-    border-radius: 5px;
-    color: #fff;
-    font-size: 12px;
-}
-
-.exercise-item .item-type {
-    display: inline-block;
-    padding: 1px 9px;
-    border-radius: 5px;
-    color: #fff;
-    font-size: 12px;
-    margin-left: 5px;
-    background: rgb(16, 171, 231);
-}
-
-.exercise-item .item-relevant-points {
-    display: inline-block;
-    padding: 1px 9px;
-    font-size: 13px;
-}
-
-.exercise-item .item-question .item-question-order {
-    display: inline-block;
-    vertical-align: top;
-    width: 25px;
-}
-
-.exercise-item .item-question .item-question-text {
-    display: inline-block;
-    width: calc(90% - 50px);
-}
-
-.exercise-item .item-options {
-    margin-top: 10px;
-}
-
-.exercise-item .item-options .item-option-content {
-    margin: 7px 0;
-}
-
-.exercise-item .item-options .item-option-order {
-    display: inline-block;
-    vertical-align: top;
-    width: 25px;
-}
-
-.exercise-item .item-options .item-option-text {
-    display: inline-block;
-    width: calc(100% - 25px);
-}
-
-.exercise-item .toggle-area {
-    border-top: 1px #c3c3c34d dashed;
-    padding-top: 10px;
-    margin-top: 10px;
-}
-
-.exercise-item .item-answer {
-    display: inline-block;
-    cursor: pointer;
-    margin-top: 12px;
-    font-size: 14px;
-}
-
-.exercise-item .item-answer-item {
-    margin-left: 25px;
-    padding: 0 25px;
-    margin-bottom:10px;
-/*    border-bottom: 2px solid rgb(128, 128, 128);*/
-}
-
-.exercise-item .item-answer-item:first-child {
-    margin-left: 0;
-}
-
-.exercise-item .item-answer-details {
-    margin: 10px 20px;
-}
-
-.exercise-item .item-answer .answer-title-line {
-    background: rgb(0, 173, 37);
-    padding: 0 3px;
-    border-radius: 5px;
-}
-
-.exercise-item .item-answer .answer-title {
-    margin-left: 10px;
-    color: rgb(0, 173, 37);
-}
-
-.exercise-item .item-explain {
-    margin-top: 10px;
-    cursor: pointer;
-    font-size: 14px;
-}
-
-.exercise-item .item-explain-item {
-    margin-left: 25px;
-    padding: 0 25px;
-/*    border-bottom: 2px solid rgb(128, 128, 128);*/
-}
-
-.exercise-item .item-explain-details {
-    margin-left: 5px;
-    vertical-align: top;
-    display: inline-block;
-    width: calc(100% - 90px)
-}
-
-.exercise-item .item-explain-details .item-point-tag {
-    padding: 0 10px;
-    border: 1px solid #d6d6d6;
-    margin-left: 10px;
-    border-radius: 4px;
-}
-
-.exercise-item .item-explain-details .item-point-tag:first-child {
-    margin-left: 0;
-}
-
-.exercise-item .item-explain .explain-title-line {
-    background: rgb(16, 171, 231);
-    padding: 0 3px;
-    border-radius: 5px;
-}
-
-.exercise-item .item-explain .explain-title {
-    width: 80px;
-    display: inline-block;
-    color: rgb(16, 171, 231);
-}
-.exercise-item .item-explain .answer-title {
-    width: 130px;
-    display: inline-block;
-    color: red;
-}
-
-.exercise-item .item-tools {
-    width: 100%;
-    padding: 10px 0;
-    margin-top: 20px;
-    font-size: 14px;
-    border-top: 1px #c3c3c34d dashed;
-}
-
-.exercise-item .item-tools .item-tools-action {
-    float: right;
-    color: #01b4ef;
-    margin: 0 20px;
-    margin-top: 8px;
-    font-size: 14px;
-    display: flex;
-    align-items: center;
-    cursor: pointer;
-}
-
-.exercise-item .item-tools .item-tools-action .ivu-icon {
-    font-size: 18px;
-}
-
-.exercise-item .item-tools .ivu-icon {
-    font-size: 16px;
-    margin-right: 5px;
-    font-weight: bold;
-}
-
-.exercise-item .item-tools .ivu-btn {
-    float: right;
-    border-color: transparent;
-    box-shadow: none;
-}
-
-.exercise-item .item-tools-tool {
-    margin-left: 10px;
-    font-weight: bold;
-    cursor: pointer;
-    color: rgb(16, 171, 231);
-    font-size: 14px;
-}
-
-.exercise-item .item-tools-tool .ivu-icon {
-    margin-left: 15px;
-    vertical-align: top;
-}
-
-.exercise-item .item-tools-tool .item-bind-point {
-    color: rgb(128, 128, 128);
-    margin-left: 5px;
-}
-
-.exercise-item .item-tools-tool .ivu-tag {
-    margin-top: -2px;
-}
-
-.exercise-item .item-tools-tool .ivu-tag-border {
-    line-height: 22px;
-}
-
-
-.exercise-item .item-tools .item-tools-info {
-    vertical-align: sub;
-    color: #868686;
-    border-right: 2px solid #d2d2d2;
-    font-size: 12px;
-    padding: 0 10px;
-}
-
-.exercise-item .item-tools .item-tools-info:first-child {
-    padding-left: 0;
-}
-
-.exercise-item .item-tools span:nth-child(3) {
-    border-right-width: 0;
-}
-
-
-.ev-list-container h1, h2, h3, h4, h5, h6 {
-    display: inline-block;
-}
-
-.filter-wrap {
-    width: 100%;
-    padding: 20px;
-    background: #fff;
-}
-
-.filter-wrap .filter-item:first-child {
-    margin-top: 0px;
-}
-
-.filter-wrap .filter-item {
-    margin-top: 10px;
-}
-
-.filter-wrap .filter-title {
-    font-size: 16px;
-    font-weight: bold;
-    margin-right: 10px;
-}
-
-.filter-wrap .ivu-radio-group {
-    padding-bottom: 4px;
-}
-
-.filter-wrap .ivu-radio-wrapper {
-    padding: 0 10px;
-    margin-left: 15px;
-    height: 28px;
-    line-height: 28px;
-    box-shadow: none !important;
-    border: none !important;
-    font-size: 14px;
-    border-radius: 0 !important;
-}
-
-.filter-wrap .ivu-radio-wrapper .ivu-icon {
-    margin-bottom: 2px;
-}
-
-.filter-wrap .ivu-radio-wrapper:after, .ivu-radio-group-button .ivu-radio-wrapper:before {
-    content: none;
-}
-
-.filter-wrap .ivu-radio-group-item {
-    border-radius: 5px !important;
-}
-
-.filter-wrap .ivu-radio-wrapper-checked {
-    background: rgb(16, 171, 231);
-    box-shadow: none !important;
-    color: white;
-}
-
-.filter-wrap .ivu-radio-group-button .ivu-radio-wrapper-checked:hover {
-    color: #fff !important;
-}
-
-
-
-.filter-wrap .ivu-checkbox-group {
-    padding-bottom: 4px;
-    display: inline-block;
-}
-
-.filter-wrap .ivu-checkbox-inner,
-.filter-wrap .ivu-checkbox-checked,
-.filter-wrap .ivu-checkbox {
-    display: none;
-}
-
-.filter-wrap .ivu-checkbox-wrapper {
-    padding: 0 10px;
-    margin-left: 15px;
-    height: 28px;
-    line-height: 28px;
-    box-shadow: none !important;
-    border: none !important;
-    font-size: 14px;
-    border-radius: 0 !important;
-}
-
-.filter-wrap .ivu-checkbox-wrapper .ivu-icon {
-    margin-bottom: 2px;
-}
-
-.filter-wrap .ivu-checkbox-wrapper:after, .ivu-checkbox-group-button .ivu-checkbox-wrapper:before {
-    content: none;
-}
-
-.filter-wrap .ivu-checkbox-group-item {
-    border-radius: 5px !important;
-}
-
-.filter-wrap .ivu-checkbox-wrapper-checked {
-    background: rgb(16, 171, 231);
-    box-shadow: none !important;
-    color: white;
-}
-
-.filter-wrap .ivu-checkbox-group-button .ivu-checkbox-wrapper-checked:hover {
-    color: #fff !important;
-}
-
-
-.ev-list-container .ivu-page {
-    display: flex;
-    flex-direction: row;
-    justify-content: center;
-    margin: 20px 0;
-}
-
-/*绑定知识点部分树形结构样式*/
-
-.singleClass {
-    cursor: pointer;
-    font-size: 14px;
-    margin: 10px;
-}
-
-.transferModal {
-    overflow: hidden;
-}
-
-.transferModal .point-list {
-    max-height: 400px;
-    overflow: auto;
-}
-
-.transferModal .point-list .ivu-input-wrapper {
-    width: 90%;
-    margin-bottom: 10px;
-}
-
-.transferModal .selected-point-list {
-    padding: 10px;
-    width: 100%;
-    border-top: 1px solid rgba(128, 128, 128,.3);
-    margin-top: 15px;
-}
-
-.transferModal .bind-title {
-    margin: 10px 0;
-    font-weight: bold;
-    font-size: 14px;
-}
-
-.transferModal .checked-point {
-    margin: 5px 10px;
-    background: rgb(16, 171, 231);
-    padding: 5px 10px;
-    color: #fff;
-    border-radius: 5px;
-    display: inline-block;
-}
-
-.transferModal .ivu-checkbox-checked .ivu-checkbox-inner {
-    background: rgb(16, 171, 231);
-    border-color: rgb(16, 171, 231);
-}
-
-.transferModal .ivu-icon {
-    color: rgb(16, 171, 231);
-}
-
-.transferModal .btn-clear {
-    float: right;
-    font-weight: 500;
-    font-size: 12px;
-    color: rgb(16, 171, 231);
-    cursor: pointer;
-    letter-spacing: 1px;
-}
-
-.transferModal .point-checkbox {
-    margin-left: 10px;
-    border-radius: 2px;
-    width: 15px;
-    height: 15px;
-    padding: 2px;
-    vertical-align: middle;
-    box-sizing: border-box;
-    border: 1px solid #dcdee2;
-}
-
-.transferModal .point-checked {
-    background: rgb(16, 171, 231);
-    background-clip: content-box;
-}
-
-.transferModal .ivu-tabs-nav-scroll {
-    display: flex;
-    flex-direction: row;
-    justify-content: center;
-}
-
-.transferModal .ivu-tree-empty {
-    text-align: center;
-    margin: 15px;
-    color: rgb(128, 128, 128);
-}
-
-.point-list::-webkit-scrollbar { /*滚动条整体样式*/
-    width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-    height: 1px;
-}
-
-.point-list:hover .ztree_box::-webkit-scrollbar {
-    width: 5px;
-}
-
-.point-list::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-    border-radius: 10px;
-    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-    background: #70707026;
-}
-
-.point-list::-webkit-scrollbar-track { /*滚动条里面轨道*/
-    background: #f4f4f400;
-}
-
-.shop {
-    position: fixed;
-    top: 300px;
-    left: 400px;
-}
-
-.ball {
-    position: fixed;
-    right: 128px;
-    bottom: 45px;
-    z-index: 200;
-    transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
-    /*贝塞尔曲线*/
-}
-
-.inner {
-    width: 16px;
-    height: 16px;
-    border-radius: 50%;
-    /*background-color: rgb(0, 160, 220);*/
-    transition: all 0.4s linear;
-}
-
-.inner img {
-    width: 26px;
-    height: 26px;
-}
-
-.cart {
-    position: fixed;
-    bottom: 22px;
-    right: 32px;
-    width: 30px;
-    height: 30px;
-    background-color: rgb(0, 160, 220);
-    color: rgb(255, 255, 255);
-}

File diff suppressed because it is too large
+ 719 - 192
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperList.vue


+ 688 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperLists.less

@@ -0,0 +1,688 @@
+.answer-box{
+    display:inline-flex;
+    margin-left:-5px;
+}
+.answer-score {
+    width: 130px;
+    color: rgb(16, 171, 231);
+}
+.answer-scores {
+    width: 130px;
+    color: rgb(16, 171, 231);
+    padding-top:10px;
+}
+
+.components-el-container .type-name {
+    font-size: 18px;
+    font-weight: bold;
+    margin-top: 20px;
+}
+
+
+.components-el-container .exercise-item .item-tools-t:hover {
+    background: #4a5ae6;
+}
+
+.components-el-container .exercise-item .item-score {
+    margin-right: 10px;
+    color: #fff;
+    background: #01b4ef;
+    padding: 4px 10px;
+    border-radius: 5px;
+}
+
+.type-score-btn {
+    width: 80%;
+    margin-left: 10%;
+    height: 40px;
+    line-height: 40px;
+}
+
+
+.ev-list-container {
+    user-select: none !important;
+    position: relative;
+    font-family: '微軟正黑體', 'Heiti TC' !important;
+}
+
+.ev-list-container .ev-header {
+    background: #fff;
+    padding: 10px;
+    display: flex;
+    align-items: center;
+}
+
+.ev-list-container .ev-title {
+    font-size: 20px;
+    font-weight: bold;
+    margin-left: 5px;
+    vertical-align: middle;
+}
+
+.ev-list-container .ev-length {
+    font-size: 12px;
+    font-weight: bold;
+    margin-left: 30px;
+    display: inline-block;
+    margin-top: 5px;
+    vertical-align: text-top;
+}
+
+.ev-list-container .ivu-divider-horizontal {
+    margin: 15px 0;
+}
+ .no-data-text {
+   text-align:center;
+   margin-top:20%;
+}
+
+.ev-list-operation {
+    position: absolute;
+    top: -65px;
+    right: 0;
+    height: 60px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.ev-list-operation .ivu-checkbox-wrapper {
+    font-size: 14px;
+}
+
+.ev-list-operation .ivu-checkbox {
+    margin: 10px;
+}
+
+.ev-list-operation .import-exercise {
+    font-weight: bold;
+    color: rgb(16, 171, 231);
+    font-size: 16px;
+    display: flex;
+}
+
+.ev-list-operation .import-exercise .ivu-btn {
+    margin-right: 10px;
+    border: none !important;
+}
+
+.ev-list-operation .ivu-icon {
+    font-size: 16px;
+    margin-right: 6px;
+    cursor: pointer;
+    vertical-align: initial;
+}
+
+.ev-list-operation .ivu-badge-count {
+    right: 12px;
+}
+
+.ev-list-operation .ivu-checkbox-checked .ivu-checkbox-inner {
+    background: #01b4ef;
+    border-color: #01b4ef;
+}
+
+
+.exercise-backet-wrap .ivu-btn {
+    border: none !important;
+}
+
+.exercise-backet-wrap .exercise-backet-item:not(:first-child) {
+    margin-left: 10px;
+}
+
+.exercise-backet-wrap .exercise-backet-num {
+    font-weight: bold;
+    margin: 0 5px;
+    font-size: 16px;
+    color: rgb(16, 171, 231);
+}
+
+
+
+.ev-content {
+    background: none;
+}
+
+.content-wrap {
+    position: relative;
+    width: 100%;
+    height: auto;
+    display: flex;
+    flex-direction: column;
+}
+
+.content-wrap .exercise-item {
+    width: 100%;
+    height: auto;
+    padding: 10px 20px 10px 20px;
+    margin-top: 10px;
+    font-size: 16px;
+    font-weight: 600;
+    background: #fff;
+    cursor: pointer;
+    /*box-shadow: 6px 5px 5px 2px rgb(214, 214, 214);*/
+}
+
+.content-wrap .exercise-item table, .content-wrap .exercise-item td {
+/*    border: 1px solid rgb(128, 128, 128);*/
+    border-collapse: collapse;
+    text-align: center;
+    padding: 5px 10px;
+}
+
+
+.content-wrap .exercise-item:hover .item-tools-bind {
+    display: unset;
+}
+
+.complete-line {
+    margin: 0 5px;
+    padding: 0 45px;
+/*    border-bottom: 2px solid rgb(128, 128, 128);*/
+}
+
+.exercise-item .item-question {
+    /*display: inline-block;*/
+    /*margin-top:20px;*/
+    position: relative;
+    cursor: pointer;
+}
+
+.exercise-item img {
+    vertical-align: middle;
+}
+
+.exercise-item .item-question .item-btn-toggle {
+    position: absolute;
+    right: 0;
+    top: 0;
+}
+
+.exercise-item .item-question .item-btn-toggle .ivu-icon {
+    font-size: 22px;
+    cursor: pointer;
+}
+
+.exercise-item .item-difficulty {
+    display: inline-block;
+    padding: 2px 10px;
+    background: rgb(16, 171, 231);
+    border-radius: 5px;
+    color: #fff;
+    font-size: 12px;
+}
+
+.exercise-item .item-type {
+    display: inline-block;
+    padding: 1px 9px;
+    border-radius: 5px;
+    color: #fff;
+    font-size: 12px;
+    margin-left: 5px;
+    background: rgb(16, 171, 231);
+}
+
+.exercise-item .item-relevant-points {
+    display: inline-block;
+    padding: 1px 9px;
+    font-size: 13px;
+}
+
+.exercise-item .item-question .item-question-order {
+    display: inline-block;
+    vertical-align: top;
+    width: 25px;
+}
+
+.exercise-item .item-question .item-question-text {
+    display: inline-block;
+    width: calc(90% - 50px);
+}
+
+.exercise-item .item-options {
+    margin-top: 10px;
+}
+
+.exercise-item .item-options .item-option-content {
+    margin: 7px 0;
+}
+
+.exercise-item .item-options .item-option-order {
+    display: inline-block;
+    vertical-align: top;
+    width: 25px;
+}
+
+.exercise-item .item-options .item-option-text {
+    display: inline-block;
+    width: calc(100% - 25px);
+}
+
+.exercise-item .toggle-area {
+    border-top: 1px #c3c3c34d dashed;
+    padding-top: 10px;
+    margin-top: 10px;
+}
+
+.exercise-item .item-answer {
+    display: inline-block;
+    cursor: pointer;
+    margin-top: 12px;
+    font-size: 14px;
+}
+
+.exercise-item .item-answer-item {
+    margin-left: 25px;
+    padding: 0 25px;
+    margin-bottom:10px;
+/*    border-bottom: 2px solid rgb(128, 128, 128);*/
+}
+
+.exercise-item .item-answer-item:first-child {
+    margin-left: 0;
+}
+
+.exercise-item .item-answer-details {
+    margin: 10px 20px;
+}
+
+.exercise-item .item-answer .answer-title-line {
+    background: rgb(0, 173, 37);
+    padding: 0 3px;
+    border-radius: 5px;
+}
+
+.exercise-item .item-answer .answer-title {
+    margin-left: 10px;
+    color: rgb(0, 173, 37);
+}
+
+.exercise-item .item-explain {
+    margin-top: 10px;
+    cursor: pointer;
+    font-size: 14px;
+}
+
+.exercise-item .item-explain-item {
+    margin-left: 25px;
+    padding: 0 25px;
+/*    border-bottom: 2px solid rgb(128, 128, 128);*/
+}
+
+.exercise-item .item-explain-details {
+    margin-left: 5px;
+    vertical-align: top;
+    display: inline-block;
+    width: calc(100% - 90px)
+}
+
+.exercise-item .item-explain-details .item-point-tag {
+    padding: 0 10px;
+    border: 1px solid #d6d6d6;
+    margin-left: 10px;
+    border-radius: 4px;
+}
+
+.exercise-item .item-explain-details .item-point-tag:first-child {
+    margin-left: 0;
+}
+
+.exercise-item .item-explain .explain-title-line {
+    background: rgb(16, 171, 231);
+    padding: 0 3px;
+    border-radius: 5px;
+}
+
+.exercise-item .item-explain .explain-title {
+    width: 80px;
+    display: inline-block;
+    color: rgb(16, 171, 231);
+}
+.exercise-item .item-explain .answer-title {
+    width: 130px;
+    display: inline-block;
+    color: red;
+}
+
+.exercise-item .item-tools {
+    width: 100%;
+    padding: 10px 0;
+    margin-top: 20px;
+    font-size: 14px;
+    border-top: 1px #c3c3c34d dashed;
+}
+
+.exercise-item .item-tools .item-tools-action {
+    float: right;
+    color: #01b4ef;
+    margin: 0 20px;
+    margin-top: 8px;
+    font-size: 14px;
+    display: flex;
+    align-items: center;
+    cursor: pointer;
+}
+
+.exercise-item .item-tools .item-tools-action .ivu-icon {
+    font-size: 18px;
+}
+
+.exercise-item .item-tools .ivu-icon {
+    font-size: 16px;
+    margin-right: 5px;
+    font-weight: bold;
+}
+
+.exercise-item .item-tools .ivu-btn {
+    float: right;
+    border-color: transparent;
+    box-shadow: none;
+}
+
+.exercise-item .item-tools-tool {
+    margin-left: 10px;
+    font-weight: bold;
+    cursor: pointer;
+    color: rgb(16, 171, 231);
+    font-size: 14px;
+}
+
+.exercise-item .item-tools-tool .ivu-icon {
+    margin-left: 15px;
+    vertical-align: top;
+}
+
+.exercise-item .item-tools-tool .item-bind-point {
+    color: rgb(128, 128, 128);
+    margin-left: 5px;
+}
+
+.exercise-item .item-tools-tool .ivu-tag {
+    margin-top: -2px;
+}
+
+.exercise-item .item-tools-tool .ivu-tag-border {
+    line-height: 22px;
+}
+
+
+.exercise-item .item-tools .item-tools-info {
+    vertical-align: sub;
+    color: #868686;
+    border-right: 2px solid #d2d2d2;
+    font-size: 12px;
+    padding: 0 10px;
+}
+
+.exercise-item .item-tools .item-tools-info:first-child {
+    padding-left: 0;
+}
+
+.exercise-item .item-tools span:nth-child(3) {
+    border-right-width: 0;
+}
+
+
+.ev-list-container h1, h2, h3, h4, h5, h6 {
+    display: inline-block;
+}
+
+.filter-wrap {
+    width: 100%;
+    padding: 20px;
+    background: #fff;
+}
+
+.filter-wrap .filter-item:first-child {
+    margin-top: 0px;
+}
+
+.filter-wrap .filter-item {
+    margin-top: 10px;
+}
+
+.filter-wrap .filter-title {
+    font-size: 16px;
+    font-weight: bold;
+    margin-right: 10px;
+}
+
+.filter-wrap .ivu-radio-group {
+    padding-bottom: 4px;
+}
+
+.filter-wrap .ivu-radio-wrapper {
+    padding: 0 10px;
+    margin-left: 15px;
+    height: 28px;
+    line-height: 28px;
+    box-shadow: none !important;
+    border: none !important;
+    font-size: 14px;
+    border-radius: 0 !important;
+}
+
+.filter-wrap .ivu-radio-wrapper .ivu-icon {
+    margin-bottom: 2px;
+}
+
+.filter-wrap .ivu-radio-wrapper:after, .ivu-radio-group-button .ivu-radio-wrapper:before {
+    content: none;
+}
+
+.filter-wrap .ivu-radio-group-item {
+    border-radius: 5px !important;
+}
+
+.filter-wrap .ivu-radio-wrapper-checked {
+    background: rgb(16, 171, 231);
+    box-shadow: none !important;
+    color: white;
+}
+
+.filter-wrap .ivu-radio-group-button .ivu-radio-wrapper-checked:hover {
+    color: #fff !important;
+}
+
+
+
+.filter-wrap .ivu-checkbox-group {
+    padding-bottom: 4px;
+    display: inline-block;
+}
+
+.filter-wrap .ivu-checkbox-inner,
+.filter-wrap .ivu-checkbox-checked,
+.filter-wrap .ivu-checkbox {
+    display: none;
+}
+
+.filter-wrap .ivu-checkbox-wrapper {
+    padding: 0 10px;
+    margin-left: 15px;
+    height: 28px;
+    line-height: 28px;
+    box-shadow: none !important;
+    border: none !important;
+    font-size: 14px;
+    border-radius: 0 !important;
+}
+
+.filter-wrap .ivu-checkbox-wrapper .ivu-icon {
+    margin-bottom: 2px;
+}
+
+.filter-wrap .ivu-checkbox-wrapper:after, .ivu-checkbox-group-button .ivu-checkbox-wrapper:before {
+    content: none;
+}
+
+.filter-wrap .ivu-checkbox-group-item {
+    border-radius: 5px !important;
+}
+
+.filter-wrap .ivu-checkbox-wrapper-checked {
+    background: rgb(16, 171, 231);
+    box-shadow: none !important;
+    color: white;
+}
+
+.filter-wrap .ivu-checkbox-group-button .ivu-checkbox-wrapper-checked:hover {
+    color: #fff !important;
+}
+
+
+.ev-list-container .ivu-page {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    margin: 20px 0;
+}
+
+/*绑定知识点部分树形结构样式*/
+
+.singleClass {
+    cursor: pointer;
+    font-size: 14px;
+    margin: 10px;
+}
+
+.transferModal {
+    overflow: hidden;
+}
+
+.transferModal .point-list {
+    max-height: 400px;
+    overflow: auto;
+}
+
+.transferModal .point-list .ivu-input-wrapper {
+    width: 90%;
+    margin-bottom: 10px;
+}
+
+.transferModal .selected-point-list {
+    padding: 10px;
+    width: 100%;
+    border-top: 1px solid rgba(128, 128, 128,.3);
+    margin-top: 15px;
+}
+
+.transferModal .bind-title {
+    margin: 10px 0;
+    font-weight: bold;
+    font-size: 14px;
+}
+
+.transferModal .checked-point {
+    margin: 5px 10px;
+    background: rgb(16, 171, 231);
+    padding: 5px 10px;
+    color: #fff;
+    border-radius: 5px;
+    display: inline-block;
+}
+
+.transferModal .ivu-checkbox-checked .ivu-checkbox-inner {
+    background: rgb(16, 171, 231);
+    border-color: rgb(16, 171, 231);
+}
+
+.transferModal .ivu-icon {
+    color: rgb(16, 171, 231);
+}
+
+.transferModal .btn-clear {
+    float: right;
+    font-weight: 500;
+    font-size: 12px;
+    color: rgb(16, 171, 231);
+    cursor: pointer;
+    letter-spacing: 1px;
+}
+
+.transferModal .point-checkbox {
+    margin-left: 10px;
+    border-radius: 2px;
+    width: 15px;
+    height: 15px;
+    padding: 2px;
+    vertical-align: middle;
+    box-sizing: border-box;
+    border: 1px solid #dcdee2;
+}
+
+.transferModal .point-checked {
+    background: rgb(16, 171, 231);
+    background-clip: content-box;
+}
+
+.transferModal .ivu-tabs-nav-scroll {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+}
+
+.transferModal .ivu-tree-empty {
+    text-align: center;
+    margin: 15px;
+    color: rgb(128, 128, 128);
+}
+
+.point-list::-webkit-scrollbar { /*滚动条整体样式*/
+    width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+}
+
+.point-list:hover .ztree_box::-webkit-scrollbar {
+    width: 5px;
+}
+
+.point-list::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
+    border-radius: 10px;
+    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+    background: #70707026;
+}
+
+.point-list::-webkit-scrollbar-track { /*滚动条里面轨道*/
+    background: #f4f4f400;
+}
+
+.shop {
+    position: fixed;
+    top: 300px;
+    left: 400px;
+}
+
+.ball {
+    position: fixed;
+    right: 128px;
+    bottom: 45px;
+    z-index: 200;
+    transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
+    /*贝塞尔曲线*/
+}
+
+.inner {
+    width: 16px;
+    height: 16px;
+    border-radius: 50%;
+    /*background-color: rgb(0, 160, 220);*/
+    transition: all 0.4s linear;
+}
+
+.inner img {
+    width: 26px;
+    height: 26px;
+}
+
+.cart {
+    position: fixed;
+    bottom: 22px;
+    right: 32px;
+    width: 30px;
+    height: 30px;
+    background-color: rgb(0, 160, 220);
+    color: rgb(255, 255, 255);
+}

+ 394 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaperLists.vue

@@ -0,0 +1,394 @@
+<template>
+	<div class="components-el-container">
+		<!-- 题目列表部分 -->
+		<div v-if="exerciseList.length == 0" class="no-data-text">
+			<img src="@/assets/icon/no_data.svg" width="120" />
+			<span style="margin-top:15px;display:block;color:#808080">请先选择学生信息</span>
+		</div>
+		<div class="content-wrap" v-if="groupList.length != 0">
+			<Loading :top="200" v-show="dataLoading" type="1"></Loading>
+			<div class="list-view" :key="typeIndex" v-for="(typeItem,typeIndex) in groupList">
+				<p v-show="viewModel === 'type' && typeItem.list.length" class="type-name">
+					{{ numberConvertToUppercase(getLatestTypeIndex(typeItem.type) + 1) }} : {{ exersicesType[typeItem.type] }}
+					( {{ typeItem.score }} 分)
+				</p>
+				<div class="exercise-item" v-for="(item,index) of typeItem.list" :key="index"
+					>
+					<!-- 题干部分 -->
+					<div class="item-question">
+						<div v-if="viewModel === 'list'">
+							<div class="item-question-order">{{pageSize * (pageNum - 1) + exerciseList.indexOf(item) + 1}} . </div>
+							<div class="item-question-text" v-html="item.question"></div>
+						</div>
+						<div v-else>
+							<div class="item-question-order">{{ pageSize * (pageNum - 1) + index + 1 }} . </div>
+							<div class="item-question-text" v-html="item.question"></div>
+						</div>
+						<span class="item-btn-toggle">
+							<span class="item-score">{{ item.score }} 分</span>
+							<Icon :type="collapseList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" />
+						</span>
+					</div>
+					<!-- 选项部分 -->
+					<div v-for="(option,optionIndex) in item.option" :key="optionIndex" class="item-options" style="pointer-events:none">
+						<div class="item-option-content">
+							<div class="item-option-order">{{String.fromCharCode(64 + parseInt(optionIndex+1))}} :</div>
+							<div class="item-option-text" v-html="option.value"></div>
+						</div>
+					</div>
+
+					<div class="item-explain">
+						<span class="answer-title">【作 答 答 案】</span>
+                        <div class="item-explain-details">
+                            <!-- 问答题答案 -->
+							<div v-if="item.type === 'Subjective'">
+								<div v-for="(answer,index) in item.answerData" :key="index">
+									<span v-html="item.answer.length ? answer.ans[0] : '未设置答案'"></span><br />
+								</div>
+								<div class="answer-box">
+									<span class="answer-scores">【题 目 分 数】</span>
+									<InputNumber  v-model="answer.score" placeholder="请输入题目分数..." @on-change="inputScore(answer)" style=" width: 150px; margin-top: -5px;" />
+								</div>
+							</div>
+                            <!-- 填空题答案 -->
+							<div v-else-if="item.type === 'Complete'">
+								<div  v-for="(answer,index) in item.answerData" :key="index">
+									<div :class="[ item.type === 'Complete' ? 'item-answer-items':'']">
+										<p>{{index+1}}:</p><span v-html="answer.ans[0]"></span><br />
+									</div>
+									<div class="answer-box">
+										<span class="answer-scores">【题 目 分 数 】</span>
+										<InputNumber v-model="answer.score"  placeholder="请输入题目分数..." @on-change="inputScore(answer)" style=" width: 150px; margin-top: 5px;" />
+									</div>
+								</div>
+							</div>
+                            <!-- 其余题型答案 -->
+							<div v-else>
+								<div :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answerData" :key="index">
+									<span>{{answer.ans[0]}}</span><br />
+								</div>
+								<div class="answer-box">
+									<span class="answer-score">【题 目 分 数】</span>
+									<InputNumber v-model="answer[index].listInfo[0].score" placeholder="请输入题目分数..." @on-change="inputScore(answer[index])" style=" width: 150px; margin-top: -5px;margin-right:10px;" />
+									<Button size="small" v-if="answer[index].listInfo[0].score !== null" type="success">修改</Button>
+								</div>
+							</div>
+                        </div>
+					</div>
+
+					<transition name="slide">
+						<div v-show="collapseList.indexOf(exerciseList.indexOf(item)) > -1" class="toggle-area">
+							<!-- 答案展示部分 -->
+							<div class="item-explain" v-show="isShowAnswer">
+								<span class="explain-title">【答ㅤ案】</span>
+								<div class="item-explain-details">
+									<!-- 问答题答案 -->
+									<div v-if="item.type === 'Subjective'">
+										<span v-for="(answer,index) in item.answer" :key="index" v-html="item.answer.length ? answer : '未设置答案'"></span>
+									</div>
+									<!-- 填空题答案 -->
+									<div v-else-if="item.type === 'Complete'">
+										<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index"
+											  v-html="answer"></span>
+									</div>
+									<!-- 其余题型答案 -->
+									<div v-else>
+										<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index">{{answer}}</span>
+									</div>
+								</div>
+							</div>
+							<!-- 解析部分 -->
+							<div class="item-explain" v-show="isShowAnswer">
+								<span class="explain-title">【解ㅤ析】</span>
+								<div class="item-explain-details">
+									<span v-html="item.explain || '暂无解析'"></span>
+								</div>
+							</div>
+						</div>
+					</transition>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	import Loading from '@/common/Loading.vue'
+	export default {
+		props: {
+			paper: {
+				type: Object,
+				default: null
+			},
+			answer: {
+				type: Array,
+				default:() => []
+            }
+		},
+		components: {
+			Loading,
+		},
+		data() {
+			return {
+				value:'',
+				schoolCode: '',
+				dataLoading: false,
+				exerciseList: [],
+				schoolInfo: {},
+				exersicesType: {
+					Single: '单选题',
+					Multiple: '多选题',
+					Judge: '判断题',
+					Complete: '填空题',
+					Subjective: '问答题',
+					Compose: '综合题'
+				},
+				exersicesDiff: ['容易', '较易', '一般', '较难', '困难'],
+				diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
+				totalNum: 0,
+				isShowAnswer: true,
+				importLoading: false,
+				pageSize: 99,
+				pageNum: 1,
+				currentPage: 1,
+				collapseList: [],
+				periodList: [],
+				gradeList: [],
+				subjectList: [],
+				basketList: [],
+				originData: [],
+				groupList: [],
+				groupTypeList: [],
+				typeList: ['Single', 'Multiple', 'Judge', 'Complete', 'Subjective', 'Compose'],
+				viewModel: 'type',
+				filterParams: {},
+				surPlusScore: 0,
+				curItemScore: 0,
+				curIndex: 0,
+				lastScore: 0,
+				scoreStep: 0.5,
+				curTypeItems: [],
+				scoreModal: false,
+				currentExercise: {},
+				allPointList: []
+			}
+		},
+
+		methods: {
+			inputScore(data) {
+				console.log(data)
+				if (data.score == "") {
+					this.$Message.warning('请完成题目评分!')
+                }
+			},
+			/**
+			 * 题干展开与收缩
+			 * @param index
+			 * @param id
+			 */
+			onQuestionToggle(index, id, e) {
+				//e.stopPropagation()
+				//let listIndex = this.collapseList.indexOf(index)
+				//if (listIndex > -1) {
+				//	this.collapseList.splice(listIndex, 1)
+				//} else {
+				//	/** 如果是首次展开 则需要获取详细数据 否则直接展开 */
+				//	if (!this.exerciseList[index].answer.length) {
+				//		this.collapseList.push(index)
+				//		this.pageScrollTo(e.target.offsetTop + 420) // 490就是 content-wrap 距离顶部高度
+				//	} else {
+				//		this.collapseList.push(index)
+				//		this.pageScrollTo(e.target.offsetTop + 420) // 490就是 content-wrap 距离顶部高度
+				//	}
+				//}
+
+				//this.$emit('toggleChange', this.collapseList)
+			},
+
+			/**
+			 * 根据知识点id集合换取知识点对象集合
+			 * @param ids
+			 */
+			getPointsByIds(ids) {
+				// 去除空值后
+				let idsArr = this._.compact(ids)
+				return new Promise((r, j) => {
+					if (idsArr.length) {
+						this.$api.knowledge.FindKnowledgebyId(idsArr).then(res => {
+							if (!res.error && res.result.data.length) {
+								r(res.result.data)
+							} else {
+								r([])
+							}
+						}).catch(err => {
+							j(err)
+						})
+					} else {
+						r([])
+					}
+				})
+
+			},
+
+			/**
+			 * 数字与中文转换
+			 * @param num
+			 */
+			numberConvertToUppercase(num) {
+				num = Number(num)
+				var upperCaseNumber = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '百', '千', '万', '亿']
+				var length = String(num).length
+				if (length === 1) {
+					return upperCaseNumber[num]
+				} else if (length === 2) {
+					if (num === 10) {
+						return upperCaseNumber[num]
+					} else if (num > 10 && num < 20) {
+						return '十' + upperCaseNumber[String(num).charAt(1)]
+					} else {
+						return upperCaseNumber[String(num).charAt(0)] + '十' + upperCaseNumber[String(num).charAt(1)].replace('零', '')
+					}
+				}
+			},
+
+			// 分页操作
+			pageChange(page) {
+				let start = this.pageSize * (page - 1)
+				let end = this.pageSize * page
+				this.pageNum = page
+				this.collapseList = []
+				this.exerciseList = this.originData.slice(start, end)
+				this.pageScrollTo(0)
+			},
+
+			pageSizeChange(val) {
+				this.pageSize = val
+				this.pageChange(1)
+			},
+
+			/**
+			 * 页面滚动事件
+			 * @param scrollDistance 页面滚动距离
+			 */
+			pageScrollTo(scrollDistance) {
+				//let parentVm = this.$parent.$parent.$parent.$parent
+				//parentVm.$refs['evScroll'].scrollTo(
+				//    {
+				//        y: scrollDistance
+				//    },
+				//    500, 'easeInQuad'
+				//)
+			},
+			// 子题顺序操作
+			moveItems(arr, index1, index2) {
+				arr[index1] = arr.splice(index2, 1, arr[index1])[0]
+				return arr
+			},
+
+			/**
+			 * 全部展开与全部折叠
+			 * @param isAllOpen
+			 */
+			onHandleToggle(isAllOpen) {
+				if (isAllOpen) {
+					this.collapseList = []
+				} else {
+					this.collapseList = [...this.exerciseList.keys()]
+				}
+			},
+
+			/**
+			 * 获取题目列表总分
+			 * @param arr
+			 */
+			getTotalScore(arr) {
+				arr.forEach(i => {
+					if (i.list.length === 0) {
+						i.score = 0
+					}
+				})
+				return arr.reduce((p, e) => p + e.score, 0)
+			},
+
+			getLatestTypeIndex(type) {
+				let arr = []
+				this.groupList.forEach(i => {
+					if (i.list.length) {
+						arr.push(i.type)
+					}
+				})
+				return arr.indexOf(type)
+			},
+			newPapers(data) {
+                if (data) {
+                    let that = this
+                    this.groupList = []
+                    this.exerciseList = []
+                    if (data.item !== undefined) {
+                        if (data.item.length !== 0) {
+                            /* 处理试卷内题目按照题型排序 */
+                            this.typeList.forEach(item => {
+                                this._.mapKeys(this._.groupBy(data.item, 'type'), function (value, key) {
+                                    if (key === item) { /* 按照题型排序,并且计算每种题型的总分 */
+                                        that.groupList.push({
+                                            type: key,
+                                            list: value,
+                                            score: value.reduce((p, e) => p + e.score, 0)
+                                        })
+                                        that.exerciseList = that.exerciseList.concat(value)
+                                    }
+                                })
+                            });
+                        }
+
+                        this.originData = this.exerciseList
+                        this.groupTypeList = this.groupList
+                        this.totalNum = data.item.length
+                        this.surPlusScore = data.score - data.item.reduce((p, e) => p + e.score, 0);
+                        this.pageScrollTo(0)
+                        this.pageChange(1)
+                    }
+                }
+            }
+		},
+
+		computed: {
+
+		},
+		watch: {
+			paper: {
+				handler(newPaper) {
+                    this.newPapers(newPaper)
+				},
+				deep: true
+			},
+			answer: {
+				handler(newValue, oldValue) {
+					this.newPapers(this.paper)
+				},
+				deep:true
+            },
+			viewModel: {
+				handler(newValue) {
+					if (newValue) {
+						if (newValue === 'list') {
+							this.groupList = [{
+								type: 'all',
+								score: this.exerciseList.reduce((p, e) => p + e.score, 0),
+								list: this.exerciseList
+							}]
+						} else {
+							this.groupList = this.groupTypeList
+						}
+					}
+				},
+				immediate: true
+			}
+		}
+
+	}
+</script>
+
+<style scoped>
+	@import "../learnactivity/ReviewPaperList.less";
+</style>

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

@@ -157,7 +157,7 @@
         z-index: 1 !important;
 
         .w-e-menu {
-            z-index: 1 !important;
+            z-index: 2 !important;
         }
     }
 

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

@@ -84,10 +84,9 @@
 				relateFileList: [],
 				uploadUrl: '',
 				defaultConfig: {
-					uploadImgServer: '/api/file/uploadWangEditor', // 图片上传地址
 					showLinkImg: false, // 是否展示网络图片链接上传
 					uploadFileName: 'files', // 上传图片后台获取的文件名
-					menus: this.$tools.wangEditorMenu
+					menus: this.$tools.wangEditorMenuSimple
 				},
 				qnForm: {
 					name: '',

+ 1 - 1
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseGeniusLine.vue

@@ -13,7 +13,7 @@
         props: ['echartsId', 'echartsData'],
         data() {
             return {
-                dataLoading:true,
+                dataLoading:false,
                 radarData: []
             }
         },

+ 8 - 3
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTest.vue

@@ -108,9 +108,9 @@
       </div>
       <!--單一學科試卷-->
       <div
-        v-if="
-          (this.$store.getters.getItemTitle.isDone == false &&
-            this.$store.getters.getItemTitle.endTime > '2020.02.10' &&
+        v-if="(
+           this.$store.getters.getItemTitle.isDone == false &&
+           this.$store.getters.getItemTitle.endTime > '2020.02.10' &&
             this.$store.getters.getItemTitle.eventSubject != '綜合學科') ||
           (this.$store.getters.getItemTitle.isDone == false &&
             this.$store.getters.getItemTitle.endTime <= '2020.02.10' &&
@@ -146,6 +146,11 @@
 
       <!----->
       <!--多學科試卷-->
+
+
+
+
+
       <div
         v-if="
           (this.$store.getters.getItemTitle.isDone == false &&

+ 7 - 12
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestPop.vue

@@ -139,9 +139,7 @@
           <span v-if="currentFilterQuestion == 'all'"
             >{{ $t("studentWeb.exam.testpop.all") }}
           </span>
-          <span v-if="currentFilterQuestion == 'wrong'">{{
-            $t("studentWeb.exam.testpop.onlywrong")
-          }}</span>
+          <span v-if="currentFilterQuestion == 'wrong'">{{ $t("studentWeb.exam.testpop.onlywrong") }}</span>
           {{ $t("studentWeb.exam.testpop.questions") }}
           <Icon type="ios-arrow-down"></Icon>
         </a>
@@ -173,12 +171,8 @@
         class="submitBtn"
         @click="showAns()"
       >
-        <span v-if="showtheAnsTable == false">{{
-          $t("studentWeb.exam.testpop.showAns")
-        }}</span>
-        <span v-if="showtheAnsTable == true">{{
-          $t("studentWeb.exam.testpop.hideAns")
-        }}</span>
+        <span v-if="showtheAnsTable == false">{{ $t("studentWeb.exam.testpop.showAns")}}</span>
+        <span v-if="showtheAnsTable == true">{{ $t("studentWeb.exam.testpop.hideAns")}}</span>
       </button>
     </div>
 
@@ -265,6 +259,7 @@
             alt
           />
           <br />
+            <!--答案卡-->
           <div class="md-ansSheetGroup">
             <h4>{{ $t("studentWeb.exam.testpop.myAnswerSheet") }}</h4>
             <table class="ansSheet">
@@ -355,9 +350,7 @@
                 (currentFilterQuestion == 'wrong' && currentQuestionNo != 1)
               "
             >
-              <Icon type="ios-arrow-back" />{{
-                $t("studentWeb.exam.testpop.previous")
-              }}
+              <Icon type="ios-arrow-back" />{{$t("studentWeb.exam.testpop.previous")}}
             </button>
             <!--span>第{{currentQuestionNo+1}}題</span-->
             <!--span>{{ this.$store.getters.getCurrentPhase+1 }}/3</span-->
@@ -377,6 +370,7 @@
             </button>
           </div>
         </div>
+          <!--答案卡-->
         <div
           style="margin-top: 10%"
           class="sm-ansSheetGroup"
@@ -569,6 +563,7 @@
             <Icon type="ios-arrow-forward" />
           </button>
         </div>
+          <!--答案卡-->
         <div style="margin-top: 10%" class="sm-ansSheetGroup">
           <h4>{{ $t("studentWeb.exam.testpop.myAnswerSheet") }}</h4>
           <table class="ansSheet">

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

@@ -418,7 +418,8 @@ export default {
 
   components: { PreviewProgressPie },
   created() {
-    this.createMockdata();
+      this.createMockdata();
+      this.setPaper()
   },
   watch: {
     /*eventTypeCheckers: function (value) {
@@ -481,7 +482,19 @@ export default {
       } else this.isListNoItem = false;
     },
   },
-  methods: {
+        methods: {
+            async setPaper() {
+                console.log(this.$store.state)
+                let data = {
+                    "id": "609b71e5-fe60-4abd-3892-bf5e90c8691a",
+                    "code": "Paper-hbcn",
+                    "name": "主观题测试",
+                    "blob": "/paper/主观题测试",
+                    "scope": "school",
+                }
+                let info = await this.$evTools.getFullItem(data)
+                console.log(info)
+            },
     timeoutCondition(item) {
       return (
         (item.endTime <= "2020.02.10" && item.allowRetryNow == false&& item.eventType != "問卷") ||
@@ -516,7 +529,14 @@ export default {
     createMockdata: function () {
       if (localStorage.getItem("lang") == "en") {
         this.mockdata = mockdataEn.eventList;
-      } else this.mockdata = mockdata.eventList;
+        } else this.mockdata = mockdata.eventList
+        for (let item of this.mockdata) {
+            if (item.eventType == "評量") {
+                console.log(item)
+            }
+        }
+        console.log('评量信息')
+        console.log(this.mockdata)
     },
     transStatustoEn(status) {
       if (status == "所有活動狀態") return "All Status";

+ 162 - 158
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventView.vue

@@ -1,180 +1,184 @@
 <template>
-  <div class="event-view">
-    <EventList
-      :class="{ 'hide-sidebar': this.$store.getters.getSidebarisOpen == false }"
-    ></EventList>
-    <EventContentArea
-      :class="{
+    <div class="event-view">
+        <EventList :class="{ 'hide-sidebar': this.$store.getters.getSidebarisOpen == false }"></EventList>
+        <EventContentArea :class="{
         'eventContentArea-Span': this.$store.getters.getSidebarisOpen == false,
         'eventContentArea-left':
           this.$store.getters.getOpenCommentList == true &&
           this.$store.getters.getSidebarisOpen == false,
-      }"
-    ></EventContentArea>
-    <CommentList
-      v-if="
+      }"></EventContentArea>
+        <CommentList v-if="
         this.$store.getters.getOpenCommentList == true &&
         this.$store.getters.getSidebarisOpen == false
-      "
-    />
-    <div
-      class="nextItemBtn"
-      @click="gotoNextItem()"
-      v-if="
+      " />
+        <div class="nextItemBtn"
+             @click="gotoNextItem()"
+             v-if="
         this.$store.getters.getSidebarisOpen == false &&
         this.$store.getters.getOpenCommentList == false
-      "
-    >
-      {{ $t("studentWeb.nextTask") }} →
+      ">
+            {{ $t("studentWeb.nextTask") }} →
+        </div>
     </div>
-  </div>
 </template>
 
 <script>
-import CommentList from "./CommentList.vue";
-import EventList from "./EventList";
-import EventContentArea from "./EventContentArea.vue";
-import mockdata from "@/api/newData";
-import mockdataEn from "@/api/newDataEn";
-export default {
-  name: "EventView",
-  components: {
-    EventList,
-    EventContentArea,
-    CommentList,
-  },
-  data() {
-    return {
-      MyNo: "4", //接收NavBar 選定的那一頁icon標示
-      MyName: "",
-      mockdata: "",
-      eventPageType: ["課前預習", "評量", "作業", "投票","問卷"] //本頁出現的類型
-    };
-  },
-  created() {
-    //發送本頁target 跟名字給App.Vue 的navBar
-  if(localStorage.getItem("lang") == ""){
-      this.mockdata = mockdata.eventList;
-    }
-    if (localStorage.getItem("lang") == "tw") {
-      this.mockdata = mockdata.eventList;
-    } else this.mockdata = mockdataEn.eventList;
-    this.MyName = this.$t("studentWeb.eventView-title");
-    this.$emit("onNavNo", this.MyNo);
-    this.$emit("onNavName", this.MyName);
-    this.$store.commit("ToggleSidebar", true);
-    this.$store.commit("SaveNowPage", '活動');
-  },
-  methods: {
-    scrollList() {
-      //當從通知操作進行捲動時,將篩選條件清空
-      this.selectedEventStatusNow = "所有活動狀態";
-      this.eventTypeCheckers = [];
-      console.log("收到從下一個按鈕切換項目");
+    import CommentList from "./CommentList.vue";
+    import EventList from "./EventList";
+    import EventContentArea from "./EventContentArea.vue";
+    import mockdata from "@/api/newData";
+    import mockdataEn from "@/api/newDataEn";
+    export default {
+        name: "EventView",
+        components: {
+            EventList,
+            EventContentArea,
+            CommentList,
+        },
+        data() {
+            return {
+                MyNo: "4", //接收NavBar 選定的那一頁icon標示
+                MyName: "",
+                mockdata: "",
+                eventPageType: ["課前預習", "評量", "作業", "投票", "問卷"] //本頁出現的類型
+            };
+        },
+        created() {
+            //發送本頁target 跟名字給App.Vue 的navBar
+            if (localStorage.getItem("lang") == "") {
+                this.mockdata = mockdata.eventList;
+            }
+            if (localStorage.getItem("lang") == "tw") {
+                this.mockdata = mockdata.eventList;
+            } else this.mockdata = mockdataEn.eventList;
+            this.MyName = this.$t("studentWeb.eventView-title");
+            this.$emit("onNavNo", this.MyNo);
+            this.$emit("onNavName", this.MyName);
+            this.$store.commit("ToggleSidebar", true);
+            this.$store.commit("SaveNowPage", '活動');
+            this.setPaperData()
+        },
+        methods: {
+            setPaperData() {
+                let data = {
+                    scope: "school",
+                    blob: "/paper/主观题测试"
+                }
+                let info = this.$evTools.getFullPaper(data)
+                console.log('学生端试卷信息')
+                console.log(info)
+            },
+            scrollList() {
+                //當從通知操作進行捲動時,將篩選條件清空
+                this.selectedEventStatusNow = "所有活動狀態";
+                this.eventTypeCheckers = [];
+                console.log("收到從下一個按鈕切換項目");
+
+                let targetItem = document.getElementById(
+                    `event${this.$store.getters.getItemTitle.eventID}`
+                );
+                let scrollList = document.querySelectorAll(".event-list .list-block")[0];
+
+                if (scrollList !== undefined) {
+                    let scrollvalue = 0;
+                    if (targetItem.offsetTop > 600) {
+                        scrollvalue = targetItem.offsetTop - 128;
+                    } else if (targetItem.offsetTop < 600) {
+                        scrollvalue = -scrollList.scrollHeight;
+                    }
+                    console.log(scrollList.scrollHeight, scrollvalue);
+                    scrollList.scrollTo({
+                        top: scrollvalue,
+                        behavior: "smooth",
+                    });
+                }
+            },
+            gotoNextItem() {
+                let nextItems = [];
 
-      let targetItem = document.getElementById(
-        `event${this.$store.getters.getItemTitle.eventID}`
-      );
-      let scrollList = document.querySelectorAll(".event-list .list-block")[0];
+                for (let i = 0; i <= this.mockdata.length; i++) {
+                    if (this.$store.getters.getItemTitle == this.mockdata[i]) {
+                        console.log("目前:" + i, this.mockdata[i].eventName);
+                        let j = i + 1;
+                        if (
+                            j < this.mockdata.length &&
+                            this.eventPageType.includes(this.mockdata[j].eventType)
+                        ) {
+                            nextItems.push(this.mockdata[j]);
+                        } else {
+                            for (let j = i + 1; j < this.mockdata.length; j++) {
+                                if (this.eventPageType.includes(this.mockdata[j].eventType)) {
+                                    nextItems.push(this.mockdata[j]);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (nextItems != "") {
+                    if (
+                        nextItems[0].eventName ==
+                        this.mockdata[this.mockdata.length - 1].eventName
+                    ) {
+                        console.log("沒有下一個!");
+                    }
+                    console.log("下一個:" + nextItems[0].eventName);
+                    this.$store.commit("ChangeItemName", nextItems[0]);
+                    this.$router.push("/studentWeb/eventView#" + nextItems[0].eventID);
+                    this.scrollList();
+                    this.$store.commit("SetisFromInfoPoptpScroll", true);
+                    //重置預習活動
+                    this.$store.commit("PassPhaseTest", 0);
+                    this.$store.commit("ChangeCurrentPhase", 0);
+                    this.$store.commit("ChangeCurrentSelectedReadingName", 1);
+                    this.$store.commit("ToggleSentCurrentphase", false);
+                    this.$store.commit("SetCurrentQuestionNo", 0);
+                    this.$store.commit("SetTrytestCount", [0, 0, 0]);
+                } else {
+                    this.$store.commit("ChangeItemName", this.mockdata[0]);
+                    this.scrollList();
+                    this.$store.commit("SetisFromInfoPoptpScroll", true);
+                }
+            },
+        },
+    };
+</script>
+<style>
+      .eventContentArea-view {
+          float: right;
+          width: 75%;
+          /*height: 100vh;
+    overflow: scroll;*/
+      }
 
-      if (scrollList !== undefined) {
-        let scrollvalue = 0;
-        if (targetItem.offsetTop > 600) {
-          scrollvalue = targetItem.offsetTop - 128;
-        } else if (targetItem.offsetTop < 600) {
-          scrollvalue = -scrollList.scrollHeight;
-        }
-        console.log(scrollList.scrollHeight, scrollvalue);
-        scrollList.scrollTo({
-          top: scrollvalue,
-          behavior: "smooth",
-        });
+      .eventContentArea-Span {
+          padding: 1% 15%;
+          width: 100%;
       }
-    },
-    gotoNextItem() {
-      let nextItems = [];
 
-      for (let i = 0; i <= this.mockdata.length; i++) {
-        if (this.$store.getters.getItemTitle == this.mockdata[i]) {
-          console.log("目前:" + i, this.mockdata[i].eventName);
-          let j = i + 1;
-          if (
-            j < this.mockdata.length &&
-            this.eventPageType.includes(this.mockdata[j].eventType)
-          ) {
-            nextItems.push(this.mockdata[j]);
-          } else {
-            for (let j = i + 1; j < this.mockdata.length; j++) {
-              if (this.eventPageType.includes(this.mockdata[j].eventType)) {
-                nextItems.push(this.mockdata[j]);
-              }
-            }
-          }
-        }
+      .eventContentArea-left {
+          width: 80%;
+          float: left;
+          padding: 1% 7%;
+          transition: 0s;
       }
 
-      if (nextItems != "") {
-        if (
-          nextItems[0].eventName ==
-          this.mockdata[this.mockdata.length - 1].eventName
-        ) {
-          console.log("沒有下一個!");
-        }
-        console.log("下一個:" + nextItems[0].eventName);
-        this.$store.commit("ChangeItemName", nextItems[0]);
-          this.$router.push("/studentWeb/eventView#" + nextItems[0].eventID);
-        this.scrollList();
-        this.$store.commit("SetisFromInfoPoptpScroll", true);
-        //重置預習活動
-        this.$store.commit("PassPhaseTest", 0);
-        this.$store.commit("ChangeCurrentPhase", 0);
-        this.$store.commit("ChangeCurrentSelectedReadingName", 1);
-        this.$store.commit("ToggleSentCurrentphase", false);
-        this.$store.commit("SetCurrentQuestionNo", 0);
-        this.$store.commit("SetTrytestCount", [0, 0, 0]);
-      } else {
-        this.$store.commit("ChangeItemName", this.mockdata[0]);
-        this.scrollList();
-        this.$store.commit("SetisFromInfoPoptpScroll", true);
+      .nextItemBtn {
+          position: fixed;
+          bottom: 4%;
+          right: 3%;
+          background-color: #d8d8d8;
+          color: #515a6e;
+          z-index: 3;
+          padding: 7px;
+          cursor: pointer;
+          border-radius: 3px;
+          font-weight: bolder;
       }
-    },
-  },
-};
-</script>
-<style>
-.eventContentArea-view {
-  float: right;
-  width: 75%;
-  /*height: 100vh;
-  overflow: scroll;*/
-}
 
-.eventContentArea-Span {
-  padding: 1% 15%;
-  width: 100%;
-  
-}
-.eventContentArea-left {
-  width: 80%;
-  float: left;
-  padding: 1% 7%;
-  transition: 0s;
-}
-.nextItemBtn {
-  position: fixed;
-  bottom: 4%;
-  right: 3%;
-  background-color: #d8d8d8;
-  color: #515a6e;
-  z-index: 3;
-  padding: 7px;
-  cursor: pointer;
-  border-radius: 3px;
-  font-weight: bolder;
-}
-.nextItemBtn:hover {
-  background-color: rgb(100, 174, 22) !important;
-  color: white;
-  border: none;
-}
+          .nextItemBtn:hover {
+              background-color: rgb(100, 174, 22) !important;
+              color: white;
+              border: none;
+          }
 </style>

+ 132 - 146
TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue

@@ -3,166 +3,148 @@
     <Row :gutter="30" v-if="spanCharts == false">
       <i-col :xs="0" :sm="0" :md="0" :lg="1"></i-col>
       <i-col :xs="24" :sm="24" :md="12" :lg="7">
-        <Card :bordered="true" class="calenderCard">
-          <p slot="title">
-            <svg-icon class="titleIcon" icon-class="calander" />
-            <span class="title">{{ $t("studentWeb.calenderCardTitle") }}</span>
-          </p>
-          <router-link to="/SchoolCalender">
-            <div>
-              <div class="title-rect" />
-              <p class="title-rect-name">{{ $t("studentWeb.recentClass") }}</p>
-              <p class="classtitle">{{ $t("studentWeb.defaultRecentClass") }}</p>
-              <p class="time">{{ $t("studentWeb.defaultClassTime") }}</p>
-              <p class="place">{{ $t("studentWeb.defaultClassPlace") }}</p>
-            </div>
-          </router-link>
+          <Card :bordered="true" class="calenderCard" @click.native="noData">
+              <p slot="title">
+                  <svg-icon class="titleIcon" icon-class="calander" />
+                  <span class="title">{{ $t("studentWeb.calenderCardTitle") }}</span>
+              </p>
 
-          <div class="todaydayline">
-            <div class="todaydaylinewraptitle">
-              <div class="title-rect" />
-              <router-link to="/SchoolCalender">
-                <p class="title-rect-name">
-                  {{ $t("studentWeb.todaydeadlineList") }}
-                  <Icon type="ios-arrow-forward" />
-                </p>
-              </router-link>
-            </div>
-            <div class="todaydaylineList">
-              <div
-                class="list-block"
-                :style="{ 'max-height': todaydaylineListHeight + 'px' }">
-                <li
-                  :id="`tditem${index}`"
-                  class="list-item"
-                  v-for="(item, index) in mockdata"
-                  :key="index"
-                  v-show="eventPageType.includes(item.eventType) == true &&item.isDone == false && index < 8 " @click="sentSelectedEventTitle(item)" >
-                  <router-link :to="`/studentWeb/eventView#${item.eventID}`">
-                    <ul>
-                      <li class="list-item-icon">
-                        <svg-icon
-                          v-if="item.eventType == '作業'"
-                          icon-class="doc"
-                        />
-                        <svg-icon
-                          v-if="item.eventType == '課前預習'"
-                          icon-class="selflearninginTime"
-                        />
-                        <svg-icon
-                          v-if="item.eventType == '評量'"
-                          icon-class="test"
-                          class="reset-testIcon"
-                        />
-                        <svg-icon
-                          v-if="item.eventType == '投票'"
-                          icon-class="vote"
-                        />
-                        <svg-icon
-                          v-if="item.eventType == '問卷'"
-                          icon-class="quesnaire"
-                        />
-                      </li>
-                      <li class="list-item-info">
-                        <p
-                          class="list-item-title"
-                          :class="{
+              <div>
+                  <div class="title-rect" />
+                  <p class="title-rect-name">{{ $t("studentWeb.recentClass") }}</p>
+                  <p class="classtitle">{{ $t("studentWeb.defaultRecentClass") }}</p>
+                  <p class="time">{{ $t("studentWeb.defaultClassTime") }}</p>
+                  <p class="place">{{ $t("studentWeb.defaultClassPlace") }}</p>
+              </div>
+              <!--<router-link to="/SchoolCalender">
+              </router-link>-->
+
+              <div class="todaydayline">
+                  <div class="todaydaylinewraptitle">
+                      <div class="title-rect" />
+
+                      <p class="title-rect-name">
+                          {{ $t("studentWeb.todaydeadlineList") }}
+                          <Icon type="ios-arrow-forward" />
+                      </p>
+                      <!--<router-link to="/SchoolCalender">
+            </router-link>-->
+                  </div>
+                  <div class="todaydaylineList">
+                      <div class="list-block"
+                           :style="{ 'max-height': todaydaylineListHeight + 'px' }">
+                          <li :id="`tditem${index}`"
+                              class="list-item"
+                              v-for="(item, index) in mockdata"
+                              :key="index"
+                              v-show="eventPageType.includes(item.eventType) == true &&item.isDone == false && index < 8 " >
+                              <ul>
+                                  <li class="list-item-icon">
+                                      <svg-icon v-if="item.eventType == '作業'"
+                                                icon-class="doc" />
+                                      <svg-icon v-if="item.eventType == '課前預習'"
+                                                icon-class="selflearninginTime" />
+                                      <svg-icon v-if="item.eventType == '評量'"
+                                                icon-class="test"
+                                                class="reset-testIcon" />
+                                      <svg-icon v-if="item.eventType == '投票'"
+                                                icon-class="vote" />
+                                      <svg-icon v-if="item.eventType == '問卷'"
+                                                icon-class="quesnaire" />
+                                  </li>
+                                  <li class="list-item-info">
+                                      <p class="list-item-title"
+                                         :class="{
                             'list-item-titleEn': getCurrentLang() == 'en',
-                          }"
-                        >
-                          <span
-                            class="list-item-typeMark"
-                            v-if="getCurrentLang() == 'tw'"
-                            >{{ item.eventType }}</span
-                          >
-                          <span
-                            class="list-item-typeMark"
-                            v-if="getCurrentLang() == 'en'"
-                            >{{ transTypetoEn(item.eventType) }}</span
-                          >
+                          }">
+                                          <span class="list-item-typeMark"
+                                                v-if="getCurrentLang() == 'tw'">{{ item.eventType }}</span>
+                                          <span class="list-item-typeMark"
+                                                v-if="getCurrentLang() == 'en'">{{ transTypetoEn(item.eventType) }}</span>
+
+                                          <span>{{ item.eventName }}</span>
+                                      </p>
+                                      <p class="list-item-time">
+                                          {{ $t("studentWeb.endsTodayTime") }}
+                                      </p>
+                                  </li>
+                                  <li class="list-item-unDone"></li>
+                              </ul>
+                              <!--<router-link :to="`/studentWeb/eventView#${item.eventID}`">
 
-                          <span>{{ item.eventName }}</span>
-                        </p>
-                        <p class="list-item-time">
-                          {{ $t("studentWeb.endsTodayTime") }}
-                        </p>
-                      </li>
-                      <li class="list-item-unDone"></li>
-                    </ul>
-                  </router-link>
-                </li>
+                    </router-link>-->
+                          </li>
+                      </div>
+                  </div>
               </div>
-            </div>
-          </div>
-        </Card>
-        <br />
-        <router-link to="/courseList">
-          <Card style="overflow: hidden">
-            <h3 style="color: #575757; font-weight: 700">
-              <svg-icon class="titleIcon" icon-class="course" />
-              {{ $t("studentWeb.coursesCardTitle") }}
-              <Icon type="ios-arrow-forward" />
-            </h3>
+          </Card>
+          <br />
+          <!--<router-link to="/courseList">
+
+          </router-link>-->
+          <Card style="overflow: hidden" @click.native="noData">
+              <h3 style="color: #575757; font-weight: 700">
+                  <svg-icon class="titleIcon" icon-class="course" />
+                  {{ $t("studentWeb.coursesCardTitle") }}
+                  <Icon type="ios-arrow-forward" />
+              </h3>
 
-            <p class="course-new">{{ $t("studentWeb.newAddCourse") }}</p>
+              <p class="course-new">{{ $t("studentWeb.newAddCourse") }}</p>
           </Card>
-        </router-link>
 
-        <br />
+          <br />
       </i-col>
       <i-col :xs="24" :sm="24" :md="12" :lg="8">
         <MissionListCard />
       </i-col>
       <i-col :xs="24" :sm="24" :md="12" :lg="7">
-        <Card :bordered="true">
-          <div class="spanAllchartBtn" @click="setSpanCharts()">
-            <svg-icon class="spanAllchartIcon" icon-class="dimensions" />
-          </div>
-          <ChartCarousel />
-        </Card>
-        <br />
-        <router-link to="/studentWeb/eventView">
-          <Card class="bar-card">
-            <h3 style="color: #575757; font-weight: 700">
-              <svg-icon class="titleIcon" icon-class="target" />
-              {{ $t("studentWeb.myProgressBar.tasksCompletionRate") }}
-            </h3>
+          <Card :bordered="true">
+              <div class="spanAllchartBtn" @click="setSpanCharts()">
+                  <svg-icon class="spanAllchartIcon" icon-class="dimensions" />
+              </div>
+              <ChartCarousel />
+          </Card>
+          <br />
+          <Card class="bar-card" @click.native="noData">
+              <h3 style="color: #575757; font-weight: 700">
+                  <svg-icon class="titleIcon" icon-class="target" />
+                  {{ $t("studentWeb.myProgressBar.tasksCompletionRate") }}
+              </h3>
 
-            <div class="myProgressBar">
-              <span class="myTestProgressNum">
-                {{ MyEventData }}
-                <span style="font-size: 20px">&nbsp;%</span>
-              </span>
-              <div
-                class="myTestProgressContent"
-                :style="{ width: MyEventData + '%' }"
-                style="background: #00ad6c"
-              ></div>
-              <div class="myTestProgress"></div>
-            </div>
+              <div class="myProgressBar">
+                  <span class="myTestProgressNum">
+                      {{ MyEventData }}
+                      <span style="font-size: 20px">&nbsp;%</span>
+                  </span>
+                  <div class="myTestProgressContent"
+                       :style="{ width: MyEventData + '%' }"
+                       style="background: #00ad6c"></div>
+                  <div class="myTestProgress"></div>
+              </div>
           </Card>
-        </router-link>
-        <br />
-        <router-link to="/studentWeb/studyView">
-          <Card class="bar-card">
-            <h3 style="color: #575757; font-weight: 700">
-              <svg-icon class="titleIcon studyIcon" icon-class="note" />
-              {{ $t("studentWeb.myProgressBar.selfStudyClickRate") }}
-            </h3>
-            <div class="myProgressBar">
-              <span class="myTestProgressNum">
-                {{ 22 }}
-                <span style="font-size: 20px">&nbsp;%</span>
-              </span>
-              <div
-                class="myTestProgressContent"
-                :style="{ width: 22 + '%' }"
-                style="background: linear-gradient(90deg, #ffa400, #fa6400)"
-              ></div>
-              <div class="myTestProgress"></div>
-            </div>
+          <!--<router-link to="/studentWeb/eventView">
+
+          </router-link>-->
+          <br />
+          <Card class="bar-card" @click.native="noData">
+              <h3 style="color: #575757; font-weight: 700">
+                  <svg-icon class="titleIcon studyIcon" icon-class="note" />
+                  {{ $t("studentWeb.myProgressBar.selfStudyClickRate") }}
+              </h3>
+              <div class="myProgressBar">
+                  <span class="myTestProgressNum">
+                      {{ 22 }}
+                      <span style="font-size: 20px">&nbsp;%</span>
+                  </span>
+                  <div class="myTestProgressContent"
+                       :style="{ width: 22 + '%' }"
+                       style="background: linear-gradient(90deg, #ffa400, #fa6400)"></div>
+                  <div class="myTestProgress"></div>
+              </div>
           </Card>
-        </router-link>
+          <!--<router-link to="/studentWeb/studyView">
+
+    <!--</router-link>-->
       </i-col>
     </Row>
     <Row :gutter="30" v-if="spanCharts == true">
@@ -244,7 +226,11 @@ export default {
     };
   },
 
-  methods: {
+        methods: {
+            noData() {
+                this.$Message.warning('此功能暂未开放!')
+
+            },
     getCurrentLang() {
       return localStorage.getItem("lang");
     },

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

@@ -27,7 +27,7 @@
           <svg-icon icon-class="selflearning" class="tabIcon2" />
         </router-link>
       </span>
-      <span class="menu-item" :class="{'menu-item-selected':MyNo==3}">
+      <!--<span class="menu-item" :class="{'menu-item-selected':MyNo==3}">
         <router-link to="/studentWeb/studyView">
           <svg-icon icon-class="note" class="tabIcon1" />
         </router-link>
@@ -41,7 +41,7 @@
         <router-link to="/studentWeb/InformView" >
           <svg-icon icon-class="bell" class="tabIcon1" />
         </router-link>
-      </span>
+      </span>-->
 
       <span class="menu-item profile-dropdown">
         <Avatar
@@ -49,7 +49,7 @@
         />
         <div id="profile-pop">
             <span class="profile-pop-triangle"></span>
-            <h5 class="profileName">Nancy Chen (ST11096)</h5>
+            <h5 class="profileName">Nancy  (ST11096)</h5>
             <router-link to="/setting">
               <li class="profile-pop-item">
                 <svg-icon icon-class="setting" class="profile-pop-itemIcon1" />個人設定

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

@@ -16,6 +16,7 @@ import teachermgmt from './teachermgmt'
 import regist from './regist'
 import forgotPW from './forgotPW'
 import studentWeb from './studentWeb'
+import settings from './settings'
 
 export default {
   schoolBaseInfo,
@@ -36,6 +37,7 @@ export default {
   regist,
   forgotPW,
   studentWeb,
+  settings,
   test: 'test',
   formConfigP: {
     input: 'Please Enter ',

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

@@ -47,7 +47,7 @@ export default {
         text1: 'IES5智慧服务平台'
     },
     modal: {
-        title: '选择身',
+        title: '选择身',
         btn1: '老师',
         btn2: '学生'
     }

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

@@ -0,0 +1,5 @@
+export default {
+    setting_title1: 'School Manage',
+	setting_title2: 'Normal Settings'
+
+}

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

@@ -16,6 +16,7 @@ import teachermgmt from './teachermgmt'
 import regist from './regist'
 import forgotPW from './forgotPW'
 import studentWeb from './studentWeb'
+import settings from './settings'
 
 export default {
   schoolBaseInfo,
@@ -36,6 +37,7 @@ export default {
   regist,
   forgotPW,
   studentWeb,
+  settings,
   test: '测试',
   formConfigP: {
     input: '请输入',

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

@@ -47,7 +47,7 @@ export default {
         text1: 'IES5智慧服务平台'
     },
     modal: {
-        title: '选择身',
+        title: '选择身',
         btn1: '老师',
         btn2: '学生'
     }

+ 5 - 0
TEAMModelOS/ClientApp/src/locale/lang/zh-CN/settings.js

@@ -0,0 +1,5 @@
+export default {
+    setting_title1: '学校管理',
+	setting_title2: '一般设置'
+
+}

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

@@ -16,6 +16,7 @@ import teachermgmt from './teachermgmt'
 import regist from './regist'
 import forgotPW from './forgotPW'
 import studentWeb from './studentWeb'
+import settings from './settings'
 
 export default {
   schoolBaseInfo,
@@ -36,6 +37,7 @@ export default {
   regist,
   forgotPW,
   studentWeb,
+  settings,
   test: '測試',
   formConfigP: {
     input: '請輸入',

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

@@ -0,0 +1,5 @@
+export default {
+    setting_title1: '學校管理',
+	setting_title2: '壹般設置'
+
+}

+ 4 - 1
TEAMModelOS/ClientApp/src/static/Global.js

@@ -12,6 +12,8 @@ const CONTENT_TYPES = {
 const PRIVATE_SPACE = 1024 * 1024 * 1024 * 1
 //学校Blob空间
 const SCHOOL_SPACE = 1024 * 1024 * 1024 * 10
+//尚未归属学校的默认学校编码
+const DEFAULT_SCHOOL_CODE = 'SYSTEM_NO_SCHOOL'
 
 //系统默认考试类型
 const EXAM_TYPE = [
@@ -33,5 +35,6 @@ export default {
     CONTENT_TYPES,
     PRIVATE_SPACE,
     SCHOOL_SPACE,
-    EXAM_TYPE
+    EXAM_TYPE,
+    DEFAULT_SCHOOL_CODE
 }

+ 8 - 5
TEAMModelOS/ClientApp/src/store/index.js

@@ -12,6 +12,7 @@ import teachers from './module/teachers'
 import studentWeb from './module/studentWeb'
 import scboard from './module/scboard'
 import serviceDriveAuth from './module/serviceDriveAuth'
+import GLOBAL from '@/static/Global.js'
 Vue.use(Vuex)
 
 // TYPES
@@ -31,13 +32,14 @@ const mutations = {
         state.schoolSas = obj
     },
     setUserInfo(state, obj) {
-        if (!obj.schoolCode) { // 如果账号暂未归户到学校,schoolCode为空,但是很多API schoolCode为必传,所以这里先暂时为没有归户的账号设定一个默认schoolcode
-            obj.schoolCode = 'SYSTEM_NO_SCHOOL'
-        }
+		console.log(obj)
+        obj.schoolCode = obj.schoolCode || GLOBAL.DEFAULT_SCHOOL_CODE
+        obj.hasSchool = obj.schoolCode !== GLOBAL.DEFAULT_SCHOOL_CODE
 		state.userInfo = obj
 	},
 	setSchoolCode(state,obj){
-		state.userInfo.schoolCode = obj
+		state.userInfo.schoolCode = obj || GLOBAL.DEFAULT_SCHOOL_CODE
+		state.userInfo.hasSchool = obj !== GLOBAL.DEFAULT_SCHOOL_CODE
 	}
 }
 
@@ -60,7 +62,8 @@ export default new Vuex.Store({
         userInfo: {
             TEAMModelId: '',
             name: '',
-            schoolCode: ''
+            schoolCode: '',
+			hasSchool:false
         }
     },
     modules: {

+ 19 - 5
TEAMModelOS/ClientApp/src/store/module/studentWeb.js

@@ -18,9 +18,12 @@ export default {
       state: {
         lang: "zh-TW", //存放
         sideBarIsOpen: true, //存放側邊欄是否開合
-    
-        //存放活動相關的狀態
-        Item: "",
+        userInfo: {
+            name: '',
+            studentId: '',
+            roles: []
+        },
+        Item: "", //存放活動相關的狀態
         tempfinishedItem: [], //用來暫存目前完成的項目ID
         tempfinishedItemtime: [],
         CountedIsDonePercent: myMockData.initialfinishResult, //存放活動完成度值,初始值先從Api抓資料,後續透過vuex抓狀態變化
@@ -84,7 +87,15 @@ export default {
       },
     
       //定義方法
-      mutations: {
+    mutations: {
+        //保存学生基本信息
+        setUserInfo(state, data) {
+            if (data.name !== "") {
+                state.userInfo.name = data.name // 学生姓名
+                state.userInfo.studentId = data.sub // 学生ID
+                state.userInfo.roles = data.roles // 學生是否拥有不同权限
+            }
+        },
         searchCourseIDforAdd(state, cIDadd) {
           if (
             state.courseIDs.includes(cIDadd) == true &&
@@ -286,7 +297,10 @@ export default {
         },
       },
       getters: {
-        getSidebarisOpen: (state) => {
+          getUserInfo: (state) => {
+              return state.userInfo;
+          },
+          getSidebarisOpen: (state) => {
           return state.sideBarIsOpen;
         },
         getItemTitle: (state) => {

+ 1 - 0
TEAMModelOS/ClientApp/src/store/module/totalAnalysis.js

@@ -173,6 +173,7 @@ export default {
             if (data) {
                 localStorage.setItem('cur_s', data)
                 state.currentSubject = data
+                state.examPaper = null
 				state.scatterData = null
 				state.knowledgeData = null
 				state.exerciseData = null

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

@@ -104,16 +104,12 @@ export default {
 	getFullItem(list){
 		return new Promise(async (resolve,reject) => {
 			let promiseArr = []
-			let schoolHost = JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri
-			let privateHost = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri
-			let schoolSas = await $tools.getSchoolSas()
-			let privateSas = await $tools.getPrivateSas()
 			for(let i=0; i<list.length; i++){
 				promiseArr.push(new Promise(async (r,j) => {
 					if(list[i].blob){
-						const blobHost = list[i].scope === 'school' ?  schoolHost :  privateHost
+						const blobHost = list[i].scope === 'school' ?  JSON.parse(decodeURIComponent(localStorage.school_profile, "utf-8")).blob_uri :  JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8")).blob_uri
 						// 根据试题的Blob地址 去读取JSON文件
-						let sasString = list[i].scope === 'school' ?  schoolSas : privateSas
+						let sasString = list[i].scope === 'school' ?  await $tools.getSchoolSas() : await $tools.getPrivateSas()
 						let jsonInfo = await $tools.getFile(blobHost + list[i].blob + sasString.sas)
 						let jsonData = JSON.parse(jsonInfo)
 						// 调整渲染试题数据结构

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

@@ -153,6 +153,18 @@ export default {
 		'table', // 表格
 		'undo', // 撤销
 	],
+	wangEditorMenuSimple: [
+		'head', // 标题
+		'bold', // 粗体
+		'fontSize', // 字号
+		'fontName', // 字体
+		'italic', // 斜体
+		'underline', // 下划线
+		'strikeThrough', // 删除线
+		'foreColor', // 文字颜色
+		'justify', // 对齐方式
+		'table', // 表格
+	],
 	// 生成随机UUID工具
 	randomId: function() {
 		return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
@@ -371,7 +383,7 @@ export default {
 	 */
 	getSchoolSas() {
 		return new Promise((r, j) => {
-			if (!store.state.schoolSas || checkSas(store.state.schoolSas.timeout)) {
+			if (!store.state.schoolSas || checkSas(store.state.schoolSas.timeout)  || store.state.schoolSas.name !== store.state.userInfo.schoolCode) {
 				$api.uploadFile.blobSasRCW({
 					name: store.state.userInfo.schoolCode,
 					role: 'school'

+ 33 - 12
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -1,23 +1,19 @@
 <template>
     <div id="main">
+        <Loading v-if="isLoading" :top="300"></Loading>
         <BaseLayout>
             <!-- 头部右侧个人中心部分 -->
             <div class="header-right-box fl-around" slot="header-content">
-                <Icon custom="iconfont icon-home" @click="toHome"/>
+                <Icon custom="iconfont icon-home" :color="routerName == 'homePage' ? '#1CC0F3':'#d0d0d0'" @click="toHome"/>
 				<BaseNotification></BaseNotification>
-                <Icon type="ios-settings" @click="toSettings"/>
-				<Icon type="md-help-circle" @click="toFeedback"/>
+                <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>
             </div>
             <div id="content" class="custom-scroll-bar" slot="content">
                 <router-view :key="this.$route.name"></router-view>
             </div>
         </BaseLayout>
-		<Modal v-model="isShowMock" title="作答数据模拟生成" width="400px" class="related-point-modal" style="z-index:99999">
-			<BaseMock @onSuccess="isShowMock = false"></BaseMock>
-			<div slot="footer" style="display: none;">
-			</div>
-		</Modal>
     </div>
 </template>
 
@@ -32,13 +28,24 @@
         data() {
             return {
 				isShowMock:false,
-                isOpenDrawer: false
+                isOpenDrawer: false,
+                routerName: '',
+                isLoading: false
             }
         },
         created() {
             //刷新重置vuex
-            let user = JSON.parse(decodeURIComponent(localStorage.userInfo, "utf-8"));
-            let user_profile = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
+            console.log('进入大云...')
+            console.log(this.$store)
+            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,
@@ -49,7 +56,7 @@
                 this.$store.commit('setUserInfo', {
                     TEAMModelId: user.id,
                     name: user.name,
-                    schoolCode: 'SYSTEM_NO_SCHOOL'
+                    schoolCode: this.$GLOBAL.DEFAULT_SCHOOL_CODE
                 })
             }
         },
@@ -96,6 +103,20 @@
             }
         },
         mounted() {
+			this.$EventBus.$on('onGlobalLoading', val => {
+				this.isLoading = val
+			})
+        },
+        watch: {
+            $route: {
+                handler(val, oldval) {
+                    this.routerName = val.name
+                },
+                // 深度观察监听
+                deep: true,
+                //立即执行
+                immediate: true
+            }
         }
     }
 </script>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue

@@ -41,7 +41,7 @@
                         <span>{{row.groupName ? row.groupName : '未分组'}}</span>
                     </template>
                 </Table>
-                <EmptyData textContent="暂无您管理的班级" :top="150"></EmptyData>
+                <EmptyData v-else textContent="暂无您管理的班级" :top="150"></EmptyData>
             </vuescroll>
         </div>
         <div class="mgt-class-body dark-iview-table animated fadeIn dark-iview-input disabled-iview-input" id="table-wrap" v-else>

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

@@ -8,7 +8,7 @@
 				<RadioGroup v-model="filterOrigin" type="button" @on-change="filterOriginChange">
 					<Radio :label="schoolCode" v-if="isShowSchoolBank">校本题库</Radio>
 					<Radio :label="userId">个人题库</Radio>
-					<Radio :label="schoolCode" v-if="!isShowSchoolBank">校本题库</Radio>
+					<Radio :label="schoolCode" v-if="!isShowSchoolBank && hasSchool">校本题库</Radio>
 				</RadioGroup>
 			</div>
 			<div class="filter-item" v-show="isShowSchoolBank">
@@ -77,11 +77,11 @@
 		<!-- 筛选部分结束 -->
 		<!-- 题目列表部分 -->
 		<div v-if="exerciseList.length === 0" class="no-data-text">
-			<img src="../../../assets/icon/no_data.svg" width="120" />
+			<img src="@/assets/icon/no_data_evaluation.png" width="120" />
 			<span style="margin-top:15px;color:#808080">暂无数据</span>
 		</div>
 		<div class="content-wrap" ref="mathJaxContainer" v-else>
-			<Loading :top="100" v-show="dataLoading" type="1" hideMask></Loading>
+			<Loading :top="100" v-show="dataLoading" hideMask></Loading>
 			<div class="exercise-item" v-for="(item,index) of exerciseList" :key="index" @click="onQuestionToggle(index,item.id,$event)">
 				<!-- 题干部分 -->
 				<div class="item-question">
@@ -252,7 +252,7 @@
 				curAudioSrc: "",
 				curAudioName: "",
 				curVideoSrc: "",
-				curVideoName: ""
+				curVideoName: "",
 			}
 		},
 		created() {
@@ -379,7 +379,6 @@
 				let that = this
 				this.$api.newEvaluation.FindExerciseList(data).then(async res => {
 					let list = res.items
-					this.originData = res.items
 					/* 获取试题总数 */
 					this.totalNum = res.items.length
 					/* 查找当前页面所有知识点ID换名称 */
@@ -468,24 +467,18 @@
 			 */
 			onQuestionToggle(index, id, e) {
 				let curClassName = e.target.className
+				console.log(curClassName)
 				if(curClassName === 'item-tools' || curClassName === 'richText-video' || curClassName === 'richText-audio') return
 				e.stopPropagation()
 				let listIndex = this.collapseList.indexOf(index)
 				if (listIndex > -1) {
 					this.collapseList.splice(listIndex, 1)
 				} else {
-					/** 如果是首次展开 则需要获取详细数据 否则直接展开 */
-					// if (!this.exerciseList[index].answer.length) {
-					// 	this.collapseList.push(index)
-					// 	this.pageScrollTo(e.target.offsetTop + 320) // 490就是 content-wrap 距离顶部高度
-					// } else {
-					// 	this.collapseList.push(index)
-					// 	this.pageScrollTo(e.target.offsetTop + 320) // 490就是 content-wrap 距离顶部高度
-					// }
-					
 					this.collapseList.push(index)
-					this.pageScrollTo(e.target.offsetTop + 320)
-
+					let exerciseItemDom =  e.path.filter(i => i.className === 'exercise-item')
+					if(exerciseItemDom.length){
+						this.pageScrollTo(exerciseItemDom[0].offsetTop + 280)
+					}
 				}
 
 				this.$emit('toggleChange', this.collapseList)
@@ -800,6 +793,9 @@
 			},
 			curScope(){
 				return this.filterOrigin === this.$store.state.userInfo.schoolCode ? 'school' : 'private'
+			},
+			hasSchool(){
+				return this.$store.state.userInfo.hasSchool
 			}
 		}
 	}

+ 14 - 4
TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.vue

@@ -24,11 +24,11 @@
                     <!-- <span class="info-item">难度系数:<span class="info-bold">{{ paper.item ? handleDiffCalc(paper.item) : 0 }}</span></span> -->
                 </div>
                 <div class="paper-item-tools">
-                    <span class="paper-item-tools-edit" @click="goToPaper(paper)"  v-if="$access.can('admin.*|Paper_Edit')">
+                    <span class="paper-item-tools-edit" @click="goToPaper(paper)"  v-if="$access.can('admin.*|teacher.*|Paper_Edit')">
 						<Icon type="ios-create" />
 						<span>编辑</span>
 					</span>
-                    <span class="paper-item-tools-delete"  @click.stop="onDeletePaper(paper)"  v-if="$access.can('admin.*|Paper_Edit')">
+                    <span class="paper-item-tools-delete"  @click.stop="onDeletePaper(paper)"  v-if="$access.can('admin.*|teacher.*|Paper_Edit')">
 						<Icon type="md-trash" />
 						<span>删除</span>
 					</span>
@@ -73,6 +73,7 @@
                 subjectList: [],
                 filterParams: {},
                 findCountParams: {},
+				originList:[],
                 schoolInfo: {},
                 filterSort: 'createTime',
                 paperInfo: {
@@ -84,6 +85,7 @@
         },
         created() {
             // this.getPaperList()
+			// this.doFilter()
 
         },
         methods: {
@@ -109,7 +111,8 @@
 
                 //this.gradeList = this.periodList.filter(item => item.periodCode = filterParams.periodCode[0])[0].grades
                 //this.subjectList = this.periodList.filter(item => item.periodCode = filterParams.periodCode[0])[0].subjects
-                this.pageChange(1)
+                // this.pageChange(1)
+				this.doFilter()
             },
 
             /** 获取试卷列表 */
@@ -117,6 +120,9 @@
                 let that = this
                 this.$api.learnActivity.FindExamPaper(params).then(async res => {
                     this.paperList = res.papers
+					this.originList = res.papers
+					this.totalNum = res.papers.length
+					this.pageChange(1)
                     setTimeout(() => {
                         that.dataLoading = false
                     }, 1000)
@@ -238,7 +244,11 @@
             */
             pageChange(page) {
                 this.pageNum = page
-                this.doFilter()
+				let start = this.pageSize * (page - 1)
+				let end = this.pageSize * page
+				// 拿到当前页码需要展示的数据
+				this.paperList = this.originList.slice(start, end)
+                // this.doFilter()
             },
 
             /**

+ 10 - 3
TEAMModelOS/ClientApp/src/view/evaluation/bank/index.less

@@ -21,10 +21,17 @@
         }
 
         .import-exercise {
-            font-weight: bold;
-            color: rgb(16, 171, 231);
-            font-size: 16px;
+            font-size: 14px;
             display: flex;
+			
+			.bank-tools-btn{
+				color: #f5f5f5;
+				margin-right: 50px;
+				font-weight: 200;
+				cursor: pointer;
+				display: flex;
+				align-items: center;
+			}
         }
 
         .ivu-icon {

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

@@ -10,9 +10,21 @@
 		</Tabs>
 		<div class="ev-list-operation">
 			<div class="import-exercise common-save-btn">
-				<Button type="text" @click="goCreatePaper" icon="ios-add" v-show="currentTab === 'paper' && $access.can('admin.*|Paper_Add')">新建试卷</Button>
-				<Button type="text" @click="goCreateExercise" icon="ios-add"  v-show="currentTab === 'exercise' && $access.can('admin.*|Exercise_Add')">新建习题</Button>
-				<Button type="text" @click="onHandleToggle" :icon="isAllOpen ? 'ios-arrow-down' : 'ios-arrow-up'"  v-show="currentTab === 'exercise'">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button>
+				<span @click="goCreatePaper" v-show="currentTab === 'paper'" class="bank-tools-btn">
+					<Icon type="md-add" size="16"/>
+					<span>新建试卷</span>
+				</span>
+				<span @click="goCreateExercise" v-show="currentTab === 'exercise'" class="bank-tools-btn">
+					<Icon type="md-add" size="16"/>
+					<span>新建习题</span>
+				</span>
+				<span @click="onHandleToggle" v-show="currentTab === 'exercise'" class="bank-tools-btn">
+					<Icon :type="isAllOpen ? 'ios-arrow-down' : 'ios-arrow-up'" size="16"/>
+					<span>{{ isAllOpen ? '全部折叠' : '全部展开'}}</span>
+				</span>
+				<!-- <Button type="text" @click="goCreatePaper" icon="ios-add" v-show="currentTab === 'paper'">新建试卷</Button>
+				<Button type="text" @click="goCreateExercise" icon="ios-add"  v-show="currentTab === 'exercise'">新建习题</Button>
+				<Button type="text" @click="onHandleToggle" :icon="isAllOpen ? 'ios-arrow-down' : 'ios-arrow-up'"  v-show="currentTab === 'exercise'">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button> -->
 				<!--<BaseImport></BaseImport>-->
 			</div>
 		</div>

+ 11 - 4
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue

@@ -1,5 +1,5 @@
 <template>
-	<div class="child-wrap">
+	<div class="child-wrap" ref="childRef">
 		<div class="child-item" v-for="(item,index) in children" :key="index">
 			<div class="child-item-question">
 				<span class="child-item-question-order">【小题{{ index + 1 }}】</span>
@@ -27,7 +27,7 @@
 					</div>
 					<!-- 其余题型答案 -->
 					<div v-else>
-						<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index">{{answer}}</span>
+						<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index" v-html="answer"></span>
 					</div>
 				</div>
 			</div>
@@ -80,11 +80,18 @@
 		},
 
 		mounted() {
-
+			
 		},
 
 		watch: {
-			
+			children:{
+				handler(n){
+					console.log(n)
+					this.$nextTick(()=>{
+						window.MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
+					})
+				}
+			}
 		}
 
 	}

+ 161 - 80
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue

@@ -10,9 +10,9 @@
 			<div class="list-view" :key="typeIndex" v-for="(typeItem,typeIndex) in listData">
 				<p v-show="viewModel === 'type' && typeItem.list.length" class="type-name">{{ numberConvertToUppercase(getLatestTypeIndex(typeItem.type) + 1) }}
 					: {{ exersicesType[typeItem.type] }}
-					  ({{ typeItem.score || 0 }} 分) </p>
-					
-				<div class="exercise-item" v-for="(item,index) of typeItem.list" :key="index" 
+					({{ typeItem.score || 0 }} 分) </p>
+
+				<div v-for="(item,index) of typeItem.list" :key="index" :class='["exercise-item",isError(item.id) ? "exercise-item-error":""]'
 				 @mouseenter="exerciseMouseover($event)" @mouseleave="exerciseMouseleave($event)">
 
 					<!-- 工具栏部分 -->
@@ -21,6 +21,9 @@
 							<Icon type="ios-list-box-outline" />配分</div> -->
 						<!-- <div class="item-tools-t flex-row-center" v-show="isShowTools" @click.stop="handleToolEdit(typeItem.list,item,index)">
 							<Icon type="ios-brush-outline" />编辑</div> -->
+						<div class="item-tools-t flex-row-center" v-show="isShowTools && noAnswerList.indexOf(item) > -1"
+						 @click.stop="onSetAnswer(item,exerciseList.indexOf(item),typeItem.list,index)">
+							<Icon type="ios-brush-outline" />设置正确答案</div>
 						<div class="item-tools-t flex-row-center" v-show="isShowTools" @click.stop="handleDelete(typeItem.list,item,index)">
 							<Icon type="ios-archive-outline" />删除</div>
 						<div class="item-tools-t flex-row-center" v-show="index != 0 && isShowTools" @click.stop="handleMoveUp(typeItem.list,index)">
@@ -29,6 +32,12 @@
 						 @click.stop="handleMoveDown(typeItem.list,index)">
 							<Icon type="md-arrow-down" />下移</div>
 					</div>
+
+					<div class="item-error-wrap" v-if="errorList.indexOf(item) > -1">
+						<span v-if="isNoAnswer(item)">请为当前客观题设置正确答案!</span>
+						<span v-else>试题题干或选项信息有误,请删除或者重新导入正确文档!</span>
+					</div>
+
 					<div @click="onQuestionToggle(exerciseList.indexOf(item),item.id,$event,typeItem.list)">
 						<!-- 题干部分 -->
 						<div class="item-question">
@@ -52,8 +61,8 @@
 					<div class="item-btn-toggle" @click.stop>
 						<template>
 							<InputNumber :max="item.score + surPlusScore" :min="0" v-model="item.score" style="display: inline-block ;width: 60px;margin-right: 10px;height: 30px;"
-							    @click.stop></InputNumber>
-								<span style="margin-right: 20px;">分</span>
+							 @click.stop></InputNumber>
+							<span style="margin-right: 20px;">分</span>
 							<!-- <span class="item-score" title="设置题目分数" @click.stop="onSetSingleItem(item,index)" v-else>{{ item.score }} 分</span> -->
 						</template>
 						<Icon :type="collapseList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown'" />
@@ -113,13 +122,21 @@
 				</div>
 			</div>
 		</div>
-		
+
 		<!-- 单个试题配分弹框 -->
-<!-- 		<Modal v-model="scoreModal" title="题目配分" @on-ok="onConfirmScore">
-			<InputNumber :max="curItemScore + surPlusScore" :min="0" :step="scoreStep" v-model="curItemScore" @on-change="onScoreChange"></InputNumber>
-			<p>剩余可分配分数:{{ surPlusScore }}</p>
-		</Modal> -->
-		
+		<Modal v-model="answerModal" title="设置答案" @on-ok="onConfirmAnswer">
+			<div v-if="curErrorItem.type === 'single'">
+				<RadioGroup v-model="curErrorSingleAnswer" type="button">
+					<Radio v-for="(option,index) in curErrorItem.option" :key="index" :label="option.code"></Radio>
+				</RadioGroup>
+			</div>
+			<div v-else>
+				<CheckboxGroup v-model="curErrorMulAnswer">
+					<Checkbox v-for="(option,index) in curErrorItem.option" :key="index" :label="option.code" border></Checkbox>
+				</CheckboxGroup>
+			</div>
+		</Modal>
+
 		<!-- 题型配分弹窗 -->
 		<Modal v-model="typeScoreModel" title="题型配分" footer-hide>
 			<span class="type-score-item">试卷总分 : {{ paperInfo.score }}</span>
@@ -159,21 +176,21 @@
 			<p style="color:red;text-align:center;font-weight:bold;margin-top:10px" v-show="getTotalScore(groupTypeList) > paperInfo.score">配分已超试卷总分,请重新分配!</p>
 
 		</Modal>
-		
+
 		<!-- 编辑试题弹窗 -->
-<!-- 		<Modal v-model="editExerciseModal" class-name="edit-exercise-modal" width="1200px" footer-hide title="编辑习题">
+		<!-- 		<Modal v-model="editExerciseModal" class-name="edit-exercise-modal" width="1200px" footer-hide title="编辑习题">
 			<BaseEditExercise :exerciseItem="currentExercise" @onEditSuccess="onEditSuccess" refId="paperEdit" ref="paperEdit"></BaseEditExercise>
 			<div slot="footer">
 				<Button type="success">确认</Button>
 			</div>
 		</Modal> -->
-		
+
 		<!-- 音频播放弹窗 -->
 		<Modal v-model="playAudioModal" width="400" footer-hide @on-visible-change="onAudioModalChange">
 			<div class="modal-header" slot="header">音频播放</div>
 			<BaseAudioPlayer :audioSrc="curAudioSrc" :audioName="curAudioName" ref="audioPlayer"></BaseAudioPlayer>
 		</Modal>
-		
+
 		<!-- 视频播放弹窗 -->
 		<Modal v-model="playVideoModal" width="400" footer-hide @on-visible-change="onVideoModalChange">
 			<div class="modal-header" slot="header">视频播放</div>
@@ -207,11 +224,11 @@
 			return {
 				schoolCode: '',
 				dataLoading: false,
-				curEditItemId:null,
+				curEditItemId: null,
 				exerciseList: [],
 				schoolInfo: {},
 				isShowUploadList: false,
-				multipleRule:1,
+				multipleRule: 1,
 				typeScoreModel: false,
 				setPaperInfoModal: false,
 				editExerciseModal: false,
@@ -239,7 +256,7 @@
 				originData: [],
 				groupList: [],
 				groupTypeList: [],
-				orderList:[],
+				orderList: [],
 				typeList: ['single', 'multiple', 'judge', 'complete', 'subjective', 'compose'],
 				viewModel: 'type',
 				filterParams: {},
@@ -258,10 +275,18 @@
 				curAudioName: "",
 				curVideoSrc: "",
 				curVideoName: "",
-				modifyItems:[],
-				paperInfo:{
-					score:0
-				}
+				modifyItems: [],
+				errorList: [],
+				paperInfo: {
+					score: 0
+				},
+				curErrorItem: {
+					type:''
+				},
+				curErrorSingleAnswer: 'A',
+				curErrorMulAnswer: [],
+				noAnswerList:[],
+				answerModal: false
 			}
 		},
 
@@ -269,21 +294,21 @@
 			//console.log(this.exerciseList)
 		},
 		methods: {
-			
+
 			/* 音频弹窗切换事件 */
 			onAudioModalChange(val) {
 				if (!val) {
 					this.$refs.audioPlayer.onCloseAudio()
 				}
 			},
-			
+
 			/* 音频弹窗切换事件 */
 			onVideoModalChange(val) {
 				if (!val) {
 					// this.$refs.audioPlayer.onCloseAudio()
 				}
 			},
-			
+
 			/* 音频点击播放事件 */
 			onRichTextClick(e) {
 				if (e.srcElement.classList[0] === 'richText-audio') {
@@ -322,16 +347,6 @@
 				this.$emit('toggleChange', this.collapseList)
 			},
 
-			onSetSingleItem(item,index){
-				this.curItemScore = item.score
-				this.curEditItemId = item.id
-			},
-			
-			onItemScoreChange(val){
-				console.log(val)
-			},
-
-
 			/**
 			 * 数字与中文转换
 			 * @param num
@@ -352,22 +367,6 @@
 					}
 				}
 			},
-
-			// 分页操作
-			pageChange(page) {
-				let start = this.pageSize * (page - 1)
-				let end = this.pageSize * page
-				this.pageNum = page
-				this.collapseList = []
-				this.exerciseList = this.originData.slice(start, end)
-				this.pageScrollTo(0)
-			},
-
-			pageSizeChange(val) {
-				this.pageSize = val
-				this.pageChange(1)
-			},
-
 			/**
 			 * 页面滚动事件
 			 * @param scrollDistance 页面滚动距离
@@ -423,11 +422,14 @@
 					onOk: () => {
 						this.$Message.success('删除成功')
 						this.surPlusScore += item.score
-						this.$emit('scoreUpdate',this.surPlusScore)
+						this.$emit('scoreUpdate', this.surPlusScore)
 						arr.splice(index, 1)
 						this.exerciseList.splice(this.exerciseList.indexOf(item), 1)
 						this.$emit('dataUpdate', this.exerciseList)
-						this.$EventBus.$emit('onPaperItemChange',this.exerciseList)
+						this.$EventBus.$emit('onPaperItemChange', this.exerciseList)
+						if(this.errorList.indexOf(item) > -1){
+							this.errorList.splice(this.errorList.indexOf(item),1)
+						}
 					}
 				})
 			},
@@ -446,6 +448,42 @@
 			},
 
 
+			/**
+			 * 给单个试题配分
+			 * @param item
+			 * @param index
+			 */
+			onSetAnswer(item, index, arr, groupIndex) {
+				this.currentExerciseIndex = index
+				this.curIndex = groupIndex
+				this.curTypeItems = arr
+				this.curErrorItem = item
+				this.answerModal = true
+			},
+
+			onConfirmAnswer() {
+				if(this.curErrorItem.type === 'single'){
+					this.curErrorItem.answer = [this.curErrorSingleAnswer]
+					let errorIndex = this.errorList.map(i => i.id).indexOf(this.curErrorItem.id)
+					if(errorIndex > -1){
+						this.errorList.splice(errorIndex,1)
+					}
+				}else{
+					if(this.curErrorMulAnswer.length){
+						this.curErrorItem.answer = this.curErrorMulAnswer
+						let errorIndex = this.errorList.map(i => i.id).indexOf(this.curErrorItem.id)
+						if(errorIndex > -1){
+							this.errorList.splice(errorIndex,1)
+						}
+					}else{
+						this.curErrorItem.answer = []
+						this.errorList.push(this.curErrorItem)
+					}
+				}
+				
+			},
+
+
 			/**
 			 * 给单个试题配分
 			 * @param item
@@ -467,7 +505,7 @@
 			onScoreChange(val) {
 				this.surPlusScore = this.surPlusScore + this.lastScore - val
 				this.lastScore = val
-				this.$emit('scoreUpdate',this.surPlusScore)
+				this.$emit('scoreUpdate', this.surPlusScore)
 
 			},
 
@@ -486,15 +524,15 @@
 				} else {
 					/* 按照题型配分后平均分配给每个子题 */
 					this.groupTypeList.forEach(item => {
-						item.list.forEach((exercise,exerciseIndex) => {
+						item.list.forEach((exercise, exerciseIndex) => {
 							// 先找到原始列表里面的当前题目
 							let listItem = this.exerciseList.filter(item => item.id === exercise.id)[0]
 							// 先判断是否总分除以题目数量能否除尽
 							let remainder = item.score % item.list.length
 							// 如果可以整除 则直接计算
-							if(remainder === 0){
+							if (remainder === 0) {
 								exercise.score = item.score / item.list.length
-							}else{
+							} else {
 								// 如果不能整除 则前面所有取整 最后一题加上余数 即可完成配分
 								let integerScore = parseInt(item.score / item.list.length)
 								let lastItem = exerciseIndex === item.list.length - 1
@@ -503,21 +541,21 @@
 							listItem.score = exercise.score
 						})
 					})
-					
+
 					/** 回到题型视图 */
 					this.groupList = this.groupTypeList
 					this.$parent.viewModel = 'type'
 					this.$parent.paperInfo.multipleRule = this.multipleRule
 					this.typeScoreModel = false
-					this.$emit('scoreUpdate',this.surPlusScore)
+					this.$emit('scoreUpdate', this.surPlusScore)
 				}
 
 			},
 
 			/** 编辑成功 */
 			onEditSuccess(item) {
-				
-				
+
+
 				if (item.id) {
 					this.$refs.paperEdit.isLoading = false
 					this.editExerciseModal = false
@@ -525,14 +563,14 @@
 					this.exerciseList.splice(this.currentExerciseIndex, 1, item)
 					this.curTypeItems.splice(this.curIndex, 1, item)
 					this.$emit('dataUpdate', this.exerciseList)
-					
+
 					let existIndex = this.modifyItems.map(i => i.id).indexOf(item.id)
-					if( existIndex < 0){
+					if (existIndex < 0) {
 						this.modifyItems.push(item)
-					}else{
+					} else {
 						this.modifyItems[existIndex] = item
 					}
-					
+
 				} else {
 					this.editExerciseModal = false
 					this.exerciseList.splice(this.currentExerciseIndex, 1, item)
@@ -601,16 +639,35 @@
 
 
 		},
-
+		mounted() {
+			this.$EventBus.$on('importFinish', list => {
+				this.errorList = list
+				this.noAnswerList = list.filter(i => i.answer.length === 0)
+				console.log(list)
+				console.log(this.noAnswerList)
+			})
+		},
 		computed: {
-			listData(){
+			listData() {
 				return this.viewModel === 'type' ? this.groupList : this.orderList
+			},
+			isError() {
+				return id => {
+					return this.errorList.length && this.errorList.map(i => i.id).indexOf(id) > -1
+				}
+			},
+			isNoAnswer() {
+				return item => {
+					return (item.question.replace(/\s*/g, "")) && item.option.length && !item.answer.length
+				}
 			}
 		},
 		watch: {
 			paper: {
 				handler(newPaper) {
 					if (newPaper) {
+						console.log('获取的题目信息')
+                        console.log(newPaper)
 						let that = this
 						this.groupList = []
 						this.exerciseList = []
@@ -618,9 +675,11 @@
 						this.paperInfo = newPaper
 						if (newPaper.item.length) {
 							newPaper.item.forEach(i => {
-								if(!i.score) i.score = 0
+								if (!i.score) i.score = 0
+							})
+							this.orderList.push({
+								list: newPaper.item
 							})
-							this.orderList.push({ list:newPaper.item })
 							/* 处理试卷内题目按照题型排序 */
 							this.typeList.forEach(item => {
 								this._.mapKeys(this._.groupBy(newPaper.item, 'type'), function(value, key) {
@@ -640,11 +699,10 @@
 						this.groupTypeList = this.groupList
 						this.totalNum = newPaper.item.length
 						this.surPlusScore = newPaper.score - newPaper.item.reduce((p, e) => parseInt(p) + parseInt(e.score), 0);
-						this.$emit('scoreUpdate',this.surPlusScore)
+						this.$emit('scoreUpdate', this.surPlusScore)
 						this.pageScrollTo(0)
-						this.pageChange(1)
-						this.$nextTick(()=>{
-							window.MathJax.Hub.Queue(["Typeset", MathJax.Hub,this.$refs.mathJaxContainer]);
+						this.$nextTick(() => {
+							window.MathJax.Hub.Queue(["Typeset", MathJax.Hub, this.$refs.mathJaxContainer]);
 						})
 					}
 				},
@@ -682,24 +740,33 @@
 		justify-content: center;
 		margin: 20px 0;
 	}
-	
+
+	.components-el-container .exercise-item-error {
+		background-color: rgb(255 152 152 / 60%);
+	}
+
+	.components-el-container .exercise-item-error:hover {
+		border: 2px solid red !important;
+	}
+
+
 	.components-el-container .type-name {
 		font-size: 18px;
 		font-weight: bold;
 		margin-top: 20px;
 	}
-	
+
 	.components-el-container /deep/ .ivu-input-number-handler-down-inner,
-	.components-el-container /deep/ .ivu-input-number-handler-up-inner{
+	.components-el-container /deep/ .ivu-input-number-handler-up-inner {
 		right: 8px;
 		font-size: 16px;
 	}
 
 
 	.components-el-container .exercise-item:hover {
-		border: 1px solid #01b4ef;
+		border: 2px solid #01b4ef;
 	}
-	
+
 	.components-el-container .exercise-item {
 		position: relative;
 		margin-top: 30px;
@@ -710,10 +777,24 @@
 		width: 92%;
 	}
 
+	.components-el-container .exercise-item .item-error-wrap {
+		position: absolute;
+		right: -2px;
+		bottom: 0;
+		width: auto;
+		height: 30px;
+		line-height: 30px;
+		padding: 0 10px;
+		margin: 0;
+		background: #ff5656;
+		color: #fff
+	}
+
+
 	.components-el-container .exercise-item .item-tools-wrap {
 		position: absolute;
-		right: 0;
-		top: -30px;
+		right: -2px;
+		top: -32px;
 		width: auto;
 		height: 30px;
 		margin: 0;

+ 8 - 2
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseFilter.vue

@@ -5,7 +5,7 @@
             <RadioGroup v-model="filterOrigin" type="button" @on-change="filterOriginChange">
 				<Radio :label="schoolCode" v-if="isShowSchoolBank">校本试卷库</Radio>
 				<Radio :label="userId">个人试卷库</Radio>
-				<Radio :label="schoolCode" v-if="!isShowSchoolBank">校本试卷库</Radio>
+				<Radio :label="schoolCode" v-if="!isShowSchoolBank && hasSchool">校本试卷库</Radio>
             </RadioGroup>
         </div>
         <div class="filter-item" v-show="isShowSchoolBank">
@@ -252,7 +252,13 @@
 
         mounted() {
 
-        }
+        },
+		computed: {
+			hasSchool(){
+				let user = JSON.parse(decodeURIComponent(localStorage.user_profile, "utf-8"));
+				return user.schools.length && user.schools.filter(i => i.status === 'join').length > 0
+			}
+		}
 
     }
 </script>

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

@@ -2,7 +2,6 @@
     <div class="cp-import-container">
             <div v-if="!isImportFinish" style="padding:40px 0;height:100%">
                 <Upload multiple
-                        type="drag"
                         :action="uploadUrl"
                         :headers="headers"
                         :format="['docx']"
@@ -12,79 +11,39 @@
                         :show-upload-list="isShowList"
                         :before-upload="beforeUpload"
                         :on-success="uploadSuccess">
-                    <div class="import-tips">
-                        <Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
-                        <p style="font-size:18px;font-weight:bold;">导入注意事项</p>
-                        <p>1.暂时只支持".docx"格式的文件导入,文件大小不超过10M,请按照<a href="https://teammodelstorage.blob.core.chinacloudapi.cn/hiteachcc/pptfiles/20190806/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF.docx">模板</a>格式导入</p>
-                        <p>2.导入题型暂时只支持单选、多选、判断、填空、问答以及综合题型</p>
-                        <p>3.{{ `请保持模板语言与当前浏览器语言(${ curLang })   一致` }}</p>
-                        <p>4.更多注意事项请查看<a href="https://teammodelstorage.blob.core.chinacloudapi.cn/hiteachcc/pptfiles/20190806/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF.docx">模板制作详情说明</a></p>
-                    </div>
-
-                    <div v-show="isSelectFinish" class="import-loading-wrap">
+                        <Icon type="ios-folder" size="150" color="#878787" style="margin: 30px 0;"/>
+                    <div v-show="isBtnLoading" class="import-loading-wrap">
                         <img src="@/assets/loading/loading.svg" width="100px" />
-                        <p style="font-size:16px;font-weight:bold">读取中</p>
+                        <!-- <p style="font-size:16px;font-weight:bold">读取中</p> -->
                     </div>
                 </Upload>
-                
-            </div>
-            <div v-else style="padding:40px">
-                <div class="exercise-item" v-for="(item,index) of exerciseList" :key="index">
-                    <!-- 题干部分 -->
-                    <div class="item-question">
-                        <p>{{ index + 1 }} : <span v-html="item.question"></span></p>
-                        <span class="item-btn-toggle btn-edit-exercise" @click="onEditExercise(item,index)">
-                            <Icon type="md-create" color="#B5B5B5" size="20" />
-                            <span> 编辑  </span>
-
-                        </span>
-                    </div>
-                    <!-- 选项部分 -->
-                    <div v-for="(option,optionIndex) in item.option" :key="optionIndex" class="item-options" style="pointer-events:none">
-                        <p class="item-option-content">{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
-                    </div>
-                    <div>
-                        <!-- 答案展示部分 -->
-                        <div class="item-explain">
-                            <span class="explain-title">【答案】</span>
-                            <div class="item-explain-details">
-                                <span v-html="item.answer" v-if="item.type === 'Subjective'"></span>
-                                <span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index" v-else-if="item.type === 'Complete'" v-html="answer"></span>
-                                <span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index" v-else>{{answer}}</span>
-                            </div>
-                        </div>
-                        <!-- 解析部分 -->
-                        <div class="item-explain">
-                            <span class="explain-title">【解析】</span>
-                            <div class="item-explain-details">
-                                <span v-html="item.explain || '暂无解析'"></span>
-                            </div>
-                        </div>
-
-                    </div>
-                </div>
+				<div class="import-tips">
+					<p style="font-size:18px;font-weight:bold;color: #fff;">导入注意事项</p>
+					<p>1.点击上方文件夹图标选择文件</p>
+					<p>2.暂时只支持".docx"格式的文件导入,文件大小不超过10M,请按照模板格式导入</p>
+					<p>3.导入题型暂时只支持单选、多选、判断、填空、问答以及综合题型</p>
+					<p>4.{{ `请保持模板语言与当前浏览器语言(${ curLang })   一致` }}</p>
+					<p>5.更多注意事项请查看模板制作详情说明</a></p>
+					<Dropdown style="margin-top: 20px;" @on-click="onTemplateSelect">
+					        <Button type="primary">
+					            多语言模板下载
+					            <Icon type="ios-arrow-down"></Icon>
+					        </Button>
+					        <DropdownMenu slot="list">
+					            <DropdownItem :name="0">中文简体(zh-CN)</DropdownItem>
+					            <DropdownItem :name="1">中文繁体(zh-TW)</DropdownItem>
+					            <DropdownItem :name="2">英文(en-US)</DropdownItem>
+					        </DropdownMenu>
+					    </Dropdown>
+					<Button type="primary" style="margin-top: 20px;" @click="onDownloadDetails">下载模板制作详情说明</Button>	
+				</div>
             </div>
-
-
-        <!-- 编辑习题 弹窗 -->
-        <Modal v-model="editExerciseModal"
-               class-name="edit-exercise-modal"
-               width="1200px"
-               footer-hide
-               title="编辑习题">
-
-            <BaseEditExercise :exerciseItem="currentExercise" @onEditSuccess="onEditSuccess" refId="importEdit"></BaseEditExercise>
-
-            <div slot="footer">
-                <Button type="success">确认</Button>
-            </div>
-
-        </Modal>
     </div>
 </template>
 <script>
     import Loading from '@/common/Loading.vue'
     import BaseEditExercise from './BaseEditExercise'
+	import FileSaver from "file-saver";
     export default {
         components: {
             Loading, BaseEditExercise
@@ -100,21 +59,24 @@
                 isShowList: true,
                 exerciseList: [],
                 importPreviewModal: false,
-                selectUsageModal: false,
-                editExerciseModal: false,
-                currentExercise: null,
-                currentExerciseIndex: null,
-                currentUsage: 'bank',
                 uploadUrl: '',
-                paperInfo: {
-                    name: '',
-                    score: 100
-                }
+				downloadUrls:[{
+					url:'/download/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF%E7%AE%80%E4%BD%93.docx',
+					fileName:'题目模板(简体).docx'
+				},{
+					url:'/download/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF%E7%B9%81%E4%BD%93.docx',
+					fileName:'题目模板(繁体).docx'
+				},{
+					url:'/download/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF%E8%8B%B1%E8%AF%AD.docx',
+					fileName:'题目模板(英文).docx'
+				}],
+				hostName:''
             }
         },
         created() {
             this.uploadUrl = window.location.origin  + '/api/ImportExercise/uploadWord'
 			this.curLang = localStorage.getItem('local')
+			this.hostName = this.$store.state.privateSas.url || 'https://teammodelstorage.blob.core.chinacloudapi.cn'
         },
         methods: {
 
@@ -124,25 +86,36 @@
                 this.exerciseList = []
                 this.isImportFinish = false
             },
-
-            /**
-             * 编辑单个试题
-             * @param item
-             */
-            onEditExercise(item, index) {
-                console.log(item)
-                console.log(this)
-                this.currentExercise = item
-                this.currentExerciseIndex = index
-                this.editExerciseModal = true
-            },
-
-            /** 编辑成功 */
-            onEditSuccess(newItem) {
-                this.editExerciseModal = false
-                this.$Message.success("修改成功!")
-                this.exerciseList.splice(this.currentExerciseIndex, 1, newItem)
-            },
+			
+			/* 下载模板 */
+			async onTemplateSelect(val){
+				let curFile = this.downloadUrls[val]
+				const downloadRes = async () => {
+				      let response = await fetch(this.hostName + curFile.url); // 内容转变成blob地址
+				      let blob = await response.blob();  // 创建隐藏的可下载链接
+				      let objectUrl = window.URL.createObjectURL(blob);
+				      let a = document.createElement('a');
+				      a.href = objectUrl;
+				      a.download = curFile.fileName;
+				      a.click()
+				      a.remove(); 
+				   }
+				  downloadRes();
+			},
+			
+			onDownloadDetails(){
+				const downloadRes = async () => {
+				      let response = await fetch(this.hostName + '/download/%E6%A8%A1%E6%9D%BF%E5%88%B6%E4%BD%9C%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9.txt'); // 内容转变成blob地址
+				      let blob = await response.blob();  // 创建隐藏的可下载链接
+				      let objectUrl = window.URL.createObjectURL(blob);
+				      let a = document.createElement('a');
+				      a.href = objectUrl;
+				      a.download = '模板制作注意事项.txt';
+				      a.click()
+				      a.remove(); 
+				   }
+				  downloadRes();
+			},
 
             importModalChange(val) {
                 if (!val) {
@@ -199,93 +172,19 @@
                                 this.$Message.success('试题数据读取完成!')
                                 this.$emit('importFinish',res)
                                 this.isImportFinish = false
+                                this.isBtnLoading = false
                                 this.exerciseList = []
                         }else{
 							this.$Message.error('抱歉,文档解析失败!')
+							this.isBtnLoading = false
 						}
                     })
                 } else {
                     this.$Message.error('抱歉,文档解析失败!')
+					this.isBtnLoading = false
                 }
 				this.isSelectFinish = false
             },
-
-            /** 导入后选择试题用途 */
-            onSelectUsage() {
-                console.log(this.exerciseList)
-                let importList = this.exerciseList
-                for (let i = 0; i < importList.length; i++) {
-                    if (importList[i].level === 0) {
-                        this.$Message.warning(`第${i + 1}个试题未设置难度!请确保信息完善!`)
-                        return
-                    }
-                }
-                this.selectUsageModal = true
-            },
-
-            /** 选好用途后确认导入 */
-            onConfirmUsage() {
-                if (this.currentUsage === 'bank') {
-                    this.saveAllExercise(this.exerciseList).then(res => {
-                        this.$Message.success("保存成功!")
-                        this.selectUsageModal = false
-                        this.importPreviewModal = false
-                    })
-                } else if (this.currentUsage === 'paper') {
-                    this.goToTestPaper()
-                } else {
-                    if (!this.paperInfo.name) {
-                       this.$Message.warning("试卷名称不能为空!")
-                    } else {
-                       this.saveAllExercise(this.exerciseList).then(res => {
-                            this.$Message.success("保存成功!")
-                            this.goToTestPaper()
-                       })
-                    }
-                }
-            },
-
-
-            /**
-             * 保存导入的所有试题
-             * @param list
-             */
-            saveAllExercise(list) {
-                return new Promise((r, j) => {
-                    this.$api.newEvaluation.SaveAllExercise(list).then(res => {
-                        if (res.result.data) r(res.result.data)
-                    }).catch(err => {
-                        j(err)
-                    })
-                })
-
-            },
-
-            /** 导入试题后进入组卷 */
-            goToTestPaper() {
-                const parentVm = this.$parent
-                if (!this.paperInfo.name) {
-                    this.$Message.warning("试卷名称不能为空!")
-                } else {
-                    let params = {
-                        name: this.paperInfo.name,
-                        score: this.paperInfo.score,
-                        item: this.exerciseList,
-                        scopeCode: parentVm.filterParams.scopeCode,
-                        periodCode: parentVm.filterParams.periodCode[0],
-                        gradeCode: this.gradeCode,
-                        subjectCode: parentVm.filterParams.subjectCode[0]
-                    }
-                    this.$router.push({
-                        name: 'testPaper',
-                        params: {
-                            paper: params
-                        }
-                    })
-                }
-
-            },
-
         },
 
         mounted() {
@@ -307,10 +206,29 @@
 </style>
 
 <style lang="less">
-
+	.cp-import-container{
+		background: #404040;
+		height: 100%;
+	}
+	
     .cp-import-container,
     .cp-import-container .ivu-upload {
-        height:100%;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		
+		.ivu-upload-list{
+			display: none;
+		}
+		
+		.ivu-icon{
+			cursor: pointer;
+		}
+		
+		.ivu-btn-primary{
+			background-color: #00756f;
+			border: none;
+		}
     }
 
         .cp-import-container .ivu-upload-drag {
@@ -341,10 +259,14 @@
 
     .import-tips {
         padding: 20px 0;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		color: #b8b8b8;
     }
 
         .import-tips p {
-            margin: 10px;
+            margin: 5px;
         }
 
     .cp-import-container .exercise-item:not(:first-child) {
@@ -363,7 +285,7 @@
 
 
     .cp-import-container .import-loading-wrap {
-        position: relative;
+        position: absolute;
         display: flex;
         justify-content: center;
         align-items: center;

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

@@ -26,7 +26,7 @@
 		<div class="display-flex">
 			<div class="exersices-attr my-radio-style">
 				<IconText :text="'题目归属'" :color="'#00b8ff'" :icon="'md-cube'"></IconText>
-				<Select v-model="exerciseScope">
+				<Select v-model="exerciseScope" disabled>
 					<Option v-for="(item,index) in scopeList" :value="index" :key="index">{{ item }}</Option>
 				</Select>
 			</div>

+ 93 - 88
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -4,7 +4,7 @@
 			<p class="create-header-title">{{ isEditPaper ? '编辑试卷' : '新建试卷'}}</p>
 			<div style="float: right;" class="common-save-btn">
 				<Button class="btn-save" type="text" icon="md-arrow-round-back" @click="goBack">返回试卷库</Button>
-				<Button class="btn-save" type="text" icon="md-folder" :loading="isLoading" @click="saveTestPaper">保存试卷</Button>
+				<Button class="btn-save" type="text" icon="md-folder" :loading="isLoading" @click="saveTestPaper">{{ isLoading ? '保存中' : '保存试卷'}}</Button>
 			</div>
 		</div>
 		<div class="create-body">
@@ -36,7 +36,7 @@
 								<Option v-for="(subject,index) in subjectList" :value="index" :key="index">{{ subject.name }}</Option>
 							</Select>
 						</FormItem>
-						<FormItem label="试卷总分" prop="name">
+						<FormItem label="试卷总分" prop="name" class="evaluation-attr-wrap-inputNumber">
 							<InputNumber :max="200" :min="1" v-model="evaluationInfo.score"></InputNumber>
 						</FormItem>
 					</Form>
@@ -60,7 +60,7 @@
 						</TabPane>
 						<TabPane label="备选题目" name="manual" v-if="evaluationInfo.createType == 'manual'"
 						 :index="2" tab="createTest">
-							<ManualCreate :questionList="questionList" :selQue="evaluationInfo.item" @goToPreview="goToPreview"
+							<ManualCreate :questionList="questionList" :subjectId="propSubject" :selQue="evaluationInfo.item" @goToPreview="goToPreview"
 							 @selectedQuestion="getSelectedQuestion"></ManualCreate>
 						</TabPane>
 						<TabPane label="导入说明" name="import" v-if="evaluationInfo.createType == 'import'"
@@ -144,7 +144,9 @@
 					startTime: 0,
 					endTime: 0,
 					createType:'auto'
-				}
+				},
+				errorList:[],
+				noAnswerList:[]
 			}
 		},
 		async created() {
@@ -206,54 +208,61 @@
 			 * @param list
 			 */
 			async onImportFinish(list) {
+				this.errorList = []
+				this.evaluationInfo.item = []
 				let importList = await this.refreshImportItems(list)
-				this.evaluationInfo.item = this.evaluationInfo.item.concat([...importList])
+				this.evaluationInfo.item = importList
 				this.activeTab = 'preview'
+				if(this.errorList.length){
+					this.$EventBus.$emit('importFinish',this.errorList)
+				}
 			},
 
 			/* 给导入的试题 补充最新的试卷学段年级以及科目信息 */
 			refreshImportItems(list) {
 				return new Promise((r, j) => {
+					let objectiveTypes = ['single','multiple'] 
 					let code = this.isSchool ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
 					let gradeIds = this.isSchool ? this.evaluationInfo.paperGrade.length ? this.evaluationInfo.paperGrade : this.gradeList.map(i => i.id) : null
 					let subjectId = this.isSchool ? this.subjectList[this.evaluationInfo.paperSubject].id : null
 					let periodId = this.isSchool ? this.schoolInfo.period[this.evaluationInfo.paperPeriod].id : null
 					list.forEach(i => {
 						/* 如果是导入的试题 没有ID 则试题的信息和当前试卷的学段信息保持一致 */
-						if (!i.id) {
-							i.id = this.$tools.guid()
-							i.code = code
-							i.level = 3
-							i.field = 1
-							i.scope = this.isSchool ? 'school' : 'private',
-							i.gradeIds = gradeIds
-							i.subjectId = subjectId
-							i.periodId = periodId
-							if (i.children.length) {
-								i.children.forEach(j => {
-									j.id = this.$tools.guid()
-									j.code = code
-									j.level = 3
-									j.field = 1
-									j.gradeIds = gradeIds
-									j.subjectId = subjectId
-									j.periodId = periodId
-								})
-							}
+						i.id = this.$tools.guid()
+						i.code = code
+						i.level = 3
+						i.field = 1
+						i.scope = this.isSchool ? 'school' : 'private',
+						i.gradeIds = gradeIds
+						i.subjectId = subjectId
+						i.periodId = periodId
+						if (i.children.length) {
+							i.children.forEach(j => {
+								j.id = this.$tools.guid()
+								j.code = code
+								j.level = 3
+								j.field = 1
+								j.gradeIds = gradeIds
+								j.subjectId = subjectId
+								j.periodId = periodId
+							})
+						}
+						// 如果导入的是客观题 则需要检测答案与选项是否为空
+						if(objectiveTypes.includes(i.type) && (!i.question.replace(/\s*/g,"") || !i.option.length || !i.answer.length)){
+							this.errorList.push(i)
 						}
 					})
 					r(list)
 				})
 			},
+			
 
 			/**
 			 * 获取自动组题数据
 			 * @param questions
 			 */
 			async getAutoQuestions(questions) {
-				console.log(questions)
 				let autoQuestions = await this.$evTools.getFullItem(questions)
-				console.log(autoQuestions)
 				this.evaluationInfo.item = []
 				this.evaluationInfo.item = this.evaluationInfo.item.concat([...autoQuestions])
 				this.activeTab = 'preview'
@@ -264,15 +273,7 @@
 			 * @param data
 			 */
             getSelectedQuestion(data) {
-				let arr = []
-				// 把试题的blob结构 包装成 数据库格式
-				data.questions.forEach(jsonData => {
-					jsonData.exercise.id = jsonData.id
-					jsonData.exercise.question = jsonData.item[0].question
-					jsonData.exercise.score = 0
-					jsonData.exercise.option = jsonData.item[0].option
-					arr.push(jsonData.exercise)
-				})
+				let arr = data.questions
 				// 如果是编辑试卷 则往原试卷添加不包含的新题目进入
 				if(this.isEditPaper){
 					let list = this.evaluationInfo.item
@@ -304,6 +305,8 @@
 					    cancelText: '取消',
 					    onOk: () => {
 							this.evaluationInfo.item = []
+							this.$refs.testPaper.$refs.exList.errorList = []
+							this.$refs.testPaper.$refs.exList.noAnswerList = []
 							this.activeTab = data
 					    },
 						onCancel:() => {
@@ -339,7 +342,6 @@
 				// 获取初始化Blob需要的数据
 				let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
 				let itemJsonFiles = []
-				let itemJsonUrls = []
 				//初始化Blob
 				let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas,this.evaluationInfo.type)
 				return new Promise(async (resolve, j) => {
@@ -353,7 +355,6 @@
 								const itemJsonFile = await this.$evTools.createBlobItem(exerciseItem)
 								let file = new File([JSON.stringify(itemJsonFile)], exerciseItem.id + ".json");
 								itemJsonFiles.push(file)
-								itemJsonUrls.push(exerciseItem.id + ".json")
 								
 								// 如果有修改的试题 并且为个人题目 则需要同步更新个人题库里面的JSON数据内容
 								// if(modifyItems.length){
@@ -386,29 +387,30 @@
 									if (blobFile.blob) {
 										// 保存试题JSON文件到试卷文件夹需要
 										itemJsonFiles.push(file)
-										itemJsonUrls.push(exerciseItem.id + ".json")
 										// 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
 										cosmosItem.blob = blobFile.blob
 										// 保存当前试题到数据库
 										that.saveExercise(cosmosItem).then(res => {
-											r(res)
+											r(res.itemInfo)
 										})
 									}else{
 										j(500)
 									}
 								}catch(e){
 									this.$Message.error(e.spaceError)
+									this.isLoading = false
 								}
-								
 							}))
 						}
 					}
 					Promise.all(promiseArr).then(result => {
+						console.log(result)
 						resolve({
-							urls:itemJsonUrls,
+							urls:result.map(i => i.id + '.json'),
 							files:itemJsonFiles
 						})
 					}).catch(err => {
+						console.log(err)
 						this.$Message.error('操作失败')
 					})
 				})
@@ -463,44 +465,50 @@
 			async saveTestPaper() {
 				let hasSurplus = this.$refs.testPaper.$refs.exList.surPlusScore // 判断是否有剩余分数未分配
 				let noScoreList = this.$refs.testPaper.$refs.exList.exerciseList.filter(item => item.score === 0) // 判断是否有未配分的题目
-				let isPaperExist = await this.isPaperExist(this.evaluationInfo.name)
+				let hasErrorItem = this.$refs.testPaper.$refs.exList.errorList.length > 0
 				let list = this.evaluationInfo.item
 				if(this.evaluationInfo.name.trim() === ''){
 					this.$Message.warning('试卷名称不能为空!')
 					return 
 				}
-				if (hasSurplus === 0) {
-					if (!noScoreList.length) {
-						if(!isPaperExist){
-							if (list.length) {
-								this.doSavePaper(list)
-							} else {
-								this.$Message.warning('未选择任何试题!')
-							}
-						}else{
-							this.$Modal.confirm({
-							    title: '温馨提示',
-							    content: '<p>试卷库已存在重复名称试卷,是否继续保存覆盖原试卷?</p>',
-							    okText: '确认',
-							    cancelText: '取消',
-							    onOk: async () => {
-									let blobList = await this.getPaperFiles('paper/' + this.evaluationInfo.name)
-									let files = blobList.blobList.map(i => i.blob)
-									console.log(files)
-									this.onDeleteBlobPaper(files).then(r => {
-										this.doSavePaper(list)
-									})
-							    },
-								onCancel:() => {
-									this.$Message.warning('取消保存试卷')
+				console.log(this.$refs.testPaper.$refs.exList.errorList)
+				if(!hasErrorItem){
+					if (hasSurplus === 0) {
+						if (!noScoreList.length) {
+							let isPaperExist = await this.isPaperExist(this.evaluationInfo.name)
+							if(!isPaperExist){
+								if (list.length) {
+									this.doSavePaper(list)
+								} else {
+									this.$Message.warning('未选择任何试题!')
 								}
-							})
+							}else{
+								this.$Modal.confirm({
+									title: '温馨提示',
+									content: '<p>试卷库已存在重复名称试卷,是否继续保存覆盖原试卷?</p>',
+									okText: '确认',
+									cancelText: '取消',
+									onOk: async () => {
+										let blobList = await this.getPaperFiles('paper/' + this.evaluationInfo.name)
+										let files = blobList.blobList.map(i => i.blob)
+										console.log(files)
+										this.onDeleteBlobPaper(files).then(r => {
+											this.doSavePaper(list)
+										})
+									},
+									onCancel:() => {
+										this.$Message.warning('取消保存试卷')
+									}
+								})
+							}
+						} else {
+							this.$Message.warning(`存在未配分的题目,请配分后再保存!`)
 						}
 					} else {
-						this.$Message.warning(`存在未配分的题目,请配分后再保存!`)
+						this.$Message.warning(`试卷配分未完成!剩余 ${hasSurplus} 分数可分配`)
 					}
-				} else {
-					this.$Message.warning(`试卷配分未完成!剩余 ${hasSurplus} 分数可分配`)
+				}else{
+					this.$Message.warning(`存在异常试题,请修改或者重新导入!`)
 				}
 			},
 			
@@ -550,9 +558,9 @@
 				let multipleRule = this.$refs.testPaper.paperInfo.multipleRule
 				let modifyItems = this.$refs.testPaper.$refs.exList.modifyItems
 				// 将传进来的试题 如果是导入的试题 则需要补充年级学段等信息
-				let refreshList = await this.refreshImportItems(list)
+				// let refreshList = await this.refreshImportItems(list)
 				// 保存导入的试题到BLOB以及COSMOS
-				this.savePaperItems(refreshList,modifyItems,this.isEditPaper).then(async res => {
+				this.savePaperItems(list,modifyItems,this.isEditPaper).then(async res => {
 					let guid = this.$tools.guid()
 					let paperItem = {
 						id: this.evaluationInfo.id || guid,
@@ -592,6 +600,7 @@
 									}catch(e){
 										j(e)
 										this.$Message.error(e.spaceError)
+										this.isLoading = false
 									}
 									
 								}))
@@ -638,22 +647,14 @@
 			/* 获取整张试卷的答案合计Answers */
 			getAnswers(items) {
 				let arr = []
+				// 主观题的answer为空数组
+				let nullType = ['complete','subjective','compose']
 				items.forEach((i, index) => {
-					if (i.type === 'Complete') {
-						i.answer.forEach(j => {
-							arr.push({
-								type: i.type,
-								ans:[j],
-								score: i.score / i.answer.length
-							})
-						})
-					} else {
-						arr.push({
-							type: i.type,
-							ans:i.answer,
-							score: i.score
-						})
-					}
+					arr.push({
+						type: i.type,
+						ans: nullType.includes(i.type) ? [] : i.answer,
+						score: i.score
+					})
 				})
 				return arr
 			},
@@ -778,6 +779,10 @@
 	.evaluation-attr-wrap .ivu-tag .ivu-icon-ios-close{
 		color: #fff;
 	}
+	
+	.evaluation-attr-wrap-inputNumber .ivu-input-number-input{
+		color: #fff;
+	}
 
 	.evaluation-question-main .ivu-tabs-bar {
 		border-color: #404040;

+ 1 - 0
TEAMModelOS/ClientApp/src/view/evaluation/index/PickExercise.css

@@ -128,6 +128,7 @@
         font-size: 16px;
         font-weight: 600;
         background: #fff;
+		border: 2px solid transparent;
         cursor:pointer;
         /*box-shadow: 6px 5px 5px 2px rgb(214, 214, 214);*/
     }

+ 26 - 4
TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.less

@@ -162,7 +162,6 @@
     }
 
     .paper-base-info {
-        height: 60px;
 		position: sticky;
 		top: 0;
         display: flex;
@@ -172,10 +171,33 @@
 		background-color: #fff;
         border-bottom: 1px dashed #cfcfcf;
 		z-index: 99;
+		padding: 10px 0 20px 0;
+		
+		.paper-info-items{
+			display: flex;
+			flex-direction: column;
+			font-weight: bold;
+			font-size: 16px;
+			justify-content: space-between;
+			
+			.ivu-rate{
+				margin-bottom: 5px;
+			}
+			
+			&:first-child{
+				height: 55px;
+				margin-top: 5px;
+			}
+			
+			&:not(:first-child){
+				margin-left: 40px;
+				height: 50px;
+			}
+		}
 
-        .base-info-item:not(:first-child) {
-            margin-left: 30px;
-        }
+        // .base-info-item:not(:first-child) {
+        //     margin-left: 30px;
+        // }
 
         .base-info-btn:not(:last-child) {
             margin-right: 10px;

+ 32 - 26
TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue

@@ -1,12 +1,12 @@
 <template>
 	<div class="paper-container">
 		<div class="back-to-top flex-col-center" title="返回顶部" v-if="isShowBackToTop" @click="handleBackToTop">
-		    <Icon type="ios-arrow-up" />
+			<Icon type="ios-arrow-up" />
 		</div>
 		<div class="paper-main-wrap">
 			<!-- 试卷内容 -->
 			<div class="paper-content">
-<!-- 				<div class="paper-line" style="margin-top:7%">
+				<!-- 				<div class="paper-line" style="margin-top:7%">
 					<div id="pui_seal" title="点击设置&quot;装订线&quot;" style="display: block;">
 						<img alt="装订线" title="装订线" src="../../../assets/image/peal_line.png">
 					</div>
@@ -14,17 +14,21 @@
 				<div class="paper-body">
 					<!-- 试卷基础信息 -->
 					<div class="paper-base-info" v-show="isShowBaseInfo">
-						<div>
-							<span class="base-info-item">总分:<span class="analysis-info" style="cursor: pointer;" @click="isSetScore = !isSetScore">{{ paperInfo.score }}</span>分</span>
-							<span class="base-info-item">已配分:<span class="analysis-info" >{{ allocatedScore || 0 }}</span>分</span>
-							<span class="base-info-item">题量:<span class="analysis-info">{{ paperInfo.item ? paperInfo.item.length : 0 }}</span></span>
-							<span class="base-info-item">难度:<span class="analysis-info">{{ paperInfo.item.length ? paperDiff : 0 }}</span></span>
+						<div style="display: flex;">
+							<div class="paper-info-items">
+								<span class="base-info-item">试卷总分:<span class="analysis-info" style="cursor: pointer;" @click="isSetScore = !isSetScore">{{ paperInfo.score }}</span>分</span>
+								<span class="base-info-item">已配分数:<span class="analysis-info">{{ allocatedScore || 0 }}</span>分</span>
+							</div>
+							<div class="paper-info-items">
+								<span class="base-info-item">难度:<Rate allow-half v-model="paperInfo.item.length ? +paperDiff : 0" disabled /></span>
+								<span class="base-info-item">题量:<span class="analysis-info">{{ paperInfo.item ? paperInfo.item.length : 0 }}</span></span>
+							</div>
 						</div>
 						<div>
 							<Button class="base-info-btn" type="info" @click="onHandleToggle" v-show="paperInfo.item.length && !isShowAnalysis">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button>
 							<Button class="base-info-btn" type="info" @click="onSetScoreByType" v-show="paperInfo.item.length && !isShowAnalysis">题型配分</Button>
 							<Button class="base-info-btn" type="info" @click="onCleanPaper" v-show="paperInfo.item.length && !isShowAnalysis">清空试题</Button>
-							<Button class="base-info-btn" type="info" @click="onViewModelChange" v-show="paperInfo.item.length && !isShowAnalysis" >{{ `依${ viewModel === 'type' ? '顺序' : '题型' }排列` }}</Button>
+							<Button class="base-info-btn" type="info" @click="onViewModelChange" v-show="paperInfo.item.length && !isShowAnalysis">{{ `依${ viewModel === 'type' ? '顺序' : '题型' }排列` }}</Button>
 							<Button class="base-info-btn" type="info" @click="isShowAnalysis = !isShowAnalysis" v-show="paperInfo.item.length">{{ isShowAnalysis ? '试卷详情' : '试卷分析'}}</Button>
 						</div>
 					</div>
@@ -33,9 +37,9 @@
 					<div class="paper-header flex-col-center">
 						<p class="paper-title">{{paperInfo.name}}</p>
 					</div>
-					
+
 					<ExamPaperAnalysis :testPaper="paperInfo" v-show="isShowAnalysis"></ExamPaperAnalysis>
-					
+
 					<!-- 题目类型及列表 -->
 					<BaseExerciseList :paper="paperInfo" @dataUpdate="onListUpdate" v-show="!isShowAnalysis" ref="exList" :isShowTools="isShowTools"
 					 @toggleChange="onToggleChange" @scoreUpdate="scoreUpdate"></BaseExerciseList>
@@ -52,9 +56,9 @@
 				<Button type="primary" @click="onSetScore">确定</Button>
 			</div>
 		</Modal>
-		
+
 		<!-- 设置试卷标题 -->
-<!-- 		<Modal v-model="isSetPaperName" title="设置试卷名称" width="400px" class="related-point-modal" style="z-index:99999">
+		<!-- 		<Modal v-model="isSetPaperName" title="设置试卷名称" width="400px" class="related-point-modal" style="z-index:99999">
 			<span>试卷名称</span>
 			<Input v-model="paperInfo.name" style="margin:20px 0"></Input>
 			<div slot="footer">
@@ -90,21 +94,21 @@
 		},
 		data() {
 			return {
-				isShowBackToTop:false,
+				isShowBackToTop: false,
 				isAllOpen: false,
-				isShowAnalysis:false,
-				isSetPaperName:false,
+				isShowAnalysis: false,
+				isSetPaperName: false,
 				isSetScore: false,
 				isSetRules: false,
 				isShowSave: false,
 				exersicesList: [],
-				allocatedScore:0,
+				allocatedScore: 0,
 				list: [],
 				schoolInfo: {},
 				paperInfo: {
 					name: "",
 					score: 100,
-					answers:[],
+					answers: [],
 					multipleRule: 1,
 					item: []
 				},
@@ -157,8 +161,8 @@
 			titleChange(e) {
 				this.paperInfo.name = e.target.innerHTML
 			},
-			
-			handleBackToTop(){
+
+			handleBackToTop() {
 				console.log(this)
 				this.$EventBus.$emit('onBackToTop')
 			},
@@ -166,8 +170,8 @@
 			onSetMarkingRules() {
 				this.isSetRules = false
 			},
-			
-			onShowAnalysis(){
+
+			onShowAnalysis() {
 				this.isShowAnalysis = true
 			},
 
@@ -194,11 +198,13 @@
 					}
 				})
 			},
-			
+
 			/* 清空试卷试题 */
-			onCleanPaper(){
+			onCleanPaper() {
 				this.paperInfo.item = []
-				this.$EventBus.$emit('onPaperItemChange',[])
+				this.$refs.exList.errorList = []
+				this.$refs.exList.noAnswerList = []
+				this.$EventBus.$emit('onPaperItemChange', [])
 			},
 
 			onSetScore() {
@@ -266,8 +272,8 @@
 				let levelArr = arr.map(i => i.level)
 				return this._.meanBy(levelArr).toFixed(1)
 			},
-			
-			scoreUpdate(score){
+
+			scoreUpdate(score) {
 				this.allocatedScore = this.paperInfo.score - score
 			}
 

+ 1 - 1
TEAMModelOS/ClientApp/src/view/feedback/Feedback.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="home-page-container">
-        <h1 style="text-align:center; padding-top:200px;font-size:40px;">问题答疑页面正在开发中,敬请期待!</h1>
+        <h1 style="text-align: center;padding-top: 200px; font-size: 30px; color: #a9a9a9;">问题答疑页面正在开发中,敬请期待!</h1>
     </div>
 </template>
 <script>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/homepage/HomePage.vue

@@ -253,7 +253,7 @@
                                     2020.12.01-2020.12.31为IES5内测阶段!
                                 </p>
                             </li>
-                            <li v-if="$store.state.user.userProfile.schools.length == 0" @click="toJoinSchool">
+                            <li v-if="$store.state.userInfo.schoolCode == $GLOBAL.DEFAULT_SCHOOL_CODE" @click="toJoinSchool">
                                 <!--<li v-if="$store.state.user.userProfile.schools.length == 0" @click="toJoinSchool">-->
                                 <div style="display:flex;justify-content:space-between;">
                                     <p>

+ 12 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.less

@@ -108,17 +108,23 @@
         }
     }
 }
-.evaluation-question-main .ivu-tabs-bar {
+.evaluation-question-main /deep/ .ivu-tabs-bar {
     border-color: #404040;
+    margin-bottom: 0px;
+    border-bottom: none;
 }
 
-.evaluation-question-main .ivu-tabs.ivu-tabs-card > .ivu-tabs-bar .ivu-tabs-tab {
+.evaluation-question-main /deep/ .ivu-tabs-content-animated {
+    height: 100%;
+}
+.evaluation-question-main /deep/ .ivu-tabs .ivu-tabs-tabpane {
+}
+.evaluation-question-main .ivu-tabs.ivu-tabs-card /deep/ .ivu-tabs-bar .ivu-tabs-tab {
     border: none;
     background-color: #303030;
     color: white;
     margin-right: 2px;
 }
-
 .evaluation-attr-form {
     /*margin-top:30px;*/
     margin-right: 10px;
@@ -156,3 +162,6 @@
         color: aqua;
     }
 }
+.ivu-select-nochoose {
+    background-color: none !important;
+}

+ 323 - 144
TEAMModelOS/ClientApp/src/view/learnactivity/CreateEvaluation.vue

@@ -3,12 +3,12 @@
         <div class="create-header">
             <p class="create-header-title">创建评测活动</p>
             <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveEvaluation">发布评测</Button>
-            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="md-arrow-dropleft" @click="confirmToManage">返回上级</Button>
+            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="md-arrow-back" @click="confirmToManage">返回上级</Button>
         </div>
         <div class="create-body">
             <div class="evaluation-attr-wrap">
                 <p class="wrap-label">基础信息</p>
-                <div style="width:100%; height:calc(100% - 45px);padding-top:30px;" class="dark-iview-form">
+                <div style="width:100%; height:calc(100% - 45px);padding-top:30px;" class="dark-iview-form ivu-select-nochoose">
                     <Form ref="evaluationInfo" :model="evaluationInfo" label-position="top" class="evaluation-attr-form " label-colon :rules="ruleValidate">
                         <FormItem label="评测名称" prop="name">
                             <Input v-model="evaluationInfo.name" placeholder="评测名称" @on-change="handlePaperName"></Input>
@@ -23,17 +23,17 @@
                                 <Option v-for="(item,index) in typeList" :value="item.value" :key="index">{{ item.label }}</Option>
                             </Select>
                         </FormItem>
-                        <FormItem label="测试类型" prop="type">
-                            <Select v-model="evaluationInfo.type">
-                                <Option v-for="(item,index) in typeList" :value="item.value" :key="index">{{ item.label }}</Option>
+                        <FormItem label="测试学段" prop="school" >
+                            <Select v-model="evaluationInfo.school" @on-change="getPeriod">
+                                <Option v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :value="item.id" :key="index">{{ item.name }}</Option>
                             </Select>
                         </FormItem>
-
-                        <FormItem label="施测对象">
-                            <!--<Cascader :list="list" @onClick="handleClick"></Cascader>-->
-                            <!--<Select v-model="evaluationInfo.target" multiple>
-            <Option v-for="(item,index) in classroomList" :value="item.id" :key="index">{{ item.name }}</Option>
-        </Select>-->
+                        <FormItem label="测试类型" prop="examType" >
+                            <Select v-model="evaluationInfo.examType" @on-open-change="getTestType">
+                                <Option v-for="(item,index) in testType" :value="item.id" :key="index">{{ item.name }}</Option>
+                            </Select>
+                        </FormItem>
+                        <FormItem label="施测对象" >
                             <MultiCascader ref="addMulti" v-bind="config" @son="changeSon" hasValue :firstOpen="open" v-model="formChange.scope" @on-change="setChangeScope"></MultiCascader>
                         </FormItem>
                         <FormItem label="发布方式" prop="publish">
@@ -57,14 +57,13 @@
                 <div class="wrap-label" v-if="mode == 'school'">
                     <p>测试科目:</p>
                     <span v-for="(item,index) in evaluationInfo.paperInfo" :key="index" :class="index == currentSubjectIndex ? 'subject-item subject-item-active':'subject-item'" @click="selectSubject(index)">
-                        {{ jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodId).name}}
-                        <span style="margin:0px 5px;">·</span>
+                        <!--{{ jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodId+1).name}}
+                        <span style="margin:0px 5px;">·</span>-->
                         {{jsFn.getSubjectName(jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodId), item.subjectId)}}
                         <Icon type="ios-close" size="18" class="delete-subject-btn" @click="deleteSubject(index)" />
                     </span>
                     <Icon @click="addSubject" type="md-add-circle" title="添加科目" color="white" class="add-subject-icon" size="20" />
                 </div>
-
                 <div class="evaluation-question-main">
                     <EmptyData :top="0" style="padding-top:100px;" v-if="evaluationInfo.paperInfo.length == 0" textContent="暂无科目,请添加科目"></EmptyData>
                     <div class="create-type-wrap" v-if="evaluationInfo.paperInfo.length > 0 || mode == 'class'" >
@@ -78,7 +77,7 @@
                     </div>
 
 
-                    <Tabs v-model="activeTab" type="card" class="question-main-tabs dark-iview-tab" v-if="evaluationInfo.paperInfo.length > 0 || mode == 'class' " name="createTest">
+                    <Tabs v-model="activeTab" type="card" class="question-main-tabs" v-if="evaluationInfo.paperInfo.length > 0 || mode == 'class' " name="createTest">
                         <!--<TabPane label="组题条件" name="auto" v-if="evaluationInfo.paperInfo[currentSubjectIndex].createType == 'auto'" :index="1" tab="createTest">
                             <AutoCreate :subjectCode="evaluationInfo.paperInfo[currentSubjectIndex].subjectCode" :periodCode="evaluationInfo.paperInfo[currentSubjectIndex].periodCode" @goToPreview="goToPreview" @autoQuestions="getAutoQuestions"></AutoCreate>
                         </TabPane>-->
@@ -102,9 +101,6 @@
                             {{examAnalysisStatus ? '试卷预览':'试卷分析'}}
                         </span>
                     </Tabs>
-
-
-
                 </div>
             </div>
         </div>
@@ -113,9 +109,9 @@
                title="添加测试学科"
                class-name="dark-iview-modal"
                @on-ok="confirmAddSubject"
+               @on-cancel="cancelAddSubject"
                >
-               <!--@on-cancel="cancelAddSubject"-->
-            <div v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :key="index" style="margin-top:10px;margin-bottom:30px;color:white;">
+            <div v-for="(item,index) in testSubject" :key="index" style="margin-bottom:10px;color:white;">
                 <div style="padding-bottom:6px;margin-bottom:6px;">
                     <span>{{item.name}}</span>
                 </div>
@@ -173,8 +169,10 @@
         },
         data() {
             return {
-                data3: [],
+                selectSchool: '',
                 //isTeacher: true,  //判定当前教师是否分配学校
+                testType: [], //测试类型
+                testSubject:[], //测试科目
                 startTime: '',
                 endTime:'',
                 examAnalysisStatus: false,
@@ -196,6 +194,12 @@
                     evaType: [
                         { required: true, message: '评量模式不能为空!', trigger: 'change' }
                     ],
+                    school: [
+                        { required: true, message: '请设置测试学段!', trigger: 'change' }
+                    ],
+                    testType: [
+                        { required: true, message: '请设置测试类型!', trigger: 'change' }
+                    ],
                     publish: [
                         { required: true, message: '请设置发布方式!', trigger: 'change' }
                     ],
@@ -216,9 +220,11 @@
                 evaluationInfo: {
                     name: '',
                     target: [],
-                    type: '',
+                    type: '',  //测试类别
                     evaType:'',
                     publish: '',
+                    school: '', //学段
+                    examType:'', //测试类型
                     startTime: undefined,
                     endTime: undefined,
                     paperInfo: [],
@@ -266,7 +272,7 @@
                     clearable: true,
                     multiple: true,
                     data: [],
-                    placeholder: '请选择施測對象',
+                    placeholder: '请选择施测对象',
                     style: "width:100%"
                 },
                 formChange: {
@@ -281,35 +287,152 @@
                     values:'gradeId',
                     label: 'name',
                     children: 'class'
-                },   
-                //map: {
-                //    value: 'id',
-                //    values:'gradeId',
-                //    label: 'name',
-                //    children: 'class'
-                //}
+                }, 
+                gradeChoose: [],
+                classChoose:[]
             }
         },
         methods: {
             /**
              * 多選組件配置信息
              * */
-            setChangeScope(value) {
-                console.log(value)
-                //let self = this;
-                //let data = [];
-                //if (value) {
-                //    for (let i = 0; i < value.length; i++) {
-                //        data.push(value[i].value)
-                //    }
-                //    self.formChange.scope = data
-                //}
+            async setChangeScope(data) {
+                console.log(data)
+                let classInfo = []
+                let periodInfo = []
+                let periodData = []
+                for (let i = 0; i < data.length; i++) {
+                    let str = (data[i].__value || "").split(',')
+                    periodData.push(str[0])
+                    if (data[i].grade == undefined) {
+                        classInfo.push(data[i].value)
+                    } else {
+                        periodInfo.push(data[i].grade)
+                    }
+                }
+                let datas = await this.unique(periodData)
+                this.gradeChoose = this.getexamGradeName(datas)
+                console.log(this.gradeChoose)
+                let dataInfo =[]
+                dataInfo = await this.getChooseClass(periodInfo)
+                if (dataInfo.length !== 0) {
+                    this.classChoose = [...classInfo,...dataInfo]
+                } else {
+                    this.classChoose = [...classInfo]
+                }
+            },
+            getexamGradeName(data) {
+                let code = []
+                let key = {}
+                for (let datas of data) {
+                    for (let item of this.getPeriodInfo(this.evaluationInfo.school).grades) {
+                        if (item.id = datas) {
+                            key.id = item.id
+                            key.name = item.name
+                            code.push(key)
+                        }
+                    }
+                }
+                code = this.unique(code)
+                return code
+                console.log(code)
             },
             changeSon() {
-                this.open = false
+                this.open = true
+            },
+            //根据年级获取班级信息
+            getChooseClass(data) {
+                let classData = []
+                if (data.length !== 0) {
+                    for (let item of data) {
+                        for (let code of this.$store.state.schoolBaseInfo.classroomList) {
+                            if (code.gradeId == item) {
+                                classData.push(code.id)
+                            }
+                        }
+                    }
+                    return classData
+                } else {
+                    return classData
+                }
+            },
+            //数组查重
+            unique(array) {
+                var res = []
+                for (var i = 0, len = array.length; i < len; i++) {
+                    var current = array[i]
+                    if (res.indexOf(current) === -1) {  //查询重复值
+                        res.push(current)
+                    }
+                }
+                return res
             },
 
-
+            //获取选择的学段
+            async getPeriod(data) {
+                if (data !== '') {
+                    console.log(data)
+                    console.log(this.$store.state)
+                   await this.getSchoolBaseInfo()
+                    //初始化选择数据
+                    this.testSubject = []
+                    this.evaluationInfo.paperInfo = []
+                    this.addSubjectBefore.length = 0
+                    this.newAddSubjects = []
+                    this.handelClass(data)
+                }
+            },
+            //判断是否存在学段信息
+            getTestType() {
+                if (this.evaluationInfo.school == '') {
+                    this.$Message.warning('请先选择测试学段!')
+                } else {
+                    if (this.getPeriodInfo(this.evaluationInfo.school).analysis !== undefined) {
+                        this.testType = this.getPeriodInfo(this.evaluationInfo.school).analysis.type
+                    } else {
+                        this.$Message.warning('请先前往基础设置增加测试类型设定!')
+                    }
+                }
+            },
+            //处理施测对象
+            getPeriodInfo(data) {
+                if (data !== '') {
+                    let gradeInfo = this.$store.state.schoolBaseInfo.schoolBaseInfo.period
+                    for (let item of gradeInfo) {
+                        if (item.id == data) {
+                            return item
+                        } 
+                    }
+                }
+            },
+            handelClass(data) {
+                //拼接年級和班級信息
+                let grade = []
+                let grades = []
+                let classData = this.$jsFn.groupBy(this.$store.state.schoolBaseInfo.classroomList, 'gradeId')
+                console.log(this.evaluationInfo.school)
+                grade = this.getPeriodInfo(this.evaluationInfo.school).grades
+                for (let i = 0; i < grade.length; i++) {
+                    for (let j = 0; j < classData.length; j++) {
+                        if (grade[i].id == classData[j][0].gradeId) {
+                            grade[i].class = classData[j]
+                        }
+                    }
+                    if (grade[i].class !== undefined) {
+                        let all = {
+                            'id': 'all+' + grade[i].id,
+                            'gradeId': grade[i].class[0].gradeId,
+                            'name': grade[i].name + '(全年级)'
+                        }
+                        grade[i].class.unshift(all)
+                        grades.push(grade[i])
+                    }
+                }
+                console.log(grades)
+                this.config.data = this.convertTree(grades, this.map)
+                console.log('8888888888888888888888888888888')
+                console.log(this.config.data)
+            },
             /**显示试卷分析 */
             showAnalysis() {
                 this.examAnalysisStatus = !this.examAnalysisStatus
@@ -364,9 +487,9 @@
              */
             getDate(value, flag) {
                 if (flag == 0) {
-                    this.evaluationInfo.startTime = new Date(value).getTime()/1000
+                    this.evaluationInfo.startTime = new Date(value).getTime()
                 } else if (flag == 1) {
-                    this.evaluationInfo.endTime = new Date(value).getTime()/1000
+                    this.evaluationInfo.endTime = new Date(value).getTime()
                 }
             },
             /**
@@ -393,60 +516,14 @@
                     this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = [...questions]
                 }
             },
-            getSelectedQuestion(data) {
-                this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = []
-                this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = data.questions
-            },
+            //getSelectedQuestion(data) {
+            //    this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = []
+            //    this.evaluationInfo.paperInfo[this.currentSubjectIndex].item = data.questions
+            //},
             goToPreview() {
                 this.activeTab = 'preview'
                 this.evaluationInfo.paperInfo[this.currentSubjectIndex].createType = 'manualPaper'
             },
-            deleteSubject(index) {
-                this.deleteIndex = index
-                this.$Modal.confirm({
-                    title: '删除科目',
-                    content: '确认删除' + this.evaluationInfo.paperInfo[index].periodName + '·' + this.evaluationInfo.paperInfo[index].subjectName + '吗?',
-                    onOk: () => {
-                        let periodIndex = -1
-                        for (let i in this.$store.state.schoolBaseInfo.schoolBaseInfo.period) {
-                            if (this.$store.state.schoolBaseInfo.schoolBaseInfo.period[i].id == this.evaluationInfo.paperInfo[index].periodCode) {
-                                periodIndex = i
-                            }
-                        }
-                        for (let i = 0; i < this.testSubjects[periodIndex].length; i++) {
-                            if (this.evaluationInfo.paperInfo[index].subjectCode == this.testSubjects[periodIndex][i]) {
-                                this.testSubjects[periodIndex].splice(i, 1)
-                            }
-                        }
-                        this.evaluationInfo.paperInfo.splice(this.deleteIndex, 1)
-                        this.currentSubjectIndex = 0
-                        this.deleteIndex = -1
-                        this.$Message.success('删除成功!')
-                    },
-                    onCancel: () => {
-                        this.deleteIndex = -1
-                    },
-                })
-            },
-            newAddSubject(index, i, code) {
-                if (!this.checkIsDisabled(index, code)) {
-                    let flag = true
-                    for (let j = 0; j < this.newAddSubjects.length; j++) {
-                        if (this.newAddSubjects[j].index == index && this.newAddSubjects[j].i == i) {
-                            flag = false
-                            this.newAddSubjects.splice(j, 1)
-                            break
-                        }
-                    }
-                    if (flag) {
-                        this.newAddSubjects.push({
-                            index, code,i
-                        })
-                    }
-                } else {
-                    alert('disabled')
-                }
-            },
             checkIsDisabled(index, code) {
                 if (this.addSubjectBefore[index] !== undefined) {
                     return this.addSubjectBefore[index].indexOf(code) !== -1
@@ -479,6 +556,39 @@
             //        this.evaluationInfo.paperInfo.length = 0
             //    }
             //},
+            deleteSubject(index) {
+                console.log(index)
+                this.deleteIndex = index
+                this.$Modal.confirm({
+                    title: '删除科目',
+                    content: '确认删除' + this.evaluationInfo.paperInfo[index].subjectName + '吗?',
+                    onOk: () => {
+                        if (this.deleteIndex !== undefined) {
+                            this.testSubjects[0].splice(this.deleteIndex, 1)
+                            this.evaluationInfo.paperInfo.splice(this.deleteIndex, 1)
+                            this.currentSubjectIndex = 0
+                            this.deleteIndex = -1
+                            this.$Message.success('删除成功!')
+                        }
+                        //let periodIndex = -1
+                        //for (let i in this.$store.state.schoolBaseInfo.schoolBaseInfo.period) {
+                        //    if (this.$store.state.schoolBaseInfo.schoolBaseInfo.period[i].id == this.evaluationInfo.paperInfo[index].periodCode) {
+                        //        periodIndex = i
+                        //    }
+                        //}
+                        //for (let i = 0; i < this.testSubjects.length; i++) {
+                        //    if (this.evaluationInfo.paperInfo[index].subjectCode == this.testSubjects[i]) {
+                        //        console.log(i)
+                        //        this.testSubjects.splice(i, 1)
+                        //    }
+                        //}
+                        
+                    },
+                    onCancel: () => {
+                        this.deleteIndex = -1
+                    },
+                })
+            },
             confirmAddSubject() {
                 let data = {
                     pk: 'Exam',
@@ -502,22 +612,44 @@
                     scope: this.mode,
                     create: Math.round(new Date() / 1000)
                 }
+                console.log(this.newAddSubjects.length)
                 for (let item of this.newAddSubjects) {
+                     let periodData = this.getPeriodInfo(this.evaluationInfo.school)
                     this.evaluationInfo.paperInfo.push({
-                        periodName: this.$store.state.schoolBaseInfo.schoolBaseInfo.period[item.index].name,
-                        periodId: this.$store.state.schoolBaseInfo.schoolBaseInfo.period[item.index].id,
-                        subjectName: this.$store.state.schoolBaseInfo.schoolBaseInfo.period[item.index].subjects[item.i].name,
-                        subjectId: this.$store.state.schoolBaseInfo.schoolBaseInfo.period[item.index].subjects[item.i].id,
+                        periodName: periodData.name,
+                        periodId: periodData.id,
+                        subjectName: periodData.subjects[item.i].name,
+                        subjectId: periodData.subjects[item.i].id,
                         createType: 'manualPaper',
                         score: 100,
                         item: [],
                         filter: {},
-                        name: this.evaluationInfo.name + '--' + this.$store.state.schoolBaseInfo.schoolBaseInfo.period[item.index].subjects[item.i].name
+                        name: this.evaluationInfo.name + '--' +periodData.subjects[item.i].name
                     })
                 }
+                console.log(this.evaluationInfo)
                 this.newAddSubjects.length = 0
                 this.addSubjectBefore.length = 0
             },
+            newAddSubject(index, i, code) {
+                if (!this.checkIsDisabled(index, code)) {
+                    let flag = true
+                    for (let j = 0; j < this.newAddSubjects.length; j++) {
+                        if (this.newAddSubjects[j].index == index && this.newAddSubjects[j].i == i) {
+                            flag = false
+                            this.newAddSubjects.splice(j, 1)
+                            break
+                        }
+                    }
+                    if (flag) {
+                        this.newAddSubjects.push({
+                            index, code, i
+                        })
+                    }
+                } else {
+                    alert('disabled')
+                }
+            },
             cancelAddSubject() {
                  this.addSubjectBefore = [...this.testSubjects]
             },
@@ -525,6 +657,7 @@
             getSchoolBaseInfo() {
                 this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(
                     (res) => {
+                        console.log(this.$store.state)
                         if (res.code == 2) {
                             alert('数据为空!')
                         }
@@ -537,42 +670,12 @@
                     (res) => {
                         if (res.code == 2) {
                             alert('数据为空!')
-                        } else {
-                            //拼接年級和班級信息
-                            let grade = []
-                            let grades = []
-
-                            let classData = this.$jsFn.groupBy(res.data, 'gradeId')
-                            for (let item of this.$store.state.schoolBaseInfo.schoolBaseInfo.period) {
-                                grade.push(...item.grades)
-                            }
-
-                            for (let i = 0; i < grade.length; i++) {
-                                for (let j = 0; j < classData.length; j++) {
-                                    if (grade[i].id == classData[j][0].gradeId) {
-                                        grade[i].class = classData[j]
-                                    }
-                                }
-                                if (grade[i].class !== undefined) {
-                                    let all = {
-                                        'id': 'all-' + grade[i].id,
-                                        'gradeId': grade[i].class[0].gradeId,
-                                        'name': grade[i].name + '(全年级)'
-                                    }
-                                    grade[i].class.unshift(all)
-                                    grades.push(grade[i])
-                                }
-                            }
-
-                            this.config.data = this.convertTree(grades, this.map)
-                            console.log(this.config.data)
-                        }
+                        } 
                     },
                     (err) => {
                         this.$Message.error('API error!')
                     }
                 )
-                console.log(this.$store.state)
             },
             /**
              * 查找教师课程下的班级
@@ -699,29 +802,50 @@
             saveEvaluation() {
                 console.log('最後數據')
                 console.log(this.evaluationInfo)
+
                 let data = {
                     pk: 'Exam',
-                    code: "Exam-" + this.$store.state.userInfo.schoolCode,
+                    code: this.$store.state.userInfo.schoolCode,
                     school: this.$store.state.userInfo.schoolCode,
-                    id: this.$jsFn.uuid(),
                     name: this.evaluationInfo.name,
                     creatorId: this.$store.state.userInfo.TEAMModelId,
-                    type: "union",
-                    period: {},
-                    grades: [],
-                    subjects: [],
-                    examType: {},
+                    type: this.evaluationInfo.type,
+                    period: {
+                        id: this.getPeriodInfo(this.evaluationInfo.school).id,
+                        name: this.getPeriodInfo(this.evaluationInfo.school).name
+                    },
+                    grades: this.gradeChoose,
+                    subjects: this.getPaperInfo(this.evaluationInfo.papers, this.evaluationInfo.paperInfo).subject,
+                    papers: this.getPaperInfo(this.evaluationInfo.papers, this.evaluationInfo.paperInfo).paper,
+                    examType: {
+                        id: this.evaluationInfo.examType,
+                        name: this.getexamTypeName(this.evaluationInfo.examType)
+                    },
                     year: new Date().getFullYear(),
                     range: this.mode,
                     source: this.evaluationInfo.evaType,
-                    targetClasseIds: [],
-                    startTime: this.evaluationInfo.startTime,
+                    targetClassIds: this.classChoose,
+                    startTime: Math.round(new Date()),
                     endTime: this.evaluationInfo.endTime,
                     progress: 'going',
                     scope: this.mode,
-                    create: Math.round(new Date() / 1000)
+                    createDate: Math.round(new Date())
                 }
                 console.log(data)
+                this.$api.learnActivity.SaveExamInfo(data).then(
+                    res => {
+                        if (res.error == null) {
+                            console.log(res)
+                            this.$Message.success('评测发布成功!')
+                            this.evaluationInfo.papers = res.exam
+                        } else {
+                            this.$Message.error('API ERROR!')
+                        }
+                    },
+                    err => {
+                        this.$Message.error('API ERROR!')
+                    }
+                )
                 //if (this.checkData()) {
                 //    this.handleData()
 
@@ -729,10 +853,55 @@
                 //    this.$Message.error('请完善基础信息,再保存!')
                 //}
             },
-            addSubject() {
-                [...this.addSubjectBefore] = this.testSubjects
-                this.addSubjectStatus = true
+            getexamTypeName(data) {
+                let key = ''
+                for (let item of this.getPeriodInfo(this.evaluationInfo.school).analysis.type) {
+                    if (item.id = data) {
+                        key = item.name
+                        return key
+                    } 
+                }
+            },
+            getPaperInfo(data,rule) {
+                if (data.length !== 0) {
+                    let info = {
+                        subject: [],
+                        paper: []
+                    }
+                    for (let i = 0; i < data.length; i++) {
+                        let sub = {}
+                        let paper = {}
+                        sub.id = data[i].subjectId
+                        sub.name = data[i].subjectName
+                        paper.id = data[i].id
+                        paper.code = data[i].code
+                        paper.name = data[i].name
+                        paper.blob = data[i].blob
+                        paper.scope = data[i].scope
+                        paper.multipleRule = rule[i].multipleRule
+                        paper.answers = []
+                        paper.point = []
+                        for (let k = 0; k < data[i].scoring.length; k++) {
+                            paper.answers.push(data[i].scoring[k].ans)
+                            paper.point.push(data[i].scoring[k].score)
+                        }
+                        info.subject.push(sub)
+                        info.paper.push(paper)
+     
+                    }
+                    return info
+                }
+            },
 
+            addSubject() {
+                if (this.evaluationInfo.school !== '') {
+                    this.testSubject.length = []
+                    this.testSubject.push(this.getPeriodInfo(this.evaluationInfo.school))
+                    this.addSubjectBefore = [...this.testSubjects]
+                    this.addSubjectStatus = true
+                } else {
+                    this.$Message.warning('请先选择测试学段!')
+                }
             },
             //处理树结构数据
             convertTree(tree, map) {
@@ -749,6 +918,7 @@
                     }
                     if (children !== undefined) {
                         children.map(item => {
+                            console.log(item)
                             item['type'] = 'class'
                             item = delete item.children
                         })
@@ -759,11 +929,13 @@
                         children
                     })
                 })
+
                 return result
             }
         },
         created() {
             let routerData = this.$route.params.evaluationInfo
+            console.log(routerData)
             if (routerData !== undefined) {
                 this.startTime = new Date(routerData.startTime)    
                 this.endTime = new Date(routerData.endTime)   
@@ -771,7 +943,6 @@
                     routerData.paperInfo[i].createType = 'manualPaper'
                 }
                 this.evaluationInfo = routerData
-
                 /**
                 处理无接口数据时返回为个人课程或校本课程
                 */  
@@ -786,10 +957,18 @@
             this.findClassroom()
         },
         mounted() {
+            console.log(this.$store)
             this.mode = this.$route.query.type
+            this.getSchoolBaseInfo()
             if (this.mode == 'class') {
                 this.getClassType()
             }
+        },
+        watch: {
+            evaluationInfo() {
+                deep:true
+                console.log('88888888888')
+            }
         }
     }
 </script>

+ 63 - 31
TEAMModelOS/ClientApp/src/view/learnactivity/ManageEvaluation.vue

@@ -4,6 +4,19 @@
         <div class="evaluation-list-wrap">
             <div class="evaluation-list-title">
                 <span>评测列表</span>
+                <!--<Poptip trigger="hover" placement="bottom" offset="-8">
+                    <Icon type="ios-funnel" :class="evaluationList.length == 0 ? 'custom-label-disabeld to-create-icon':'to-create-icon'" size="16" style="padding-top:1px" />
+                    <div slot="content">
+                        <div style="margin-top:5px;margin-bottom:10px;">
+                            <span>学段:</span>
+                            <Select v-model="filterPeriod" style="width:80px" size="small" clearable @on-change="filterByPeriod">
+                                <Option v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :value="item.id" :key="index">
+                                    {{ item.name }}
+                                </Option>
+                            </Select>
+                        </div>
+                    </div>
+                </Poptip>-->
                 <Icon type="md-add" class="to-create-icon" size="20" @click="goToCreate" title="新建" />
                 <Icon type="md-trash" :class="evaluationList.length == 0 ? 'custom-label-disabeld to-create-icon':'to-create-icon'" title="删除" @click="deleteEvaluation" />
                 <Icon type="md-create" :class="evaluationList.length == 0 ? 'custom-label-disabeld to-create-icon':'to-create-icon'" @click="editEvaluation" title="编辑" />
@@ -17,16 +30,16 @@
                         <p class="evaluation-type">
                             <Icon type="md-time" color="#a5a5a5" style="margin-right:5px;" size="16" />
                             <span>施测时间:{{dateFormat(item.startTime)}}</span>
-                            <span class="evaluation-status-tag" :style="{ background: (item.state === 100 ? '#0BADD4' : item.state === 200 ? '#1CC0F3' : '#949594')}">{{ item.state === 100 ? '待发布' : item.state === 200 ? '进行中' : '已结束' }}</span>
+                            <span class="evaluation-status-tag" :style="{ background: (item.progress == 'pending' ? '#0BADD4' : item.progress == 'going' ? '#1CC0F3' : '#949594')}">{{ item.progress == 'pending' ? '待发布' : item.progress == 'going' ? '进行中' : '已结束' }}</span>
                         </p>
                         <div style="display:inline-flex">
                             <p class="evaluation-type">
                                 <Icon type="ios-cube" color="#a5a5a5" style="margin-right:5px;" size="16" />
-                                <span>评测类型:{{getTypeLabel(item.type)}}</span>
+                                <span>评测类型:{{item.type}}</span>
                             </p>
                             <p class="evaluation-type">
                                 <Icon type="ios-cube" color="#a5a5a5" style="margin-right:5px;" size="16" />
-                                <span>施测对象:{{getTypeLabel(item.type)}}</span>
+                                <span>施测人数:{{item.stuCount}}</span>
                                 <!--<span v-for="(item,index) in targetList" :value="item.classroomCode" :key="index">{{ item.classroomName }}</span>-->
                             </p>
                         </div>
@@ -49,9 +62,9 @@
                     <div class="evaluation-test-paper-header">
                         <span>测试科目:</span>
                         <span v-if="examPaperList.length > 0" v-for="(item,index) in examPaperList" :key="index" :class="index == currentSubjectIndex ? 'subject-item subject-item-active':'subject-item'" @click="selectSubject(index)">
-                            {{jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodCode).periodName}}
-                            <span style="margin:0px 2px;">·</span>
-                            {{jsFn.getSubjectName(jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodCode), item.subjectCode)}}
+                            <!--{{item.period}}
+                            <span style="margin:0px 2px;">·</span>-->
+                            {{item.subjectName}}
                         </span>
                     </div>
                     <div class="test-paper-detail">
@@ -62,7 +75,7 @@
                             </div>
                             <!--试卷题目信息-->
                             <div v-if="examPaperList.length > 0">
-                                <TestPaper :paper="examPaperList[currentSubjectIndex]" style="color:#515a6e;margin-top:-10px;" :isShowTools="isShowTools"></TestPaper>
+                                <TestPaper :paper="examPaperList[currentSubjectIndex].papers" style="color:#515a6e;margin-top:-10px;" :isShowTools="isShowTools"></TestPaper>
                             </div>
                             <EmptyData v-else style="margin-top:60px;"></EmptyData>
                         </vuescroll>
@@ -174,6 +187,7 @@
                         label:'定时发布'
                     }
                 ],
+                showPaperInfo: {},
                 startTime:''
             }
         },
@@ -250,7 +264,7 @@
             confirmDeleteEvaluation() {
                 let examData = {
                     id: this.evaluationList[this.avtiveEvaluationIndex].id,
-                    pk: this.evaluationList[this.avtiveEvaluationIndex].code
+                    code: this.evaluationList[this.avtiveEvaluationIndex].code
                 }
                 this.$api.learnActivity.DeleteExamInfo(examData).then(
                     res => {
@@ -438,13 +452,16 @@
                 }
             },
             selectSubject(index) {
+                console.log(index)
+                //this.showPaperInfo = {}
                 this.currentSubjectIndex = index
-                this.groupQuestion = {}
-                let groupResult = jsFn.groupBy(this.examPaperList[this.currentSubjectIndex].item, 'type')
-                for (let i = 0; i < groupResult.length; i++) {
-                    this.groupQuestion[groupResult[i][0].type] = groupResult[i]
-                }
-                this.handleBackToTop()
+                //this.showPaperInfo = this.
+                //this.groupQuestion = {}
+                //let groupResult = jsFn.groupBy(this.examPaperList[this.currentSubjectIndex].item, 'type')
+                //for (let i = 0; i < groupResult.length; i++) {
+                //    this.groupQuestion[groupResult[i][0].type] = groupResult[i]
+                //}
+                //this.handleBackToTop()
             },
             getDate() {
             },
@@ -468,6 +485,7 @@
                 this.startTime = this.dateFormat( start)
             },
             selectEvaluation(index) {
+                console.log(index)
                 this.currentBraIndex = 0
                 this.avtiveEvaluationIndex = index
                 this.getMyDate(this.evaluationList[this.avtiveEvaluationIndex].startTime, this.evaluationList[this.avtiveEvaluationIndex].endTime)
@@ -475,12 +493,12 @@
             },
             findEvaluation() {
                 let requestData = {
-                    code: this.$store.state.userInfo.TEAMModelId
+                    code: this.$store.state.userInfo.schoolCode
                 }
                 this.$api.learnActivity.FindExamInfo(requestData).then(
                     res => {
                         if (res.error == null) {
-                            this.evaluationList = res.result.data
+                            this.evaluationList = res.examInfo
                             console.log(this.evaluationList)
                             if (this.evaluationList.length > 0) {
                                 this.selectEvaluation(0)
@@ -495,29 +513,43 @@
             },
             findExamPaper() {
                 let requestData = {
-                    code: this.evaluationList[this.avtiveEvaluationIndex].id
+                    id: this.evaluationList[this.avtiveEvaluationIndex].id,
+                    code: this.evaluationList[this.avtiveEvaluationIndex].code
                 }
-                this.$api.learnActivity.FindExamPaper(requestData).then(
+                this.$api.learnActivity.FindExamInfos(requestData).then(
                     res => {
                         if (res.error == null) {
-                            this.examPaperList = res.result.data
-                            this.groupQuestion = {}
-                            if (this.examPaperList.length > 0) {
-                                let groupResult = jsFn.groupBy(this.examPaperList[0].item, 'type')
-                                for (let i = 0; i < groupResult.length; i++) {
-                                    this.groupQuestion[groupResult[i][0].type] = groupResult[i]
-                                }
-                            } else {
-                                this.groupQuestion = {}
-                            }
+                         this.getPaperData(res.examInfo[0])
                         } else {
                             this$Message.error('API ERROR!')
                         }
                     },
                     res => {
-                    }
-                )
+                    })
             },
+            async getPaperData(dataInfo) {
+                this.examPaperList = []
+                for (let i = 0; i < dataInfo.papers.length; i++) {
+                    let resData = {}
+                    console.log(dataInfo)
+                    resData.period = dataInfo.period.name
+                    resData.subjectName = dataInfo.subjects[i].name
+                    resData.class = dataInfo.targetClassIds
+                    resData.id = dataInfo.id
+                    resData.papers = await this.$evTools.getFullPaper(dataInfo.papers[i])
+                    this.examPaperList.push(resData)
+                }
+                //this.showPaperInfo = this.examPaperList[this.currentSubjectIndex].papers
+            
+                //if (this.examPaperList.length > 0) {
+                //    let groupResult = jsFn.groupBy(this.examPaperList[0].item, 'type')
+                //    for (let i = 0; i < groupResult.length; i++) {
+                //        this.groupQuestion[groupResult[i][0].type] = groupResult[i]
+                //    }
+                //} else {
+                //    this.groupQuestion = {}
+                //}
+            }
         },
         mounted() {
             //setTimeout(() => {
@@ -531,7 +563,7 @@
             Date.prototype.toLocaleString = function () {
                 return this.getFullYear() + "/" + (this.getMonth() + 1) + "/" + this.getDate();
             }
-            //this.findEvaluation()
+            this.findEvaluation()
             //this.findClassroom()
         }
     }

+ 15 - 3
TEAMModelOS/ClientApp/src/view/learnactivity/ManualCreate.vue

@@ -139,7 +139,11 @@
                 default: () => {
                     return []
                 }
-            }
+            },
+			subjectId:{
+				type:String,
+				default:''
+			}
         },
         components: {
             QuestionList,
@@ -183,6 +187,7 @@
             }
         },
         mounted() {
+			console.log(this.subjectId)
             //this.getResultCount()
             this.queryQuestionByPage()
             this.schoolPeriod = this.$store.state.schoolBaseInfo.schoolBaseInfo.period
@@ -294,7 +299,7 @@
                     "code": code,
                     "periodId": this.deleteAll(this.manualFilter.periodCode),
                     "gradeIds[*]": [],
-                    "subjectId": [],
+                    "subjectId": [this.subjectId],
                     "level": this.deleteAll(this.manualFilter.level),
                     "type": this.deleteAll(this.manualFilter.type),
                     "field": [],
@@ -378,7 +383,14 @@
                     return []
                 }
             }
-        }
+        },
+		watch:{
+			subjectId:{
+				handler(n){
+					this.queryQuestionByPage()
+				}
+			}
+		}
     }
 </script>
 <style lang="less">

+ 5 - 1
TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.less

@@ -1,4 +1,4 @@
-@main-bgColor: rgb(40,40,40); //主背景颜色
+@main-bgColor: rgb(40,40,40); //主背景颜色
 @borderColor: #424242;
 @primary-textColor: #fff; //文本主颜色
 @second-textColor: #a5a5a5; //文本副级颜色
@@ -113,4 +113,8 @@
             display: flex;
         }
     }
+}
+
+.ivu-tabs .ivu-tabs-content-animated{
+    height:100%;
 }

+ 4 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue

@@ -108,8 +108,10 @@
              * 预览试卷
              * @param index
              */
-           async previewTestPaper(index) {
-                let data = await this.$evTools.getFullPaper(this.paperList[index])
+            async previewTestPaper(index) {
+                console.log(this.paperList[index])
+               let data = await this.$evTools.getFullPaper(this.paperList[index])
+
                 this.previewPaper = data
                 this.previewStatus = true
             },

+ 39 - 33
TEAMModelOS/ClientApp/src/view/learnactivity/MultiCascader.vue

@@ -8,13 +8,12 @@
                 <Cascader :data="data"
                           style="display: inline-block; width: 100%"
                           v-model="cascader"
-
                           @on-visible-change="toggleMenu"
                           transfer
                           @on-change="(value, selectedData) => handleChange(value, selectedData)" >
                     <span v-show="noSel && !filterable" :class="[prefixCls + '-placeholder']" style="display: inline">{{ placeholder }}</span>
                     <div v-if="noSel" class="ivu-tag" style="background: none;"></div>
-                    <div class="ivu-tag" v-for="(item, index) in selData" :key="item.value" style="display: inline-block;color:#fffff">
+                    <div class="ivu-tag" v-for="(item, index) in selData" :key="item.value" style="display: inline-block;color:#fffff;min-height:25px">
                         <span class="ivu-tag-text">{{ item.name }}</span>
                         <span class="ivu-tag-text">{{ item.label }}</span>
                         <Icon type="ios-close-empty" @click.native.stop="removeTag(index)"></Icon>
@@ -162,7 +161,12 @@
             this.$emit('son',false);
           }
         }
-      }
+        },
+        data(newV,oldV) {
+            deep: true;
+            this.noSel = true
+            this.selData = []
+        }
     },
     computed: {
       classes () {
@@ -208,7 +212,7 @@
         let data = [];
         if (value) {
           for (let i = 0; i < value.length; i++) {
-              let ob = { value: value[i].id, label: value[i].name, type: value[i].type, _value: value[i]._value}
+              let ob = { value: value[i].id, label: value[i].name, type: value[i].type, __value: value[i].__value}
             data.push(ob);
           }
         }
@@ -218,10 +222,7 @@
         else self.noSel = true;
         self.selData = data.concat()
         self.propData = data.concat()
-          self.setValue(self.propData);
-          console.log(self.selData)
-          console.log(self.propData)
-          console.log(self.setValue)
+        self.setValue(self.propData);
       },
       // 设置值
       setValue(val) {
@@ -260,10 +261,9 @@
         return false;
       },
       handleChange (value, selectedData) {
-          let self = this;
-          console.log(selectedData)
+        let self = this;
         let val = selectedData[selectedData.length-1];
-          let _val = { value: val.value, label: val.label, type: val.type, _value: val._value};
+        let _val = { value: val.value, label: val.label, type: val.type, __value: val.__value};
         if (!self.isInArray(self.selData, val)) {
           if (self.addTag) {
             self.addTag = false;
@@ -280,8 +280,11 @@
           }
           let reData = []
           for (let i = 0; i < self.selData.length; i++) {
-              if (self.selData[i].type == undefined) {
-                 reData.push(self.selData[i])
+              let str = self.selData[i].value
+              let code = str.split('+')
+              if (code.length > 1 && code[0] === 'all') {
+                  self.selData[i].grade = code[1]
+                  reData.push(self.selData[i])
               }
           }
           this.getSelectData(reData)
@@ -290,29 +293,32 @@
             let self = this
             for (let i = 0; i < data.length; i++) {
                 for (let k = 0; k < self.selData.length; k++) {
-                    if (self.selData[k].__value !== undefined) {
-                        let str = self.selData[k].__value
-                        let code = str.split(',')
-                        if (data[i].value === code[0]) {
+                    if (self.selData[k].grade == undefined) {
+                        let code = (self.selData[k].__value || "").split(',')
+                        if (data[i].grade == code[0]) {
                             self.selData.splice(k, 1); 
                             k--; // 如果不减,将漏掉一个元素
                         }
                     }
                 }
             }
+            self.setValue(self.selData);
+        },
+        toggleMenu(visible) {
+            let self = this;
+            if (self.data.length == 0) {
+                this.$Message.warning('请先选择测试学段!')
+            }
+            if (this.disabled || this.autoComplete) {
+                return false;
+            }
+            // 关闭
+            if (!visible) {
+                self.addTag = true;
+                self.cascader = []
+            }
+            this.visible = !this.visible;
         },
-      toggleMenu (visible) {
-        let self = this;
-        if (this.disabled || this.autoComplete) {
-          return false;
-        }
-        // 关闭
-        if (!visible) {
-          self.addTag = true;
-          self.cascader = []
-        }
-        this.visible = !this.visible;
-      },
     }
   }
 </script>
@@ -327,12 +333,12 @@
     }
 
     .selection-container {
-        margin-bottom: 10px;
+        margin-bottom: 0px;
         border: 1px solid #dddee1;
         width: 100%;
         border-radius: 4px;
-        min-height: 40px;
-        padding: 5px;
+        min-height: 30px;
+        padding: 0px;
         position: relative;
         cursor: pointer;
         /*background-color: white;*/
@@ -344,7 +350,7 @@
         align-items: center;
         flex-wrap: wrap;
         width: 100%;
-        padding-right: 5px;
+        padding-right: 0px;
     }
     .ivu-tag-text {
     color: #ffff;

+ 30 - 10
TEAMModelOS/ClientApp/src/view/newcourse/MyCourse.vue

@@ -91,7 +91,7 @@
                 <div class="course-classroom-info-header" style="padding-right:50px;">
                     <span @click="tabName = 'record'" :class="tabName == 'record' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">课堂记录</span>
                     <span @click="tabName = 'stus'" :class="tabName == 'stus' ? 'course-classroom-label line-bottom line-bottom-active':'course-classroom-label line-bottom'">{{$t('courseManage.classroom.studentList')}}</span>
-                    <div style="float:right;" v-if="listType == 'private'">
+                    <div style="float:right;" v-if="listType == 'private' && tabName == 'stus'">
                         <span class="disable-text-icon action-btn-wrap">
                             <Icon type="md-add" size="16" />
                             添加学生
@@ -112,12 +112,18 @@
                 </div>
                 <div class="course-classroom-info-content dark-iview-table animated fadeIn" v-show="tabName == 'stus'">
                     <vuescroll style="height:100%;">
-                        <Table :columns="studentColumn" :data="students" 
+                        <Table :columns="studentColumn" :data="students"
                                :height="tableHeight" class="system-classroom-table" :loading="stuLoading" no-data-text="暂无学生">
                             <Loading slot="loading" bgColor="rgba(103, 103, 103, 0.27)"></Loading>
                             <template slot-scope="{ row ,index}" slot="action">
                                 <strong></strong>
                             </template>
+                            <template slot-scope="{ row, index }" slot="groupId">
+                                <span>{{row.groupId ? row.groupId : '- -'}}</span>
+                            </template>
+                            <template slot-scope="{ row, index }" slot="groupName">
+                                <span>{{row.groupName ? row.groupName : '未分组'}}</span>
+                            </template>
                         </Table>
                     </vuescroll>
                 </div>
@@ -286,14 +292,14 @@
                     },
                     {
                         title: this.$t('courseManage.classroom.studentTableC5'),
-                        key: 'groupId',
+                        slot: 'groupId',
                         //width: 150,
                         align: 'center',
                         sortable: true
                     },
                     {
                         title: this.$t('courseManage.classroom.studentTableC6'),
-                        key: 'groupName',
+                        slot: 'groupName',
                         //width: 150,
                         align: 'center'
                     }
@@ -463,7 +469,20 @@
                         this.saveNotice()
                     } else {
                         this.baseEditStatus = !this.baseEditStatus
-                        this.$Message.warning('暂未对接API!')
+                        console.log(this.courseListS)
+                        //this.$Message.warning('暂未对接API!')
+                        this.$api.courseMgmt.upsertNotice(this.courseListS[this.curCusIndex][this.curClassIndex]).then(
+                            res => {
+                                if (!res.error) {
+                                    this.$Message.success('保存成功')
+                                } else {
+                                    this.$Message.error('保存失败')
+                                }
+                            },
+                            err => {
+                                this.$Message.error('保存失败')
+                            }
+                        )
                     }
                 }
             },
@@ -616,15 +635,16 @@
                     title: '删除课程',
                     content: `确认删除${this.courseListP[this.curCusIndex].name}吗?`,
                     onOk:()=> {
-                        this.$Message.warning('暂未对接API')
+                        //this.$Message.warning('暂未对接API')
                         this.$api.courseMgmt.deleteCourse({
-                            id: '',
-                            code: '',
-                            scope: ''
+                            id: this.courseListP[this.curCusIndex].id,
+                            code: this.courseListP[this.curCusIndex].code,
+                            scope: this.courseListP[this.curCusIndex].scope
                         }).then(
                             res => {
                                 if (!res.error) {
                                     let index = this.curCusIndex
+                                    this.curCusIndex = 0
                                     this.courseListP.splice(index,1)
                                     this.$Message.success('删除成功!')
                                 } else {
@@ -757,7 +777,7 @@
                         return []
                     }
                 } else if (this.listType == 'private') {
-                    if (this.courseListP[this.curCusIndex] && this.courseListP[this.curCusIndex].classes && this.courseListP[this.curCusIndex].classes[this.curClassIndex].students) {
+                    if (this.courseListP[this.curCusIndex] && this.courseListP[this.curCusIndex].classes && this.courseListP[this.curCusIndex].classes[this.curClassIndex]) {
                         return this.courseListP[this.curCusIndex].classes[this.curClassIndex].students
                     } else {
                         return []

+ 32 - 9
TEAMModelOS/ClientApp/src/view/newcourse/NewCoursePlan.vue

@@ -144,13 +144,15 @@
                     })
                 }
                 if (!this.isInit) {
+                    console.log(1)
                     this.updated = true
                 }
             },
             //处理选择课程事件
-            selectCus(data,index) {
-                this.classListShow[this.curClassIndex].cusSetting.courses[index].course.id = data.value
-                this.classListShow[this.curClassIndex].cusSetting.courses[index].course.name = data.label
+            selectCus(data, index) {
+                console.log(2)
+                this.classListShow[this.curClassIndex].cusSetting.courses[index].course.id = data.value ? data.value : ''
+                this.classListShow[this.curClassIndex].cusSetting.courses[index].course.name = data.label ? data.label : ''
                 this.isInit = true
                 this.updated = true
             },
@@ -296,12 +298,33 @@
                 this.importData.length = 0
             },
             selectClass(index) {
-                console.log('0.0.0.0')
-                console.log(this.classListShow[index])
-                if (!this.classListShow[index].cusSetting) {
-                    this.findClassPlan(index)
+                if (this.updated) {
+                    this.$Modal.confirm({
+                        render: (h) => {
+                            return h('h3', {
+                                style: {
+                                    textAlign: 'center'
+                                },
+                                domProps: {
+                                    innerText: '当前班级排课数据尚未保存。如果离开,修改的数据将会丢失!'
+                                }
+                            })
+                        },
+                        onOk: () => {
+                            this.updated = false
+                            if (!this.classListShow[index].cusSetting) {
+                                this.findClassPlan(index)
+                            }
+                            this.curClassIndex = index
+                        }
+                    })
+                } else {
+                    if (!this.classListShow[index].cusSetting) {
+                        this.findClassPlan(index)
+                    }
+                    this.curClassIndex = index
                 }
-                this.curClassIndex = index
+                
             },
             //根据班级查询课程安排
             findClassPlan(index) {
@@ -336,7 +359,7 @@
                     ).finally(() => {
                         setTimeout(() => {
                             this.isLoading = false
-                        },)
+                        },500)
                     })
                 }
             }

+ 9 - 1
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.less

@@ -75,6 +75,10 @@
 
                 &-tool {
                     cursor: pointer;
+					
+					.ivu-btn:before{
+						background-color: none;
+					}
                 }
 
                 .ivu-icon {
@@ -87,9 +91,13 @@
 					background: transparent;
 					border: none;
 					color:#DCDCDC;
-					padding: 0;
+					padding: 0 10px;
 					margin-bottom: 3px;
 					
+					&::before{
+						background-color: none;
+					}
+					
 					&:focus{
 						border: none;
 					}

+ 15 - 9
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -30,7 +30,7 @@
 								<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>
-									<span class="qn-item-status" :style="{ background: (item.progress === 'pending' ? '#0BADD4' : item.progress === 'going' ? '#1CC0F3' : '#949594')}">{{ item.progress === 'pending' ? '待发布' : item.progress === 'going' ? '进行中' : '已结束' }}</span>
+									<span class="qn-item-status" :style="{ background: (item.progress === 'pending' ? '#0BADD4' : item.progress === 'going' ? '#12a568' : '#949594')}">{{ item.progress === 'pending' ? '待发布' : item.progress === 'going' ? '进行中' : '已结束' }}</span>
 								</div>
 							</div>
 						</div>
@@ -65,7 +65,7 @@
 				<div class="qn-box-header">
 					<span>问卷数据</span>
 					<div class="qn-box-header-tools" v-show="!isEmptyData">
-						<div class="qn-box-header-tools-tool" style="margin-right: 25px;" v-show="currentQn.progress !== 'finish'">
+						<div class="qn-box-header-tools-tool" style="margin-right: 25px;" v-show="currentQn.progress !== 'finish' && editable">
 							<Icon type="md-list-box" color="#dcdcdc" />
 							<Dropdown @on-click="onAddItem">
 								<Button>
@@ -83,14 +83,13 @@
 							<Icon type="md-podium" color="#dcdcdc" />
 							<span>查看统计数据</span>
 						</div>
-						<div class="qn-box-header-tools-tool" @click="onEditQn" v-show="currentQn.progress !== 'finish' && qnList.length && !editable">
+						<div class="qn-box-header-tools-tool" @click="onEditQn" v-show="currentQn.progress === 'pending' && qnList.length && !editable">
 							<Icon type="md-create" color="#209460" />
 							<span>编辑问卷</span>
 						</div>
 						
-						<div class="qn-box-header-tools-tool" @click="onSaveQn" v-show="editable" style="margin-right: 20px;">
-							<Icon type="md-folder" color="#209460" />
-							<span>保存问卷</span>
+						<div class="qn-box-header-tools-tool" v-show="editable" style="margin-right: 20px;">
+							<Button class="btn-save" icon="md-folder" :loading="isBtnLoading"  @click="onSaveQn">保存问卷</Button>
 						</div>
 						
 						<div class="qn-box-header-tools-tool" @click="onCancelEditQn" v-show="editable">
@@ -122,6 +121,7 @@
 				isEmptyData:true,
 				isLoading: false,
 				isLoadList: false,
+				isBtnLoading:false,
 				isEdit: false,
 				editable: false,
 				qnList: [],
@@ -264,7 +264,7 @@
 				this.currentRecord && this.makeItemResult(this.currentRecord)
 				this.activeQnIndex = hasNewQn ? this.qnList.indexOf(item) : index
 				this.$refs.qnForm.qnFormEdit = false
-				this.onCancelEditQn()
+				this.editable = false
 			},
 
 			/* 保存问卷操作 */
@@ -275,6 +275,7 @@
 				let qnItems = this.$refs.qnPaper.items || []
 				// 获取到基础信息 以及 题目数据 拼接保存
 				qnBaseInfo.questions = qnItems
+				this.isBtnLoading = true
 				this.saveorUpdataQn({
 					survey: qnBaseInfo,
 					reset: false
@@ -282,11 +283,13 @@
 					this.$Message.success('操作成功')
 					this.$refs.qnForm.qnFormEdit = false
 					this.isLoading = false
+					this.isBtnLoading = false
 					this.onAddSuccess()
 				}).catch(error => {
 					this.$Message.error(`操作失败,错误信息为${ error }`)
 					this.$refs.qnForm.qnFormEdit = false
 					this.isLoading = false
+					this.isBtnLoading = false
 				})
 			},
 			
@@ -369,8 +372,11 @@
 			},
 			
 			onCancelEditQn(){
+				console.log(this.activeQnIndex)
 				this.editable = false
 				this.$refs.qnForm.qnFormEdit = false
+				this.onQnClick(this.currentQn,this.activeQnIndex)
+				console.log(this.currentQn)
 			},
 
 			/* 取消发布问卷 */
@@ -382,8 +388,8 @@
 					cancelText: '取消',
 					onOk: () => {
 						this.isLoading = true
-						this.$api.questionnaire.CancelSurvey(this.currentQn.id).then(res => {
-							if (res.result.data) {
+						this.$api.questionnaire.CancelSurvey({surveyId : this.currentQn.id}).then(res => {
+							if (!res.error) {
 								this.isLoading = false
 								this.$Message.success('操作成功')
 								this.getQnList()

+ 9 - 5
TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue

@@ -651,8 +651,11 @@
                 this.keyword = ''
                 this.filterClassname()
             },
-            watchUpdate() {
-                this.updated = true
+            watchUpdate(data) {
+                if (data) {
+                    this.updated = true
+                }
+                console.log(data)
             },
             dataSort(data){
                 switch (this.orderBy) {
@@ -1004,6 +1007,7 @@
                                         this.$Message.success(this.$t('schoolBaseInfo.csTips3'))
                                         this.updated = false
                                         if (option == 'insert') {
+                                            this.classroomListShow[this.curClassIndex].code = 'Class-'+ this.classroomListShow[this.curClassIndex].code
                                             this.classroomList.unshift(this.classroomListShow[this.curClassIndex])
                                         }
                                     }
@@ -1119,7 +1123,7 @@
                                         textAlign: 'center'
                                     },
                                     domProps: {
-                                        innerText: '您修改信息后还未保存,如果修改的离开数据将会丢失!'
+                                        innerText: '当前班级信息尚未保存,切换到其他班级数据将会丢失!'
                                     }
                                 })
                             },
@@ -1245,8 +1249,8 @@
                     },
                     periodId:'',
                     gradeId: '',
-                    x: 5,
-                    y: 5,
+                    x: 20 * (this.classroomList.length % 5),
+                    y: 20 * (this.classroomList.length / 5).toFixed(0),
                     scope:'school',
                     option:'insert'
                 })

+ 6 - 6
TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/SystemSetting.less

@@ -326,7 +326,7 @@
 
     .term-list {
         width: 70%;
-        height: 100%;
+        height: ~"calc(100% - 50px)";
         border-right: 1px solid var(--border-color);
 
         &::-webkit-scrollbar { /*滚动条整体样式*/
@@ -400,13 +400,13 @@
         position: absolute;
         left: 70%;
         width: 30%;
-        height: 100%;
+        height: ~"calc(100% - 50px)";
         color: var(--label-text-color);
-        .fl-col-center;
 
         ul {
-            position: relative;
             list-style: none;
+            width: fit-content;
+            margin: auto;
         }
 
         li {
@@ -423,8 +423,8 @@
 
         .time-label {
             width: 35px;
-            text-align:center;
-            font-size:14px;
+            text-align: center;
+            font-size: 14px;
         }
 
         .time-dot {

+ 66 - 40
TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/SystemSetting.vue

@@ -34,7 +34,7 @@
                             <Draggable ghost-class="ghost" class="period-list list-group" :list="schoolSetting.period" :animation='200'>
                                 <div class="period-item list-group-item" v-for="(item,index) in schoolSetting.period" :key="index" @click.capture="choosePeriod(index)" :class="index == curPriodIndex ? 'block-bg-active block-bg':'block-bg'">
                                     <p class="period-item-name semester-name-label dark-iview-input" @click.stop>
-                                        <Input v-model="item.name" :disabled="editPrdIndex !== index" placeholder="设置学段..." style="width: 180px" />
+                                        <Input @dblclick.native="editPrdIndex = curPriodIndex"  v-model="item.name" :disabled="editPrdIndex !== index" placeholder="设置学段..." style="width: 180px" />
                                         <span class="campus-label" @click="setCampus">
                                             {{item.campusId === null ? '请设置校区': $JSONPath.query(schoolSetting, "$..campuses[?(@.id=='" + item.campusId + "')]").length > 0 ? $JSONPath.query(schoolSetting, "$..campuses[?(@.id=='" + item.campusId + "')]")[0].name : '请设置校区' }}
                                         </span>
@@ -56,39 +56,42 @@
                             <div class="col-body">
                                 <div class="no-data-text" v-if="!schoolSetting.period[curPriodIndex].semesters.length">{{$t('schoolBaseInfo.noSemester')}}</div>
                                 <div class="term-list dark-iview-input disabled-iview-input dark-iview-select disabled-iview-select" v-if="schoolSetting.period[curPriodIndex].semesters.length">
-                                    <div v-for="(item,index) in schoolSetting.period[curPriodIndex].semesters" :key="index" :class="index == curSemIndex ? 'term-item block-bg block-bg-active':'term-item block-bg'" @click.capture="chooseSemester(index)">
-                                        <span class="term-item-name-line" :style="{backgroundColor: colorList[index]}"></span>
-                                        <p class="semester-name-label" @click.stop>
-                                            <Input v-model="item.name" :disabled="editSemIndex !== index" placeholder="设置学期..." style="width: 180px" />
-                                        </p>
-                                        <div class="term-item-start" @click.stop>
-                                            <span>{{$t('schoolBaseInfo.startDate')}}</span>
-                                            <Select v-model="item.month" style="width:50px" placeholder="月" :disabled="editSemIndex !== index">
-                                                <Option v-for="(item,index) in monthList" :value="(index + 1)" :key="index">{{ item }}</Option>
-                                            </Select>
-                                            <span> / </span>
-                                            <Select v-model="item.day" style="width:50px" placeholder="日" :disabled="editSemIndex !== index">
-                                                <Option v-for="(item,index) in dayList" :value="(index + 1)" :key="index">{{ item }}</Option>
-                                            </Select>
+                                    <vuescroll>
+                                        <div v-for="(item,index) in schoolSetting.period[curPriodIndex].semesters" :key="index" :class="index == curSemIndex ? 'term-item block-bg block-bg-active':'term-item block-bg'" @click.capture="chooseSemester(index)">
+                                            <span class="term-item-name-line" :style="{backgroundColor: colorList[index]}"></span>
+                                            <p class="semester-name-label" @click.stop>
+                                                <Input @dblclick.native="editSemIndex = curSemIndex" v-model="item.name" :disabled="editSemIndex !== index" placeholder="设置学期..." style="width: 180px" />
+                                            </p>
+                                            <div class="term-item-start" @click.stop>
+                                                <span>{{$t('schoolBaseInfo.startDate')}}</span>
+                                                <Select  @dblclick.native="editSemIndex = curSemIndex" v-model="item.month" style="width:50px" placeholder="月" :disabled="editSemIndex !== index">
+                                                    <Option v-for="(item,index) in monthList" :value="(index + 1)" :key="index">{{ item }}</Option>
+                                                </Select>
+                                                <span> / </span>
+                                                <Select  @dblclick.native="editSemIndex = curSemIndex" v-model="item.day" style="width:50px" placeholder="日" :disabled="editSemIndex !== index">
+                                                    <Option v-for="(item,index) in dayList" :value="(index + 1)" :key="index">{{ item }}</Option>
+                                                </Select>
+                                            </div>
+                                            <p class="term-item-students-num">{{$t('schoolBaseInfo.semesterDuration')+ item.days + $t('schoolBaseInfo.dayUnit')  }}</p>
                                         </div>
-                                        <p class="term-item-students-num">{{$t('schoolBaseInfo.semesterDuration')+ item.days + $t('schoolBaseInfo.dayUnit')  }}</p>
-                                    </div>
+                                    </vuescroll>
                                 </div>
-
                                 <div class="term-item-time-line" v-if="schoolSetting.period[curPriodIndex].semesters.length">
-                                    <ul>
-                                        <li v-for="(item,index) in monthList" :key="index" :title="timeLineColor(index).text">
-                                            <span class="time-label">{{item}}</span>
-                                            <span class="time-dot" :style="{borderColor: timeLineColor(index).color}">
-                                                <span class="time-inner-dot" :style="{backgroundColor: timeLineColor(index).color}"></span>
-                                                <span class="time-line-tail"></span>
-                                            </span>
-                                            <div v-show="timeLineColor(index).showArrow">
-                                                <Icon class="first-arrow" size="20" :style="{color: timeLineColor(index).color}" type="ios-arrow-back" />
-                                                <Icon class="second-arrow" size="20" :style="{color: timeLineColor(index).color}" type="ios-arrow-back" />
-                                            </div>
-                                        </li>
-                                    </ul>
+                                    <vuescroll>
+                                        <ul style="">
+                                            <li v-for="(item,index) in monthList" :key="index" :title="timeLineColor(index).text">
+                                                <span class="time-label">{{item}}</span>
+                                                <span class="time-dot" :style="{borderColor: timeLineColor(index).color}">
+                                                    <span class="time-inner-dot" :style="{backgroundColor: timeLineColor(index).color}"></span>
+                                                    <span class="time-line-tail"></span>
+                                                </span>
+                                                <div v-show="timeLineColor(index).showArrow">
+                                                    <Icon class="first-arrow" size="20" :style="{color: timeLineColor(index).color}" type="ios-arrow-back" />
+                                                    <Icon class="second-arrow" size="20" :style="{color: timeLineColor(index).color}" type="ios-arrow-back" />
+                                                </div>
+                                            </li>
+                                        </ul>
+                                    </vuescroll>
                                 </div>
                             </div>
                         </div>
@@ -108,7 +111,7 @@
                                 <Draggable ghost-class="ghost" class="grade-list list-group" :list="schoolSetting.period[curPriodIndex].grades" :animation='200'>
                                     <div class="grade-item list-group-item" v-for="(item,index) in schoolSetting.period[curPriodIndex].grades" :key="index" @click.stop>
                                         <span class="grade-order">{{index + 1}}</span>
-                                        <Input class="grade-name" v-model="item.name" :disabled="!editGraStatus" placeholder="设置年级..." :style="{width: getWidth(index,item.name)+'px'}" />
+                                        <Input  @dblclick.native="editGraStatus = true" class="grade-name" v-model="item.name" :disabled="!editGraStatus" placeholder="设置年级..." :style="{width: getWidth(index,item.name)+'px'}" />
                                         <Icon type="md-close" @click.stop="showDelGrade(index)" style="cursor:pointer;flex:0.1" v-show="delGraStatus" />
                                     </div>
                                 </Draggable>
@@ -125,7 +128,7 @@
                             <div class="subject-body dark-iview-input disabled-iview-input" style="height:40%;">
                                 <div class="tag-item item-active" @click.stop v-for="(item,index) in schoolSetting.period[curPriodIndex].subjects" :key="index">
                                     <!--<span class="tag-item-icon"></span>-->
-                                    <Input v-model="item.name" :disabled="!editSubStatus" placeholder="设置学科..." :style="{width: getWidth(index,item.name)+'px'}" />
+                                    <Input @dblclick.native="editSubStatus = true"  v-model="item.name" :disabled="!editSubStatus" placeholder="设置学科..." :style="{width: getWidth(index,item.name)+'px'}" />
                                     <Icon type="md-close" @click="delSubject(index)" v-show="delSubStatus" />
                                 </div>
                                 <EmptyData v-if="schoolSetting.period[curPriodIndex].subjects.length == 0" textContent="暂无学科"></EmptyData>
@@ -144,10 +147,10 @@
                                     </p>
                                     <div class="attr-content">
                                         <div class="tag-item item-active" @click.stop v-for="(item,index) in schoolSetting.period[curPriodIndex].analysis.type" :key="index">
-                                            <!--<span class="tag-item-icon"></span>-->
-                                            <Input v-model="item.name" :disabled="!editAnaStatus" placeholder="设置考试类型..." :style="{width: getWidth(index,item.name)+'px'}" />
+                                            <Input @dblclick.native="editAnaStatus = true" v-model="item.name" :disabled="!editAnaStatus" placeholder="设置考试类型..." :style="{width: getWidth(index,item.name)+'px'}" />
                                             <Icon type="md-close" @click="confirmDelAna(index)" v-show="delAnaStatus" />
                                         </div>
+                                        <span v-if="!schoolSetting.period[curPriodIndex].analysis.type" style="line-height:32px;">暂无考试类型</span>
                                     </div>
                                 </div>
                                 <div class="attr-box-item">
@@ -158,7 +161,7 @@
                                         <span>优生率:</span>
                                     </p>
                                     <div class="attr-content" @click.stop>
-                                        <InputNumber :max="100" :min="0" :disabled="!editAnaStatus"
+                                        <InputNumber  @dblclick.native="editAnaStatus = true" :max="100" :min="0" :disabled="!editAnaStatus"
                                                      v-model="schoolSetting.period[curPriodIndex].analysis.eugenics"
                                                      :formatter="value => `${value}%`"
                                                      :parser="value => value.replace('%', '')"></InputNumber>
@@ -172,7 +175,7 @@
                                         <span>进线率:</span>
                                     </p>
                                     <div class="attr-content" @click.stop>
-                                        <InputNumber :max="100" :min="0" :disabled="!editAnaStatus"
+                                        <InputNumber @dblclick.native="editAnaStatus = true" :max="100" :min="0" :disabled="!editAnaStatus"
                                                      v-model="schoolSetting.period[curPriodIndex].analysis.income"
                                                      :formatter="value => `${value}%`"
                                                      :parser="value => value.replace('%', '')"></InputNumber>
@@ -186,7 +189,7 @@
                                         <span>踩线生:</span>
                                     </p>
                                     <div class="attr-content" @click.stop>
-                                        <InputNumber :max="100" :min="0" :disabled="!editAnaStatus"
+                                        <InputNumber @dblclick.native="editAnaStatus = true" :max="100" :min="0" :disabled="!editAnaStatus"
                                                      v-model="schoolSetting.period[curPriodIndex].analysis.touch"
                                                      :formatter="value => `${value}分`"
                                                      :parser="value => value.replace('分', '')"></InputNumber>
@@ -211,6 +214,7 @@
                 <Icon type="md-checkmark" size="20" style="margin-right:10px;position:absolute;left:15px;" v-if="index == selectedCampusIndex" />
                 <Input v-model="item.name" :disabled="editCamIndex !== index" placeholder="设置校区..." :style="{width: getWidth(0, item.name)+'px'}" />
                 <Icon type="md-create" class="campus-btn-edit" title="编辑" size="20" @click.stop="editCamIndex = index" />
+                <Icon type="md-trash" class="campus-btn-edit" title="删除" size="20" style="margin-right:40px;" @click.stop="delCampus(index)" />
             </p>
             <Icon type="md-add-circle" size="40" style="margin:auto;cursor:pointer;margin-top:30px;" @click="addCampus" />
         </Modal>
@@ -284,7 +288,7 @@
                 },
 
                 colorList: [],
-                TERM_MAX_LENGTH: 3, // 学期数上限
+                TERM_MAX_LENGTH: 6, // 学期数上限
                 campusStatus: false,
                 selectedCampusIndex: -1
             }
@@ -362,6 +366,9 @@
                 this.updated = false
                 this.countSemDays()
             },
+            test() {
+                alert(1)
+            },
             //计算时间轴选中颜色
             timeLineColor(index) {
                 let len = this.schoolSetting.period[this.curPriodIndex].semesters.length
@@ -474,6 +481,16 @@
                     }
                 })
             },
+            //删除校区
+            delCampus(index) {
+                this.$Modal.confirm({
+                    title: '删除校区',
+                    content: '删除' + this.schoolSetting.campuses[index].name + '后与之关联的数据将不能查询,确认删除吗?',
+                    onOk: () => {
+                        this.schoolSetting.campuses.splice(index, 1)
+                    }
+                })
+            },
             /**确认删除学期提示框 */
             showComfirmDelSemester() {
                 this.$Modal.confirm({
@@ -579,6 +596,12 @@
                         name: '设置校区名字',
                         id: Math.uuid()
                     })
+                    this.$nextTick(() => {
+                        setTimeout(() => {
+                            this.editCamIndex = this.schoolSetting.campuses.length - 1 
+                        },200)
+                    })
+                    
                 }
             },
             setCampus() {
@@ -751,6 +774,9 @@
 
             },
             addExamType() {
+                if (!this.schoolSetting.period[this.curPriodIndex].analysis.type) {
+                    this.schoolSetting.period[this.curPriodIndex].analysis.type = []
+                } 
                 this.schoolSetting.period[this.curPriodIndex].analysis.type.push({
                     id: this.guid(),
                     name: '预设考试类型'
@@ -851,7 +877,7 @@
             }
         },
         mounted() {
-            this.colorList = ['#F16C6A', '#68CDF1', '#1cc0f3', '#00796B', '#0288D1', '#D32F2F', '#00796B', '#7C4DFF', '#0288D1', '#D32F2F', '#00796B', '#7C4DFF']
+            this.colorList = ['#F16C6A', '#68CDF1', '#7C4DFF', '#00796B',   '#D32F2F', '#0288D1', '#D32F2F', '#00796B', '#7C4DFF', '#0288D1']
         },
         computed: {
 

+ 14 - 12
TEAMModelOS/ClientApp/src/view/selfstudy/ActivityInfo.vue

@@ -323,6 +323,8 @@
              * 确认分享学习内容
              * */
             confirmPublish() {
+                this.$Message.warning('暂未对接API')
+                return
                 this.$refs.activityInfo.validate((valid) => {
                     if (valid) {
                         let requestData = {
@@ -447,26 +449,26 @@
                 }
                 
             },
-            //获取班级关联的学生
+            //获取系统班级关联的学生(暂未对接动态班级名单)
             getClassroomStudent() {
                 this.isLoading = true
                 console.log(this.classList)
                 if (!this.classList[this.curClassIndex].students) {
-                    this.$api.courseMgmt.getClassroomStudent(
+                    this.$api.schoolSetting.getClassroomStudent(
                         {
-                            id: [this.classList[this.curClassIndex].id],
-                            schoolCode: this.classList[this.curClassIndex].code
+                            'school_code': this.$store.state.userInfo.schoolCode,
+                            'teacher.id': this.$store.state.userInfo.TEAMModelId
                         }
                     ).then(
                         (res) => {
-                            if (res.error == null) {
-                                let students = res.result.extend.students
-                                this.$set(this.classList[this.curClassIndex], 'students', students)
-                                this.findRecord()
-                            } else {
-                                this.$Message.error('API error!')
-                                this.isLoading = false
-                            }
+                            //if (res.error == null) {
+                            //    let students = res.result.extend.students
+                            //    this.$set(this.classList[this.curClassIndex], 'students', students)
+                            //    this.findRecord()
+                            //} else {
+                            //    this.$Message.error('API error!')
+                            //    this.isLoading = false
+                            //}
                         },
                         (err) => {
                             this.$Message.error('API error!')

+ 1 - 1
TEAMModelOS/ClientApp/src/view/selfstudy/CreateLearnUnit.vue

@@ -5,7 +5,7 @@
             <Input v-model="learnUnit.name" placeholder="请输入名称..." :class="checkName ? '':'my-error-style'" style="width: 300px" @on-blur="checkUnitName" />
             <span style="color:#ed4014;margin-left:15px;" v-show="!checkName">名称不能为空</span>
             <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveLearnUnitData">保存数据</Button>
-            <Button class="btn-save" type="text" ghost icon="md-arrow-dropleft" to="/home/SelfLearn" style="margin-right: 10px;">返回上级</Button>
+            <Button class="btn-save" type="text" ghost icon="md-arrow-back" to="/home/SelfLearn" style="margin-right: 10px;">返回上级</Button>
         </div>
         <div class="learn-unit-main">
             <Split v-model="split1">

+ 1 - 1
TEAMModelOS/ClientApp/src/view/selfstudy/CreateOrderLearn.vue

@@ -5,7 +5,7 @@
                 创建编序式学习
             </span>
             <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveData">保存数据</Button>
-            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="md-arrow-dropleft" to="/home/SelfLearn" style="margin-right: 10px;">返回上级</Button>
+            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="md-arrow-back" to="/home/SelfLearn" style="margin-right: 10px;">返回上级</Button>
         </div>
         <div class="order-learn-main">
             <!-- 基础信息表单 -->

+ 12 - 11
TEAMModelOS/ClientApp/src/view/selfstudy/SelfLearn.vue

@@ -8,9 +8,8 @@
                         <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="删除" />
                         <Icon type="md-create" :color="editIconStatus ? 'white':'#808080'" :style="{'cursor': editIconStatus ? 'pointer':'not-allowed'}" class="to-create-icon" @click="editInfo" title="编辑" />
-                        <Poptip trigger="hover" placement="bottom" offset="-8">
+                        <!--<Poptip trigger="hover" placement="bottom" offset="-8">
                             <Icon type="ios-funnel" class="to-create-icon" color="white" />
-                            <!--<div slot="title" style="display:none;"></div>-->
                             <div slot="content">
                                 <div style="margin-top:5px;">
                                     学年:
@@ -29,7 +28,7 @@
                                 </div>
                                 <Button type="primary" size="small" style="width:100%;margin-top:15px;">确认</Button>
                             </div>
-                        </Poptip>
+                        </Poptip>-->
                     </div>
                     <TabPane label="学习单元" name="unit" style="height:calc(100% - 40px);">
                         <vuescroll>
@@ -67,11 +66,6 @@
                @on-ok="confirmEdit">
             <p>确认跳转到<span style="padding:0px 5px;">{{ listType == 'order' ? '编序式教材':'自学单元'}}</span>编辑页面?</p>
         </Modal>
-        <Modal v-model="deleteStatus"
-               :title="listType == 'order' ? '删除编序式教材' : '删除自学单元'"
-               @on-ok="confirmDelete">
-            <p>确认删除<span style="color:blue;padding:0px 5px;font-weight:600;" v-if="deleteStatus">{{ listType == 'order' ? orderLearnList[currentLearnIndex].name : unitList[currentUnitIndex].name}}</span>?</p>
-        </Modal>
     </div>
 </template>
 <script>
@@ -97,7 +91,6 @@
                 listType: 'unit',//order: 编序式教材 unit:学习单元
                 isLoading: false,
                 sasString: '',
-                deleteStatus: false,
                 editStatus: false,
                 orderLearnList: [],
                 unitList: [],
@@ -180,7 +173,15 @@
              * 删除编序式教材或自学单元
              * */
             deleteData() {
-                this.deleteStatus = true
+                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')
+                    }
+                })
             },
             /**
              * 确认删除编序式教材或自学单元
@@ -247,7 +248,7 @@
                     }).then(
                         (res) => {
                             if (res.error == null) {
-                                let resData = res.result.data
+                                let resData = res.tasks
                                 for (let index in resData) {
                                     for (let i in this.classList) {
                                         if (this.classList[i].classroomCode == resData[index].code) {

+ 16 - 8
TEAMModelOS/ClientApp/src/view/settings/Index.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="settings-container">
         <div class="settings-header">
-            <span :class="['settings-header-item',activeTab === '0' ?  'active-item' : '']" @click="onTabChange('0')">一般设置</span>
-            <span :class="['settings-header-item',activeTab === '1' ?  'active-item' : '']" @click="onTabChange('1')">学校管理</span>
+            <span :class="['settings-header-item',activeTab === '1' ?  'active-item' : '']" @click="onTabChange('1')">{{ $t('settings.setting_title1')}}</span>
+			<span :class="['settings-header-item',activeTab === '0' ?  'active-item' : '']" @click="onTabChange('0')">{{ $t('settings.setting_title2')}}</span>
         </div>
 
         <div class="settings-body">
@@ -16,22 +16,22 @@
                             <Option value="zh-TW">中文(繁体)</Option>
                             <Option value="en-US">English</Option>
                         </Select>
-                        <Checkbox v-model="cloudSetting.isSystemLang">使用您作业系统的语系来展示</Checkbox>
+                        <Checkbox v-model="cloudSetting.isSystemLang" @on-change="onMenuStatusChange">使用您作业系统的语系来展示</Checkbox>
                     </span>
                 </div>
                 <div class="normal-settings-item">
                     <span class="item-title">网站色彩模式</span>
                     <span class="item-description">请选择网站显示的色彩模式,以便提供最佳的用户体验</span>
                     <span class="item-content">
-                        <span :class="['color-item',cloudSetting.curTheme === 'dark' ?  'color-item-active' : '']" @click="onThemeChange('dark')"></span>
-                        <span :class="['color-item',cloudSetting.curTheme === 'light' ?  'color-item-active' : '']" @click="onThemeChange('light')"></span>
+                        <span :class="['color-item',cloudSetting.curTheme === 'dark' ?  'color-item-active' : '']" @click="onTips('dark')"></span>
+                        <span :class="['color-item',cloudSetting.curTheme === 'light' ?  'color-item-active' : '']" @click="onTips('light')"></span>
                     </span>
                 </div>
                 <div class="normal-settings-item">
                     <span class="item-title">菜单显示设置</span>
                     <span class="item-description">选择左侧Menu在网站载入时的预设显示模式</span>
                     <span class="item-content">
-                        <RadioGroup v-model="cloudSetting.menuStatus">
+                        <RadioGroup v-model="cloudSetting.menuStatus" @on-change="onMenuStatusChange">
                             <Radio label="open">预设展开显示</Radio>
                             <Radio label="close">预设关闭显示</Radio>
                         </RadioGroup>
@@ -56,7 +56,7 @@
         },
         data() {
             return {
-                activeTab: '0',
+                activeTab: '1',
                 activeTheme: '0',
                 menuStatus: 'open',
                 curLang: 'zh-CN',
@@ -77,9 +77,13 @@
         methods: {
 			
 			onSelectLang(val){
-				console.log(val)
+				localStorage.setItem('cloudSetting', JSON.stringify(this.cloudSetting))
 				this.$store.commit("setLanguage", val);
 			},
+			
+			onMenuStatusChange(val){
+				localStorage.setItem('cloudSetting', JSON.stringify(this.cloudSetting))
+			},
 
             /* 一般设置与学校管理切换 */
             onTabChange(index) {
@@ -125,6 +129,10 @@
                     }
                 }
             },
+			
+			onTips(){
+				this.$Message.warning('换肤功能即将上线')
+			},
 
             /* 保存设置 */
             saveSetting() {

+ 76 - 20
TEAMModelOS/ClientApp/src/view/settings/SchoolMgmt.vue

@@ -49,13 +49,13 @@
 									<span>前往学校</span>
 								</span>
 							</span>
-							<span class="school-item-btn" style="background: rgb(202,54,54);" v-if="item.status === 'request'">
+<!-- 							<span class="school-item-btn" style="background: rgb(202,54,54);" v-if="item.status === 'request'">
 								<span>
 									<Icon type="md-close" />
 									<span>取消申请</span>
 								</span>
-							</span>
-							<span class="school-item-btn" style="background: #1CC0F3;right: 140px;" v-if="item.status === 'invite'">
+							</span> -->
+							<span class="school-item-btn" style="background: #1CC0F3;right: 140px;" v-if="item.status === 'invite'" @click="onConfirmJoin(item)">
 								<span>
 									<Icon type="md-checkmark" />
 									<span>同意加入</span>
@@ -99,7 +99,7 @@
 			<p>此举动将使您离开当前学校的 IES5 站台,并前往</p>
 			<p>{{ curSchoolItem ? curSchoolItem.name : '' }}</p>
 			<p>当前页面未保存的资料将会丢失,是否同意此操作?</p>
-			<Button>确定</Button>
+			<Button @click="onChangeSchool">确定</Button>
 		</Modal>
 
 	</div>
@@ -165,7 +165,6 @@
 		},
 		created() {
 			this.getTeacherInfo()
-			this.getTeacherSchoolInfo()
 			this.getAllShoolList()
 
 			this.mySchoolList = []
@@ -199,20 +198,22 @@
 			},
 
 			/* 获取老师所在学校的信息 */
-			getTeacherSchoolInfo() {
-				this.$api.schoolSetting.getTeacherSchoolInfo({
-					id_token: localStorage.getItem('id_token'),
-					school_code: this.$store.state.userInfo.schoolCode
-				}).then(
-					(res) => {
-						if (!res.error) {
-							console.log(res)
+			getTeacherSchoolInfo(code) {
+				return new Promise((r,j) => {
+					this.$api.schoolSetting.getTeacherSchoolInfo({
+						id_token: localStorage.getItem('id_token'),
+						school_code: code
+					}).then(
+						(res) => {
+							if (!res.error) {
+								r(res)
+							}
+						},
+						(err) => {
+							this.$Message.error("数据获取失败!")
 						}
-					},
-					(err) => {
-						this.$Message.error("数据获取失败!")
-					}
-				)
+					)
+				})
 			},
 
 			/* 获取所有授权学校列表 */
@@ -239,13 +240,16 @@
 				    cancelText: '取消',
 				    onOk: () => {
 						this.$api.schoolSetting.joinSchool({
-							grant_type:'join',
+							grant_type:'request',
 							school_code:item.id,
 							school_name:item.name
 						}).then(
 							(res) => {
+								console.log(res)
 								if (!res.error) {
 									this.$Message.success("提交成功!")
+									this.getTeacherInfo()
+									this.getAllShoolList()
 								}
 							},
 							(err) => {
@@ -257,12 +261,64 @@
 					}
 				})
 			},
-		
+			
+			/* 同意邀请 */
+			onConfirmJoin(item){
+				console.log(item)
+				this.$Modal.confirm({
+				    title: '温馨提示',
+				    content: '<p>确认加入' + item.name + ' ?</p>',
+				    okText: '确认',
+				    cancelText: '取消',
+				    onOk: () => {
+						this.$api.schoolSetting.joinSchool({
+							grant_type:'join',
+							school_code:item.schoolId,
+							school_name:item.name
+						}).then(
+							(res) => {
+								console.log(res)
+								if (!res.error) {
+									this.$Message.success("加入成功!")
+									this.getTeacherInfo()
+								}
+							},
+							(err) => {
+								this.$Message.error("操作失败!")
+							}
+						)
+				    },
+					onCancel:() => {
+					}
+				})
+			},
+			
+			/* 前往学校 */
+			async onChangeSchool(){
+				this.$EventBus.$emit('onGlobalLoading',true)
+				let schoolInfo = await this.getTeacherSchoolInfo(this.curSchoolItem.schoolId)
+				this.$store.commit('setSchoolCode',this.curSchoolItem.schoolId)
+				this.$store.commit('schoolBaseInfo/setSchoolInfo',{ period:[] })
+				this.$store.commit('schoolBaseInfo/setClassroomList', undefined)
+				this.$store.dispatch('user/setSchoolCode', this.curSchoolItem.schoolId)
+				this.$store.dispatch('user/setSchoolProfile', schoolInfo)
+				console.log('切换学校为' + this.curSchoolItem.schoolId)
+				console.log(this.$store.state)
+				setTimeout(() => {
+					this.$EventBus.$emit('onGlobalLoading',false)
+				},500)
+				this.$router.push({
+					name:'home'
+				})
+			},
+			
+			/* 搜索我的学校 */
 			onSearchChange(val){
 				console.log(val)
 				this.mySchoolList = this.originMySchoolList.filter(item => item.name.indexOf(this.mySchoolSearch) > -1)
 			},
 			
+			/* 搜索学校清单 */
 			onSearchList(val){
 				this.schoolList = this.originSchoolList.filter(item => item.name.indexOf(this.schoolListSearch) > -1)
 			},

+ 1 - 1
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less

@@ -276,7 +276,7 @@
     .no-data-text {
         width: 100%;
         height: 100%;
-        font-size: 30px;
+        font-size: 24px;
         font-weight: bold;
         color: #959595;
         text-align: center;

+ 42 - 68
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue

@@ -5,7 +5,7 @@
 			<!--学校名称部分 -->
 			<div class="section school-info">
 				<div class="school-info-box">
-					<span class="school-info-name">成都青城山学校学情分析仪表盘</span>
+					<span class="school-info-name">{{ schoolData.name }}学情分析仪表盘</span>
 					<div class="select-grade select-semester">
 						<Select v-model="selectSemester">
 							<Option v-for="(item,index) in semesterList" :value="index" :key="index">{{ item }}</Option>
@@ -16,60 +16,6 @@
 			<div class="section">
 				<Tabs :value="tabName">
 					<TabPane label="统计数据" name="tab1">
-						<!-- 基本数据统计部分 -->
-						<div class="section" style="display:none">
-							<div class="section-title">
-								{{$t('totalAnalysis.ti_title1')}}
-
-							</div>
-							<div class="section-box">
-								<div class="base-data-item block-item">
-									<div class="item-icon">
-										<Icon type="md-people" />
-									</div>
-									<div class="item-content">
-										<div class="item-num">98</div>
-										<div class="item-name">{{$t('totalAnalysis.ti_text1')}}</div>
-									</div>
-								</div>
-								<div class="base-data-item block-item">
-									<div class="item-icon">
-										<Icon type="md-school" />
-									</div>
-									<div class="item-content">
-										<div class="item-num">3655</div>
-										<div class="item-name">{{$t('totalAnalysis.ti_text2')}}</div>
-									</div>
-								</div>
-								<div class="base-data-item block-item">
-									<div class="item-icon">
-										<Icon type="logo-youtube" />
-									</div>
-									<div class="item-content">
-										<div class="item-num">3</div>
-										<div class="item-name">{{$t('totalAnalysis.ti_text3')}}</div>
-									</div>
-								</div>
-								<div class="base-data-item block-item">
-									<div class="item-icon">
-										<Icon type="md-podium" />
-									</div>
-									<div class="item-content">
-										<div class="item-num">9</div>
-										<div class="item-name">{{$t('totalAnalysis.ti_text4')}}</div>
-									</div>
-								</div>
-								<div class="base-data-item block-item">
-									<div class="item-icon">
-										<Icon type="md-tennisball" />
-									</div>
-									<div class="item-content">
-										<div class="item-num">48</div>
-										<div class="item-name">{{$t('totalAnalysis.ti_text5')}}</div>
-									</div>
-								</div>
-							</div>
-						</div>
 						<!-- 评测数据统计部分 -->
 						<div class="section">
 							<div class="section-title">
@@ -96,20 +42,20 @@
 								</div>
 								<div class="exam-data-item block-item">
 									<div class="item-content">
-										<div class="item-num">1</div>
+										<div class="item-num">0</div>
 										<div class="item-name">{{$t('totalAnalysis.ti_text8')}}</div>
 									</div>
 								</div>
 								<div class="exam-data-item block-item">
 									<div class="item-content">
-										<div class="item-num">1</div>
+										<div class="item-num">0</div>
 										<div class="item-name">{{$t('totalAnalysis.ti_text9')}}</div>
 									</div>
 								</div>
 							</div>
 						</div>
 						<!-- 年级优生率统计部分 -->
-						<div class="section">
+<!-- 						<div class="section">
 							<div class="section-title">
 								{{$t('totalAnalysis.ti_title4')}}
 							</div>
@@ -123,13 +69,16 @@
 									<BaseGeniusLine echartsId="myLine" :echartsData="geniusLineData" ref="geniusLine"></BaseGeniusLine>
 								</div>
 							</div>
-						</div>
+						</div> -->
 
 						<!-- 学科对比统计部分 -->
 						<div class="section">
 							<div class="section-title">
 								{{$t('totalAnalysis.ti_title3')}}
-
+							</div>
+							<div v-if="gradeList.length === 0" style="margin-top: 60px;">
+								<!-- <span class="no-data-text">暂无数据</span> -->
+								<EmptyData></EmptyData>
 							</div>
 							<!-- 年级雷达图部分 -->
 							<Collapse v-model="currentPanel" accordion @on-change="onRadarChange">
@@ -219,7 +168,9 @@
 								<span class="list-length">{{$t('totalAnalysis.text6')}} : {{examList.length}} </span>
 							</div>
 							<div class="section-box list-box">
-								<div class="no-data-text" v-if="!examList.length">暂无数据</div>
+								<div v-if="examList.length === 0">
+									<EmptyData></EmptyData>
+								</div>
 								<div class="genius-data-item exam-item" v-else v-for="(item,index) in examList" :key="index" @click="handleChooseExam(item,index)">
 									<div class="exam-info-top">
 										<span class="exam-type">{{item.conditions.range}}</span>
@@ -235,10 +186,9 @@
 										<span>{{$t('totalAnalysis.echarts_text13')}}: {{item.realCount}}</span>
 										<span>{{$t('totalAnalysis.echarts_text14')}}: {{getJoinRate(item)}}</span>
 										<span>{{$t('totalAnalysis.echarts_text15')}}: {{item.piont.toFixed(2)}}</span>
-										<span>{{$t('totalAnalysis.echarts_text16')}}: {{item.index.toFixed(2)}}</span>
 									</div>
 								</div>
-								<Page />
+								<Page size="small" />
 							</div>
 						</div>
 					</TabPane>
@@ -272,7 +222,7 @@
 				panelLeft: 0,
 				boxWidth: 292,
 				isShowClassRadar: true,
-				isShowFilter: false,
+				isShowFilter: true,
 				classList: new Array(11).fill('1'),
 				gradeList: [],
 				geniusLineData: null,
@@ -298,15 +248,37 @@
 				filterType: '全部',
 				filterArea: '全部',
 				filterFeedback: '全部',
-				filterSubject: '全部'
+				filterSubject: '全部',
+				schoolData:{
+					name:''
+				}
 			}
 		},
 		created() {
+			this.getSchoolInfo()
 			this.getHomePageData()
 			this.getExamList()
-			this.filterData = this.$store.state.totalAnalysis.filterData
+			// this.filterData = 
 		},
 		methods: {
+			/* 获取当前学校基础信息 */
+			getSchoolInfo() {
+				this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(res => {
+					this.schoolData = res.data
+					let schoolData = res.data
+					let filterJson = this.$store.state.totalAnalysis.filterData
+					if(schoolData.period.length){
+						this.filterData.periodList = schoolData.period
+						this.filterData.gradeList = schoolData.period[0].grades
+						this.filterData.subjectList = schoolData.period[0].subjects
+						this.filterData.termList = schoolData.period[0].semesters
+						this.filterData.typeList = filterJson.typeList
+						this.filterData.areaList = filterJson.areaList
+						this.filterData.feedbackList = filterJson.feedbackList
+					}
+					console.log(res)
+				})
+			},
 			// 获取学情首页数据
 			getHomePageData() {
 				this.isLoadingList = true
@@ -321,9 +293,10 @@
 						this.$Message.warning('暂无有效数据返回')
 					}
 					this.isLoadingList = false
-					this.$refs.geniusLine.dataLoading = false
+					// this.$refs.geniusLine.dataLoading = false
 				}).catch(err => {
 					console.log(err)
+					this.isLoadingList = false
 					this.$Message.error('服务器繁忙,请稍后重试!')
 				})
 			},
@@ -341,6 +314,7 @@
 					this.isLoadingList = false
 				}).catch(err => {
 					console.log(err)
+					this.isLoadingList = false
 				})
 			},
 
@@ -665,7 +639,7 @@
 
 	.list-box {
 		.ivu-page {
-			margin-top: 20px;
+			margin-top: 60px;
 		}
 
 		.ivu-page-item {

+ 0 - 0
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/TestAnalysis/QuestionList.css


Some files were not shown because too many files changed in this diff