浏览代码

Merge branch 'develop' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop

黄贺彬 6 年之前
父节点
当前提交
c577d4ab59
共有 61 个文件被更改,包括 4674 次插入492 次删除
  1. 1 1
      TEAMModelOS.Model/Evaluation/Dtos/DocInfoDto.cs
  2. 38 0
      TEAMModelOS.Model/Evaluation/Dtos/Own/Evaluats.cs
  3. 1 1
      TEAMModelOS.Model/Evaluation/Dtos/ExerciseDto.cs
  4. 37 0
      TEAMModelOS.Model/Evaluation/Dtos/Own/ItemBankDto.cs
  5. 21 0
      TEAMModelOS.Model/Evaluation/Dtos/Own/TestPaperDto.cs
  6. 27 0
      TEAMModelOS.Model/Evaluation/Dtos/Own/UseItemBankDto.cs
  7. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/ExerciseInfo.cs
  8. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/Item.cs
  9. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/ItemOption.cs
  10. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/MemberAnswer.cs
  11. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/MemberInfo.cs
  12. 0 0
      TEAMModelOS.Model/Evaluation/Dtos/Third/TestPaperInfo.cs
  13. 1 0
      TEAMModelOS.Model/Evaluation/Models/Evaluating.cs
  14. 30 5
      TEAMModelOS.Model/Evaluation/Models/ItemBank.cs
  15. 16 4
      TEAMModelOS.Model/Evaluation/Models/TestPaper.cs
  16. 103 0
      TEAMModelOS.Model/Evaluation/Models/UseItemBank.cs
  17. 13 0
      TEAMModelOS.Service/Evaluation/Implements/EvaluatingService.cs
  18. 1 0
      TEAMModelOS.Service/Evaluation/Implements/HtmlAnalyzeService.cs
  19. 1 1
      TEAMModelOS.Service/Evaluation/Implements/ImportExerciseService.cs
  20. 123 3
      TEAMModelOS.Service/Evaluation/Implements/ItemBankService.cs
  21. 0 1
      TEAMModelOS.Service/Evaluation/Implements/PaperService.cs
  22. 56 0
      TEAMModelOS.Service/Evaluation/Implements/TestPaperService.cs
  23. 59 0
      TEAMModelOS.Service/Evaluation/Implements/UseItemBankService.cs
  24. 12 0
      TEAMModelOS.Service/Evaluation/Interfaces/IEvaluatingService.cs
  25. 1 0
      TEAMModelOS.Service/Evaluation/Interfaces/IHtmlAnalyzeService.cs
  26. 1 0
      TEAMModelOS.Service/Evaluation/Interfaces/IImportExerciseService.cs
  27. 3 1
      TEAMModelOS.Service/Evaluation/Interfaces/IItemBankService.cs
  28. 16 0
      TEAMModelOS.Service/Evaluation/Interfaces/ITestPaperService.cs
  29. 17 0
      TEAMModelOS.Service/Evaluation/Interfaces/IUseItemBankService.cs
  30. 14 11
      TEAMModelOS/ClientApp/api/index.js
  31. 2 0
      TEAMModelOS/ClientApp/app.js
  32. 二进制
      TEAMModelOS/ClientApp/assets/icon/create_test_button_bg.png
  33. 二进制
      TEAMModelOS/ClientApp/assets/icon/icon_cart.png
  34. 二进制
      TEAMModelOS/ClientApp/assets/icon/icon_paper.png
  35. 1 0
      TEAMModelOS/ClientApp/assets/icon/no_data.svg
  36. 48 0
      TEAMModelOS/ClientApp/common/loading.vue
  37. 16 2
      TEAMModelOS/ClientApp/components/evaluation/IconText.vue
  38. 147 0
      TEAMModelOS/ClientApp/components/evaluation/SyllabusTree.vue
  39. 5 0
      TEAMModelOS/ClientApp/router/routes.js
  40. 3 5
      TEAMModelOS/ClientApp/store/api/index.js
  41. 1 1
      TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.css
  42. 23 23
      TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.vue
  43. 301 0
      TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.css
  44. 478 54
      TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.vue
  45. 255 35
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.css
  46. 359 81
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.vue
  47. 336 0
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesListTree.vue
  48. 136 13
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.css
  49. 179 31
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.vue
  50. 174 0
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.css
  51. 383 0
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.vue
  52. 268 13
      TEAMModelOS/ClientApp/view/evaluation/index/index.vue
  53. 539 103
      TEAMModelOS/ClientApp/view/evaluation/index/list.json
  54. 301 101
      TEAMModelOS/ClientApp/view/evaluation/index/paper.json
  55. 9 1
      TEAMModelOS/ClientApp/view/index.vue
  56. 1 0
      TEAMModelOS/ClientApp/view/syllabus/index/Syllabus.vue
  57. 113 0
      TEAMModelOS/Controllers/Evaluation/EvaluationController.cs
  58. 1 0
      TEAMModelOS/Controllers/Evaluation/ExamController.cs
  59. 1 0
      TEAMModelOS/Controllers/Evaluation/ImportExerciseController.cs
  60. 2 0
      TEAMModelOS/Views/Shared/_Layout.cshtml
  61. 0 1
      TeamModelOS.Test.JsonPath/TeamModelOS.Test.JsonPath.csproj

+ 1 - 1
TEAMModelOS.Model/Evaluation/Dtos/DocInfoDto.cs

@@ -4,7 +4,7 @@ using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations;
 using System.Text;
 using System.Text;
 
 
-namespace TEAMModelOS.Model.Evaluation.Dtos
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
 {
 {
     [MessagePackObject(keyAsPropertyName: true)]
     [MessagePackObject(keyAsPropertyName: true)]
     public class DocInfoDto
     public class DocInfoDto

+ 38 - 0
TEAMModelOS.Model/Evaluation/Dtos/Own/Evaluats.cs

@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
+{
+    public class Evaluats
+    {
+        /// <summary>
+        /// 题库集合
+        /// </summary>
+        public string[] ItemIds { get; set; }
+        /// <summary>
+        /// 评测名称
+        /// </summary>
+        public string Name { get; set; }
+        /// <summary>
+        /// 评测科目
+        /// </summary>
+        public string Subject { get; set; }
+        /// <summary>
+        /// 考试情景
+        /// </summary>
+        public string Scene { get; set; }
+        /// <summary>
+        /// 评测类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 评测对象
+        /// </summary>
+        public string Target { get; set; }
+        /// <summary>
+        /// 评测排定
+        /// </summary>
+        public string Schedule { get; set; }
+    }
+}

+ 1 - 1
TEAMModelOS.Model/Evaluation/Dtos/ExerciseDto.cs

@@ -4,7 +4,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Text;
 using TEAMModelOS.Model.Core.Dtos;
 using TEAMModelOS.Model.Core.Dtos;
 
 
-namespace TEAMModelOS.Model.Evaluation.Dtos
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
 {
 {
     [MessagePackObject(keyAsPropertyName: true)]
     [MessagePackObject(keyAsPropertyName: true)]
     public class ExerciseDto
     public class ExerciseDto

+ 37 - 0
TEAMModelOS.Model/Evaluation/Dtos/Own/ItemBankDto.cs

@@ -0,0 +1,37 @@
+using MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.Model.Core.Dtos;
+
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
+{
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class ItemBankDto
+    {
+        public ItemBankDto()
+        {
+            Option = new List<CodeValue>();
+            Answer = new List<string>();
+            Children = new List<ItemBankDto>();
+        }
+        public string ShaCode { get; set; }
+        public string PartitionKey { get; set; }
+        public string RowKey { get; set; }
+        public string Question { get; set; }
+        public List<CodeValue> Option { get; set; }
+        public List<string> Answer { get; set; }
+        /// <summary>
+        /// 知识点
+        /// </summary>
+        public List<Dictionary<string, object>> Concept { get; set; }
+        public string Explain { get; set; }
+        public string Type { get; set; }
+        public string ResourceCode { get; set; }
+        public string SubjectCode { get; set; }
+        public string PShaCode { get; set; }
+        public int ResourceType { get; set; }
+        [IgnoreMember]
+        public List<ItemBankDto> Children { get; set; }
+    }
+}

+ 21 - 0
TEAMModelOS.Model/Evaluation/Dtos/Own/TestPaperDto.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
+{
+    public class TestPaperDto
+    {
+        public string Name { get; set; }
+        public List<string> ItemId { get; set; }
+        public string SchoolCode { get; set; }
+        public string PeriodCode { get; set; }
+        public string GradeCode { get; set; }
+        public string ClassCode { get; set; }
+        public string SubjectCode { get; set; }
+        public string TeamodelId { get; set; }
+        public List<string> Point { get; set; }
+        public object Extend { get; set; }
+        public int State { get; set; }
+    }
+}

+ 27 - 0
TEAMModelOS.Model/Evaluation/Dtos/Own/UseItemBankDto.cs

@@ -0,0 +1,27 @@
+using MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.Model.Core.Dtos;
+
+namespace TEAMModelOS.Model.Evaluation.Dtos.Own
+{
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class UseItemBankDto
+    {
+        public UseItemBankDto()
+        {
+            Option = new List<CodeValue>();
+            Answer = new List<string>();
+        }
+        public string PartitionKey { get; set; }
+        public string RowKey { get; set; }
+        public string ShaCode { get; set; }
+        public string Question { get; set; }
+        public List<CodeValue> Option { get; set; }
+        public List<string> Answer { get; set; }
+        public string Explain { get; set; }
+        public string Type { get; set; }
+        public string Pid { get; set; }
+    }
+}

TEAMModelOS.Model/Evaluation/Dtos/ExerciseInfo.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/ExerciseInfo.cs


TEAMModelOS.Model/Evaluation/Dtos/Item.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/Item.cs


TEAMModelOS.Model/Evaluation/Dtos/ItemOption.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/ItemOption.cs


TEAMModelOS.Model/Evaluation/Dtos/MemberAnswer.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/MemberAnswer.cs


TEAMModelOS.Model/Evaluation/Dtos/MemberInfo.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/MemberInfo.cs


TEAMModelOS.Model/Evaluation/Dtos/TestPaperInfo.cs → TEAMModelOS.Model/Evaluation/Dtos/Third/TestPaperInfo.cs


+ 1 - 0
TEAMModelOS.Model/Evaluation/Models/Evaluating.cs

@@ -15,6 +15,7 @@ namespace TEAMModelOS.Model.Evaluation.Models
         /// 题库集合
         /// 题库集合
         /// </summary>
         /// </summary>
         public string[] ItemIds { get; set; }
         public string[] ItemIds { get; set; }
+
         /// <summary>
         /// <summary>
         /// 评测名称
         /// 评测名称
         /// </summary>
         /// </summary>

+ 30 - 5
TEAMModelOS.Model/Evaluation/Models/ItemBank.cs

@@ -33,6 +33,10 @@ namespace TEAMModelOS.Model.EvaluaTion.Models
         /// </summary>
         /// </summary>
         public string Point { get; set; }
         public string Point { get; set; }
         /// <summary>
         /// <summary>
+        /// 选项
+        /// </summary>
+        public string Option { get; set; }
+        /// <summary>
         /// 标准答案
         /// 标准答案
         /// </summary>
         /// </summary>
         public string Answer { get; set; }
         public string Answer { get; set; }
@@ -58,10 +62,6 @@ namespace TEAMModelOS.Model.EvaluaTion.Models
         /// </summary>
         /// </summary>
         public string Difficulty { get; set; }
         public string Difficulty { get; set; }
         /// <summary>
         /// <summary>
-        /// 创建时间
-        /// </summary>
-        public DateTime Date { get; set; }
-        /// <summary>
         /// 重要性
         /// 重要性
         /// </summary>
         /// </summary>
         public string Importance { get; set; }
         public string Importance { get; set; }
@@ -72,6 +72,31 @@ namespace TEAMModelOS.Model.EvaluaTion.Models
         /// <summary>
         /// <summary>
         /// 使用计数
         /// 使用计数
         /// </summary>
         /// </summary>
-        public string UsageCount { get; set; }
+        public int UsageCount { get; set; }
+        /// <summary>
+        /// 复合题型ID
+        /// </summary>
+        public string Pid { get; set; }
+        /// </summary>
+        public string ResourceId { get; set; }
+        /// <summary>
+        /// 资源类型
+        /// </summary>
+        public int ResourceType { get; set; }
+        /// <summary>
+        /// 学校编码
+        /// </summary>
+        public string ResourceCode { get; set; }
+        public string ResourceName { get; set; }
+        /// <summary>
+        /// 科目编码
+        /// </summary>
+        public string SubjectCode { get; set; }
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string Creator { get; set; }
+        public string CreatorCode { get; set; }
+
     }
     }
 }
 }

+ 16 - 4
TEAMModelOS.Model/Evaluation/Models/TestPaper.cs

@@ -5,9 +5,9 @@ using TEAMModelOS.SDK.Context.Attributes.Azure;
 
 
 namespace TEAMModelOS.Model.Evaluation.Models
 namespace TEAMModelOS.Model.Evaluation.Models
 {
 {
+    [TableSpace(Name = "Evaluation")]
     public class TestPaper
     public class TestPaper
     {
     {
-        public string id { get; set; }
         [PartitionKey]
         [PartitionKey]
         public string Name { get; set; }
         public string Name { get; set; }
         /// <summary>
         /// <summary>
@@ -18,15 +18,27 @@ namespace TEAMModelOS.Model.Evaluation.Models
         /// 题序(试卷排版顺序)
         /// 题序(试卷排版顺序)
         /// </summary>
         /// </summary>
         public string Index { get; set; }
         public string Index { get; set; }
+        public string SchoolCode { get; set; }
+        /// <summary>
+        /// 学段编码
+        /// </summary>
+        /// 
+        public string PeriodCode { get; set; }
+        public string GradeCode { get; set; }
+        public string ClassCode { get; set; }
+        public string SubjectCode { get; set; }
+        public string TeamodelId { get; set; }
+        /// <summary>
+        /// 是否公开
+        /// </summary>
+        public int State { get; set; } = 0;
         /// <summary>
         /// <summary>
         /// 动态字段部分
         /// 动态字段部分
         /// </summary>
         /// </summary>
-        public object Extend { get; set; }
+        public object Extends { get; set; }
         /// <summary>
         /// <summary>
         /// 分值或者配分
         /// 分值或者配分
         /// </summary>
         /// </summary>
         public string Point { get; set; }
         public string Point { get; set; }
-        public DateTimeOffset Stime { get; set; }
-        public DateTimeOffset Etime { get; set; }
     }
     }
 }
 }

+ 103 - 0
TEAMModelOS.Model/Evaluation/Models/UseItemBank.cs

@@ -0,0 +1,103 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Azure;
+
+namespace TEAMModelOS.Model.EvaluaTion.Models
+{
+    [TableSpace(Name = "Evaluation")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class UseItemBank : TableEntity
+    {
+        public string Id { get; set; }
+        /// <summary>
+        /// 题目
+        /// </summary>
+        public string Question { get; set; }
+        /// <summary>
+        /// 题目顺序 可移植到试卷库
+        /// </summary>
+        public string Index { get; set; }
+        /// <summary>
+        /// 题目类型
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 主客观类型
+        /// </summary>
+        public string Objective { get; set; }
+        /// <summary>
+        /// 分值 可移植到试卷库
+        /// </summary>
+        public string Point { get; set; }
+        /// <summary>
+        /// 选项
+        /// </summary>
+        public string Option { get; set; }
+        /// <summary>
+        /// 标准答案
+        /// </summary>
+        public string Answer { get; set; }
+        /// <summary>
+        /// 对应科目
+        /// </summary>
+        public string ConceptSubject { get; set; }
+        /// <summary>
+        /// 知识块
+        /// </summary>
+        public string ConceptArea { get; set; }
+        /// <summary>
+        /// 知识点
+        /// </summary>
+        /// 
+        public string Concept { get; set; }
+        /// <summary>
+        /// 详解
+        /// </summary>
+        public string Explain { get; set; }
+        /// <summary>
+        /// 难度
+        /// </summary>
+        public string Difficulty { get; set; }
+        /// <summary>
+        /// 重要性
+        /// </summary>
+        public string Importance { get; set; }
+        /// <summary>
+        /// 预计作答时间
+        /// </summary>
+        public string Time { get; set; }
+        /// <summary>
+        /// 使用计数
+        /// </summary>
+        public int UsageCount { get; set; }
+        //引用父类ID
+        public string Pid { get; set; }
+        /// <summary>
+        /// 数据源ID
+        /// </summary>
+        public string ResourceId { get; set; }
+        /// <summary>
+        /// 资源类型
+        /// </summary>
+        public string ResourceType { get; set; }
+        /// <summary>
+        /// 学校编码
+        /// </summary>
+        public string ResourceCode { get; set; }
+        public string ResourceName { get; set; }
+        /// <summary>
+        /// 科目编码
+        /// </summary>
+        public string SubjectCode { get; set; }
+        /// <summary>
+        /// 创建者
+        /// </summary>
+        public string Creator { get; set; }
+        public string CreatorCode { get; set; }
+
+
+    }
+}

+ 13 - 0
TEAMModelOS.Service/Evaluation/Implements/EvaluatingService.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.Service.Core.Implements;
+using TEAMModelOS.Service.Evaluation.Interfaces;
+
+namespace TEAMModelOS.Service.Evaluation.Implements
+{
+    public class EvaluatingService : BaseService, IEvaluatingService
+    {
+
+    }
+}

+ 1 - 0
TEAMModelOS.Service/Evaluation/Implements/HtmlAnalyzeService.cs

@@ -7,6 +7,7 @@ using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using TEAMModelOS.Model.Core.Dtos;
 using TEAMModelOS.Model.Core.Dtos;
 using TEAMModelOS.Model.Evaluation.Dtos;
 using TEAMModelOS.Model.Evaluation.Dtos;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using TEAMModelOS.SDK.Helper.Security.ShaHash;
 using TEAMModelOS.SDK.Helper.Security.ShaHash;

+ 1 - 1
TEAMModelOS.Service/Evaluation/Implements/ImportExerciseService.cs

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
 using System.Xml.Linq;
 using System.Xml.Linq;
 using TEAMModelOS.Model.Core.Dtos;
 using TEAMModelOS.Model.Core.Dtos;
 using TEAMModelOS.Model.Core.Models;
 using TEAMModelOS.Model.Core.Models;
-using TEAMModelOS.Model.Evaluation.Dtos;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.Model.Evaluation.Models;
 using TEAMModelOS.Model.Evaluation.Models;
 using TEAMModelOS.SDK.Context.Configuration;
 using TEAMModelOS.SDK.Context.Configuration;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;

+ 123 - 3
TEAMModelOS.Service/Evaluation/Implements/ItemBankService.cs

@@ -2,7 +2,12 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.Model.EvaluaTion.Models;
 using TEAMModelOS.Model.EvaluaTion.Models;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.SDK.Helper.Common.StringHelper;
+using TEAMModelOS.SDK.Helper.Security.ShaHash;
 using TEAMModelOS.Service.Core.Implements;
 using TEAMModelOS.Service.Core.Implements;
 using TEAMModelOS.Service.EvaluaTion.Interfaces;
 using TEAMModelOS.Service.EvaluaTion.Interfaces;
 
 
@@ -10,11 +15,126 @@ namespace TEAMModelOS.Service.EvaluaTion.Implements
 {
 {
     public class ItemBankService : BaseService, IItemBankService
     public class ItemBankService : BaseService, IItemBankService
     {
     {
-        public  async Task<List<ItemBank>> SaveOrUpdateAsync(List<ItemBank> items)
+        public async Task<List<ItemBank>> GetItemBanks(Dictionary<string, object> map)
         {
         {
-            await SaveOrUpdateAll<ItemBank>(items);
+            List<ItemBank> itemBanks = await FindListByDict<ItemBank>(map);
+            return itemBanks;
+            ///throw new NotImplementedException();
+        }
+
+        public  async Task<List<ItemBankDto>> SaveOrUpdateAsync(List<ItemBankDto> items,string lang)
+        {
+            List<ItemBank> itemBanks = new List<ItemBank>();
+            items.ForEach(p =>
+            {
+                string RowKeyP = this.GetRowKeys(p);
+                if (p.Children.Count > 0) {
+                    p.Children.ForEach(q =>
+                    {
+                        if (q.RowKey != null)
+                        {
+                            itemBanks.Add(new ItemBank()
+                            {
+                                RowKey = q.RowKey,
+                                PartitionKey = lang,
+                                Question = q.Question,
+                                Option = MessagePackHelper.ObjectToJson(q.Option),
+                                Answer = MessagePackHelper.ObjectToJson(q.Answer),
+                                Concept = MessagePackHelper.ObjectToJson(q.Concept),
+                                Explain = q.Explain,
+                                Type = q.Type
+                            });
+                        }
+                        else
+                        {
+                            string RowKey = this.GetRowKeys(q);
+                            itemBanks.Add(new ItemBank()
+                            {
+                                RowKey = RowKey,
+                                PartitionKey = lang,
+                                Question = q.Question,
+                                Option = MessagePackHelper.ObjectToJson(q.Option),
+                                Concept = MessagePackHelper.ObjectToJson(q.Concept),
+                                Answer = MessagePackHelper.ObjectToJson(q.Answer),
+                                Explain = q.Explain,
+                                Type = q.Type,
+                                Pid = RowKeyP
+                            });
+                        }
+                    });
+                }
+               
+                if (p.RowKey != null)
+                {
+                    itemBanks.Add(new ItemBank()
+                    {
+                        RowKey = p.RowKey,
+                        PartitionKey = lang,
+                        Question = p.Question,
+                        Concept = MessagePackHelper.ObjectToJson(p.Concept),
+                        Option = MessagePackHelper.ObjectToJson(p.Option),
+                        Answer = MessagePackHelper.ObjectToJson(p.Answer),
+                        Explain = p.Explain,
+                        Type = p.Type
+                    });
+                }
+                else {
+                    itemBanks.Add(new ItemBank()
+                    {
+                        RowKey = RowKeyP,
+                        PartitionKey = lang,
+                        Question = p.Question,
+                        Concept = MessagePackHelper.ObjectToJson(p.Concept),
+                        Option = MessagePackHelper.ObjectToJson(p.Option),
+                        Answer = MessagePackHelper.ObjectToJson(p.Answer),
+                        Explain = p.Explain,
+                        Type = p.Type
+                    });
+                }
+            });
+            await SaveOrUpdateAll(itemBanks);
+
             return items;
             return items;
-            //throw new NotImplementedException();
+        }
+        /// <summary>
+        /// 获取不同身份形成得唯一标识
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        public string GetRowKeys(ItemBankDto dto) {
+            if (dto.Type.Equals("Complete")|| dto.Type.Equals("Subjective")) {
+                ///dto.Question = HtmlHelper.DoUselessTag(dto.Question);
+                dto.Question = HtmlHelper.DoTextImg(dto.Question);
+                dto.ShaCode = ShaHashHelper.GetSHA1(dto.Question);
+                if (dto.ResourceType == 0)
+                {
+                    dto.RowKey = dto.SubjectCode + "-" + dto.ShaCode;
+                }
+                else
+                {
+                    dto.RowKey = dto.ResourceCode + "-" + dto.SubjectCode + "-" + dto.ShaCode;
+                }
+                return dto.RowKey;
+            }
+            else {
+                StringBuilder builder = new StringBuilder();
+                builder.Append(dto.Question);
+                dto.Option.ForEach(p =>
+                {
+                    builder.Append(p.Code + "" + p.Value);
+                });
+                dto.ShaCode = ShaHashHelper.GetSHA1(HtmlHelper.DoTextImg(builder.ToString()));
+                if (dto.ResourceType == 0)
+                {
+                    dto.RowKey = dto.SubjectCode + "-" + dto.ShaCode;
+                }
+                else
+                {
+                    dto.RowKey = dto.ResourceCode + "-" + dto.SubjectCode + "-" + dto.ShaCode;
+                }
+                return dto.RowKey;
+            }
+            
         }
         }
     }
     }
 }
 }

+ 0 - 1
TEAMModelOS.Service/Evaluation/Implements/PaperService.cs

@@ -14,7 +14,6 @@ namespace TEAMModelOS.Service.EvaluaTion.Implements
         {
         {
             await SaveOrUpdateAll<Paper>(papers);
             await SaveOrUpdateAll<Paper>(papers);
             return papers;
             return papers;
-            //throw new NotImplementedException();
         }
         }
     }
     }
 }
 }

+ 56 - 0
TEAMModelOS.Service/Evaluation/Implements/TestPaperService.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.Evaluation.Models;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces;
+using TEAMModelOS.Service.Core.Implements;
+using TEAMModelOS.Service.Evaluation.Interfaces;
+
+namespace TEAMModelOS.Service.Evaluation.Implements
+{
+    public class TestPaperService : ITestPaperService
+    {
+        public IAzureCosmosDBRepository _cosmosrepository;
+
+        public TestPaperService(IAzureCosmosDBRepository cosmosDBRepository) {
+            _cosmosrepository = cosmosDBRepository;
+        }
+
+        public async Task<List<TestPaper>> FindPapersAsync(Dictionary<string, object> paper)
+        {
+            return await _cosmosrepository.FindByparams<TestPaper>(paper);
+        }
+
+        public async Task<TestPaper> Save(TestPaperDto dto)
+        {
+            if (null != dto)
+            {
+                TestPaper paper = new TestPaper()
+                {
+                    Name = dto.Name,
+                    ItemId = MessagePackHelper.ObjectToJson(dto.ItemId),
+                    Point = MessagePackHelper.ObjectToJson(dto.Point),
+                    SchoolCode = dto.SchoolCode,
+                    PeriodCode = dto.PeriodCode,
+                    GradeCode = dto.GradeCode,
+                    ClassCode = dto.ClassCode,
+                    SubjectCode = dto.SubjectCode,
+                    TeamodelId = dto.TeamodelId,
+                    State = dto.State,
+                    Extends = dto.Extend
+
+
+                };
+                return await _cosmosrepository.Save(paper);
+            }
+            else {
+                return null;
+            }
+            
+        }
+
+    }
+}

+ 59 - 0
TEAMModelOS.Service/Evaluation/Implements/UseItemBankService.cs

@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.EvaluaTion.Models;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.Service.Core.Implements;
+using TEAMModelOS.Service.EvaluaTion.Interfaces;
+
+namespace TEAMModelOS.Service.EvaluaTion.Implements
+{
+    public class UseItemBankService : BaseService, IUseItemBankService
+    {
+        public async Task<List<UseItemBank>> GetItemBanks(Dictionary<string, object> map)
+        {
+            List<UseItemBank> itemBanks = await FindListByDict<UseItemBank>(map);
+            return itemBanks;
+        }
+
+        public  async Task<List<UseItemBankDto>> SaveOrUpdateAsync(List<UseItemBankDto> items,string lang)
+        {
+            List<UseItemBank> itemBanks = new List<UseItemBank>();
+            items.ForEach(p =>
+            {
+                if (p.PartitionKey != null)
+                {
+                    itemBanks.Add(new UseItemBank()
+                    {
+                        RowKey = p.RowKey,
+                        PartitionKey = lang,
+                        Question = p.Question,
+                        Option = MessagePackHelper.ObjectToJson(p.Option),
+                        Answer = MessagePackHelper.ObjectToJson(p.Answer),
+                        Explain = p.Explain,
+                        Type = p.Type,
+                        Pid = p.Pid
+                    });
+                }
+                else {
+                    itemBanks.Add(new UseItemBank()
+                    {
+                        RowKey = Guid.NewGuid().ToString(),
+                        PartitionKey = lang,
+                        Question = p.Question,
+                        Option = MessagePackHelper.ObjectToJson(p.Option),
+                        Answer = MessagePackHelper.ObjectToJson(p.Answer),
+                        Explain = p.Explain,
+                        Type = p.Type,
+                        Pid = p.Pid
+                    });
+                }
+            });
+            await SaveOrUpdateAll(itemBanks);
+
+            return items;
+        }
+    }
+}

+ 12 - 0
TEAMModelOS.Service/Evaluation/Interfaces/IEvaluatingService.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.Service.Core.Interfaces;
+
+namespace TEAMModelOS.Service.Evaluation.Interfaces
+{
+    public interface IEvaluatingService : IBusinessService, IBaseService
+    {
+
+    }
+}

+ 1 - 0
TEAMModelOS.Service/Evaluation/Interfaces/IHtmlAnalyzeService.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using TEAMModelOS.Model.Evaluation.Dtos;
 using TEAMModelOS.Model.Evaluation.Dtos;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.Service.Core.Interfaces;
 using TEAMModelOS.Service.Core.Interfaces;
 
 
 namespace TEAMModelOS.Service.Evaluation.Interfaces
 namespace TEAMModelOS.Service.Evaluation.Interfaces

+ 1 - 0
TEAMModelOS.Service/Evaluation/Interfaces/IImportExerciseService.cs

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using TEAMModelOS.Model.Core.Models;
 using TEAMModelOS.Model.Core.Models;
 using TEAMModelOS.Model.Evaluation.Dtos;
 using TEAMModelOS.Model.Evaluation.Dtos;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.Service.Core.Interfaces;
 using TEAMModelOS.Service.Core.Interfaces;
 
 
 namespace TEAMModelOS.Service.Evaluation.Interfaces
 namespace TEAMModelOS.Service.Evaluation.Interfaces

+ 3 - 1
TEAMModelOS.Service/Evaluation/Interfaces/IItemBankService.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.Model.EvaluaTion.Models;
 using TEAMModelOS.Model.EvaluaTion.Models;
 using TEAMModelOS.Service.Core.Interfaces;
 using TEAMModelOS.Service.Core.Interfaces;
 
 
@@ -10,6 +11,7 @@ namespace TEAMModelOS.Service.EvaluaTion.Interfaces
     public interface IItemBankService : IBusinessService, IBaseService
     public interface IItemBankService : IBusinessService, IBaseService
     {
     {
 
 
-        Task<List<ItemBank>> SaveOrUpdateAsync(List<ItemBank> items);
+        Task<List<ItemBankDto>> SaveOrUpdateAsync(List<ItemBankDto> items,string lang);
+        Task<List<ItemBank>> GetItemBanks(Dictionary<string, object> map);
     }
     }
 }
 }

+ 16 - 0
TEAMModelOS.Service/Evaluation/Interfaces/ITestPaperService.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.Evaluation.Models;
+using TEAMModelOS.Service.Core.Interfaces;
+
+namespace TEAMModelOS.Service.Evaluation.Interfaces
+{
+    public interface ITestPaperService : IBusinessService
+    {
+        Task<TestPaper> Save(TestPaperDto dto);
+        Task<List<TestPaper>> FindPapersAsync(Dictionary<string, Object> paper);
+    }
+}

+ 17 - 0
TEAMModelOS.Service/Evaluation/Interfaces/IUseItemBankService.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.EvaluaTion.Models;
+using TEAMModelOS.Service.Core.Interfaces;
+
+namespace TEAMModelOS.Service.EvaluaTion.Interfaces
+{
+    public interface IUseItemBankService : IBusinessService, IBaseService
+    {
+
+        Task<List<UseItemBankDto>> SaveOrUpdateAsync(List<UseItemBankDto> items,string lang);
+        Task<List<UseItemBank>> GetItemBanks(Dictionary<string, object> map);
+    }
+}

+ 14 - 11
TEAMModelOS/ClientApp/api/index.js

@@ -1,9 +1,11 @@
 import { fetch, post } from '@/filters/http'
 import { fetch, post } from '@/filters/http'
 import SchoolMgmt from './schoolMgmt'
 import SchoolMgmt from './schoolMgmt'
 import talMgmt from './talMgmt'
 import talMgmt from './talMgmt'
+import cloudApi from '../store/api/index'
 export default {
 export default {
   SchoolMgmt,
   SchoolMgmt,
   talMgmt,
   talMgmt,
+  cloudApi,
   //获取登录跳转链接
   //获取登录跳转链接
   getLoginLink: function (data) {
   getLoginLink: function (data) {
     return post('api/login/login', data);
     return post('api/login/login', data);
@@ -101,25 +103,26 @@ export default {
     return post('api/Knowledge/RemoveSchoolBlockPoint', data);
     return post('api/Knowledge/RemoveSchoolBlockPoint', data);
   },
   },
 
 
-
-
-
-
-
-
   //获取登录人员身份信息
   //获取登录人员身份信息
   getLoginClaim: function (data) {
   getLoginClaim: function (data) {
     return post('api/role/GetLoginClaim', data);
     return post('api/role/GetLoginClaim', data);
   },
   },
 
 
 
 
+  //新建习题保存到题库
+  SaveItemBank: function (data) {
+    return post('api/evaluation/ItemBank', data);
+  },
 
 
+  //新建试卷到试卷库
+  SaveTestPaper: function (data) {
+    return post('api/Evaluation/testPaper', data);
+  },
 
 
-
-
-
-
-
+  //新建试卷到试卷库
+  SaveAnalyzeHtml: function (data) {
+    return post('api/ImportExercise/AnalyzeHtml', data);
+  },
 
 
 
 
   //学情分析API
   //学情分析API

+ 2 - 0
TEAMModelOS/ClientApp/app.js

@@ -13,10 +13,12 @@ import apiTools from '@/api';
 import { fetch, post } from '@/filters/http';
 import { fetch, post } from '@/filters/http';
 import VideoPlayer from 'vue-video-player';
 import VideoPlayer from 'vue-video-player';
 import jwtDecode from 'jwt-decode';
 import jwtDecode from 'jwt-decode';
+import Loading from '@/common/Loading';
 
 
 require('video.js/dist/video-js.css');
 require('video.js/dist/video-js.css');
 require('vue-video-player/src/custom-theme.css');
 require('vue-video-player/src/custom-theme.css');
 Vue.use(VideoPlayer);
 Vue.use(VideoPlayer);
+Vue.use(Loading);
 
 
 //新添加的
 //新添加的
 import vuescroll from 'vue-scroll'
 import vuescroll from 'vue-scroll'

二进制
TEAMModelOS/ClientApp/assets/icon/create_test_button_bg.png


二进制
TEAMModelOS/ClientApp/assets/icon/icon_cart.png


二进制
TEAMModelOS/ClientApp/assets/icon/icon_paper.png


文件差异内容过多而无法显示
+ 1 - 0
TEAMModelOS/ClientApp/assets/icon/no_data.svg


+ 48 - 0
TEAMModelOS/ClientApp/common/loading.vue

@@ -0,0 +1,48 @@
+<template>
+  <div class="loading-container">
+    <div id="loadingBox" :style="{'margin-top':top+'px','border-width': borderWidth + 'px'}"></div>
+  </div>
+</template>
+
+<script>
+    export default {
+    name: "loadingBox",
+    props: ["top","borderColor","color","borderWidth"],
+    data() {
+      return {
+      }
+    },
+    created() {
+      console.log(this.top);
+    },
+    methods: {
+      
+    }
+    }
+</script>
+<style>
+  .loading-container {
+    position:absolute;
+    width:100%;
+    height:100%;
+    display:flex;
+    flex-direction:row;
+    justify-content:center;
+  }
+
+  #loadingBox {
+    margin-top:200px;
+    border: 3px solid hsla(185, 100%, 62%, 0.2);
+    border-top-color: #4c9cff;
+    border-radius: 50%;
+    width: 40px;
+    height: 40px;
+    animation: spin .7s linear infinite;
+  }
+
+  @keyframes spin {
+    to {
+      transform: rotate(360deg);
+    }
+  }
+</style>

+ 16 - 2
TEAMModelOS/ClientApp/components/evaluation/IconText.vue

@@ -1,7 +1,7 @@
 <template>
 <template>
   <div class="icon-text">
   <div class="icon-text">
-    <Icon :type="icon" :color="color" size="25" />
-    <span class="attr-label">{{text}}</span>
+    <Icon :type="icon" :color="color" :size="iconSize" />
+    <span class="attr-label" :style="myStyle">{{text}}</span>
   </div>
   </div>
 </template>
 </template>
 <script>
 <script>
@@ -18,6 +18,20 @@
       text: {
       text: {
         type: String,
         type: String,
         default:'文本内容'
         default:'文本内容'
+      },
+      textSize: {
+        type: Number,
+        default:16
+      },
+      iconSize: {
+        type: Number,
+        default:25
+      }
+    },
+    computed: {
+      myStyle() {
+        return "font-size:" + this.textSize + "px;";
+        //return "";
       }
       }
     }
     }
   }
   }

+ 147 - 0
TEAMModelOS/ClientApp/components/evaluation/SyllabusTree.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="tree-main">
+    <Tree :data="treeData" :render="renderContent" ref="tree" show-checkbox empty-text="暂无课纲内容"></Tree>
+  </div>
+</template>
+<script>
+  export default {
+    props: ["treeDatas"],
+    data() {
+      return {
+        treeData: []
+      };
+    },
+    created() {
+      this.treeData = this.treeDatas;
+    },
+
+    //监听树形数据源变化
+    watch: {
+      treeDatas: {
+        handler(newValue) {
+          this.treeData = newValue;
+        },
+        deep: true
+      }
+    },
+    methods: {
+      //自定义渲染树形工具
+       renderContent(h, { root, node, data }) {
+        return h(
+          "span",
+          {
+            domProps: {
+              className: "singleClass"
+            },
+            on: {
+              click: () => {
+                this.titleClick(root, node, data, event);
+              },
+            }
+          },
+          [
+            h("span", [
+              h("span", {
+                domProps: {
+                  className: "syllabus-name"
+                },
+              }, data.title)
+            ])
+          ]
+        );
+      },
+      // 标题点击收缩展开
+      titleClick(root, node, data, event) {
+        data.expand = !data.expand;
+      },
+      // 根目录点击事件
+      rootClick(data) {
+        data.expand = !data.expand;
+      }
+    },
+  };
+</script>
+<style scoped>
+  .tree-main {
+    margin-left: 5%;
+    width: 90%;
+  }
+
+  .ivu-tree .ivu-tree-arrow {
+    width: 2%;
+  }
+
+  .ivu-input-wrapper {
+    width: 80% !important;
+  }
+
+  .modelRow {
+    margin: 20px;
+    font-size: 14px;
+  }
+
+  .animated {
+    animation-duration: 0.5s;
+  }
+
+  @-webkit-keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0,-10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  @keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0, -10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  .slideInDown {
+    -webkit-animation-name: slideInDown;
+    animation-name: slideInDown;
+  }
+  .tree-main /deep/ .singleClass {
+     margin:0;
+  }
+
+
+  .tree-main /deep/ .singleClass .syllabus-name{
+    width:100px;    
+    overflow: hidden;    
+    text-overflow:ellipsis;    
+    white-space: nowrap;
+    display:inline-block;
+    vertical-align:middle;
+  }
+  .tree-main /deep/ .ivu-tree-empty{
+    width:100%;
+    height:60px;
+    line-height:60px;
+    text-align:center;
+    font-size:14px;
+  }
+
+  .btn-addClass {
+    width: 16%;
+    padding: 10px 6px !important;
+  }
+
+  .ivu-tabs-nav-scroll {
+    display: flex;
+    justify-content: center;
+  }
+</style>

+ 5 - 0
TEAMModelOS/ClientApp/router/routes.js

@@ -64,6 +64,11 @@ export const routes = [
         name: 'createTest',
         name: 'createTest',
         component: resolve => require(['@/view/evaluation/index/createTest.vue'], resolve), //路由懒加载
         component: resolve => require(['@/view/evaluation/index/createTest.vue'], resolve), //路由懒加载
       },
       },
+      {
+        path: '/testPaperList',
+        name: 'testPaperList',
+        component: resolve => require(['@/view/evaluation/index/TestPaperList.vue'], resolve), //路由懒加载
+      },
 
 
     ]
     ]
   }
   }

+ 3 - 5
TEAMModelOS/ClientApp/store/api/index.js

@@ -58,15 +58,13 @@ export default {
     return post('api/role/GetLoginClaim', data);
     return post('api/role/GetLoginClaim', data);
   },
   },
 
 
-  //评测API
 
 
-  //新建习题保存到题库
-  SaveItemBank: function (data) {
-    return post('api/evaluation/ItemBank', data);
+  //解析Html题目
+  SaveAnalyzeHtml: function (data) {
+    return post('api/ImportExercise/AnalyzeHtml', data);
   },
   },
 
 
 
 
-
   //学情分析API
   //学情分析API
   //查询班年级数据
   //查询班年级数据
   FindGrade: function () {
   FindGrade: function () {

+ 1 - 1
TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.css

@@ -58,7 +58,7 @@
 }
 }
 
 
 .my-radio-style .ivu-radio-group {
 .my-radio-style .ivu-radio-group {
-    margin-top: 30px;
+    margin-top: 15px;
 }
 }
 
 
 exersices-attr-diff {
 exersices-attr-diff {

+ 23 - 23
TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.vue

@@ -6,11 +6,11 @@
       <div class="exersices-attr-type my-radio-style">
       <div class="exersices-attr-type my-radio-style">
         <IconText :text="'选择题型'" :color="'green'" :icon="'md-apps'"></IconText>
         <IconText :text="'选择题型'" :color="'green'" :icon="'md-apps'"></IconText>
         <RadioGroup v-model="exersicesType" type="button" @on-change="typeChange">
         <RadioGroup v-model="exersicesType" type="button" @on-change="typeChange">
-          <Radio label="single" :disabled="isEdit">单选</Radio>
-          <Radio label="multiple" :disabled="isEdit">多选</Radio>
-          <Radio label="judge" :disabled="isEdit">判断</Radio>
-          <Radio label="complete" :disabled="isEdit">填空</Radio>
-          <Radio label="subjective" :disabled="isEdit">问答</Radio>
+          <Radio label="Single" :disabled="isEdit">单选</Radio>
+          <Radio label="Multiple" :disabled="isEdit">多选</Radio>
+          <Radio label="Judge" :disabled="isEdit">判断</Radio>
+          <Radio label="Complete" :disabled="isEdit">填空</Radio>
+          <Radio label="Subjective" :disabled="isEdit">问答</Radio>
         </RadioGroup>
         </RadioGroup>
       </div>
       </div>
       <div class="exersices-attr-diff my-radio-style">
       <div class="exersices-attr-diff my-radio-style">
@@ -25,11 +25,11 @@
       </div>
       </div>
     </div>
     </div>
 
 
-    <BaseSingle v-if="exersicesType=='single'" ref="single" :editInfo="editInfo"></BaseSingle>
-    <BaseMultiple v-else-if="exersicesType=='multiple'" ref="multiple" :editInfo="editInfo"></BaseMultiple>
-    <BaseJudge v-else-if="exersicesType=='judge'" ref="judge" :editInfo="editInfo"></BaseJudge>
-    <BaseCompletion v-else-if="exersicesType=='complete'" ref="complete" :editInfo="editInfo"></BaseCompletion>
-    <BaseSubjective v-else-if="exersicesType=='subjective'" ref="subjective" :editInfo="editInfo"></BaseSubjective>
+    <BaseSingle v-if="exersicesType=='Single'" ref="single" :editInfo="editInfo"></BaseSingle>
+    <BaseMultiple v-else-if="exersicesType=='Multiple'" ref="multiple" :editInfo="editInfo"></BaseMultiple>
+    <BaseJudge v-else-if="exersicesType=='Judge'" ref="judge" :editInfo="editInfo"></BaseJudge>
+    <BaseCompletion v-else-if="exersicesType=='Complete'" ref="complete" :editInfo="editInfo"></BaseCompletion>
+    <BaseSubjective v-else-if="exersicesType=='Subjective'" ref="subjective" :editInfo="editInfo"></BaseSubjective>
 
 
     <div class="exersices-analysis">
     <div class="exersices-analysis">
       <IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:15px;"></IconText>
       <IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:15px;"></IconText>
@@ -73,7 +73,7 @@
       return {
       return {
         isEdit: false,
         isEdit: false,
         editInfo: {},
         editInfo: {},
-        exersicesType: 'single',
+        exersicesType: 'Single',
         exersicesDiff: "0",
         exersicesDiff: "0",
         analysisContent: "",
         analysisContent: "",
         stemContent: "",
         stemContent: "",
@@ -110,41 +110,41 @@
       getContent: function (type) {
       getContent: function (type) {
         let exerciseItem = Object.assign({}, defaultExercise);
         let exerciseItem = Object.assign({}, defaultExercise);
         switch (type) {
         switch (type) {
-          case "single":
+          case "Single":
             exerciseItem.question = this.$refs.single._data.stemContent;
             exerciseItem.question = this.$refs.single._data.stemContent;
-            exerciseItem.options = this.$refs.single._data.optionsContent.length == this.$refs.single._data.options.length ? this.$refs.single._data.optionsContent : null;
+            exerciseItem.option = this.$refs.single._data.optionsContent.length == this.$refs.single._data.options.length ? this.$refs.single._data.optionsContent : null;
             exerciseItem.type = this.exersicesType;
             exerciseItem.type = this.exersicesType;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.answer = [String.fromCharCode(64 + parseInt(this.$refs.single._data.trueIndex + 1))];
             exerciseItem.answer = [String.fromCharCode(64 + parseInt(this.$refs.single._data.trueIndex + 1))];
             break;
             break;
-          case "multiple":
+          case "Multiple":
             exerciseItem.question = this.$refs.multiple._data.stemContent;
             exerciseItem.question = this.$refs.multiple._data.stemContent;
-            exerciseItem.options = this.$refs.multiple._data.optionsContent.length == this.$refs.multiple._data.options.length ? this.$refs.multiple._data.optionsContent : null;
+            exerciseItem.option = this.$refs.multiple._data.optionsContent.length == this.$refs.multiple._data.options.length ? this.$refs.multiple._data.optionsContent : null;
             exerciseItem.type = this.exersicesType;
             exerciseItem.type = this.exersicesType;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.answer = this.$refs.multiple._data.transferArr;
             exerciseItem.answer = this.$refs.multiple._data.transferArr;
             break;
             break;
-          case "judge":
+          case "Judge":
             exerciseItem.question = this.$refs.judge._data.stemContent;
             exerciseItem.question = this.$refs.judge._data.stemContent;
-            exerciseItem.options = [];
+            exerciseItem.option = [];
             exerciseItem.type = this.exersicesType;
             exerciseItem.type = this.exersicesType;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.answer = this.$refs.judge._data.trueAnswer;
             exerciseItem.answer = this.$refs.judge._data.trueAnswer;
             break;
             break;
-          case "complete":
+          case "Complete":
             exerciseItem.question = this.$refs.complete._data.stemContent;
             exerciseItem.question = this.$refs.complete._data.stemContent;
-            exerciseItem.options = [];
+            exerciseItem.option = [];
             exerciseItem.type = this.exersicesType;
             exerciseItem.type = this.exersicesType;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.answer = this.$refs.complete._data.optionsContent.map(item => item.value);
             exerciseItem.answer = this.$refs.complete._data.optionsContent.map(item => item.value);
             break;
             break;
-          case "subjective":
+          case "Subjective":
             exerciseItem.question = this.$refs.subjective._data.stemContent;
             exerciseItem.question = this.$refs.subjective._data.stemContent;
-            exerciseItem.options = [];
+            exerciseItem.option = [];
             exerciseItem.type = this.exersicesType;
             exerciseItem.type = this.exersicesType;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.difficulty = this.exersicesDiff;
             exerciseItem.explain = this.analysisContent;
             exerciseItem.explain = this.analysisContent;
@@ -268,6 +268,6 @@
     }
     }
   }
   }
 </script>
 </script>
-<style scoped>
-  @import"../index/CreateExercises.css";
+<style src="../index/CreateExercises.css" scoped>
+  /*@import"../index/CreateExercises.css";*/
 </style>
 </style>

+ 301 - 0
TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.css

@@ -0,0 +1,301 @@
+.ev-container {
+    user-select: none !important;
+    background: #fff;
+    padding: 30px;
+}
+
+    .ev-container .w-e-text-container {
+        height: 180px !important;
+    }
+
+    .ev-container .ev-title {
+        font-size: 20px;
+        font-weight: bold;
+        margin-left: 5px;
+        vertical-align: middle;
+    }
+
+        .ev-container .ev-title .ivu-icon {
+            margin-right: 6px;
+            margin-bottom: 6px;
+            font-size: 30px;
+            color: rgb(16, 171, 231);
+        }
+
+.display-flex {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+}
+
+.exersices-attr {
+    width: 100%;
+}
+
+.exersices-attr-type {
+    width: 50%;
+}
+
+.my-radio-style .ivu-radio-group-button .ivu-radio-wrapper {
+    margin-right: 20px;
+    border-radius: 5px;
+    background: #fff;
+    border: 1px solid #dcdee2;
+    font-size: 14px;
+}
+
+    .my-radio-style .ivu-radio-group-button .ivu-radio-wrapper:after {
+        content: none;
+    }
+
+    .my-radio-style .ivu-radio-group-button .ivu-radio-wrapper:after, .ivu-radio-group-button .ivu-radio-wrapper:before {
+        content: none;
+    }
+
+.my-radio-style .ivu-radio-group-button .ivu-radio-wrapper-checked {
+    /*background: #2d8cf0;*/
+    /*color: white;*/
+    box-shadow: none !important;
+    font-weight: 600;
+    
+}
+.test-scene .ivu-radio-group-button .ivu-radio-wrapper-checked {
+    color: green;
+    border: 1px solid;
+}
+.test-type .ivu-radio-group-button .ivu-radio-wrapper-checked {
+    color: red;
+    border: 1px solid;
+}
+.test-target .ivu-radio-group-button .ivu-radio-wrapper-checked {
+    color: #FF7F24;
+    border: 1px solid;
+}
+.test-mode .ivu-radio-group-button .ivu-radio-wrapper-checked {
+    color: #0086e6;
+    border: 1px solid;
+}
+.my-radio-style .ivu-radio-group {
+    margin-top: 20px;
+}
+
+exersices-attr-diff {
+    width: 50%;
+}
+
+.exersices-content {
+    position: relative;
+    margin-top: 35px;
+}
+.exersices-option {
+    margin-top: 50px;
+}
+
+.option-item {
+    margin-top: 15px;
+}
+
+.exersices-analysis {
+    position: relative;
+    margin-top: 50px;
+}
+
+.ev-container .w-e-toolbar {
+    height: 40px;
+    line-height: 30px;
+    font-size: 14px;
+}
+
+.create-wrap {
+    margin-top:30px;
+}
+
+.test-chapter-wrap {
+    margin-top: 20px;
+    clear: both;
+    margin-left: 34px;
+}
+    .test-chapter-wrap p {
+        color:#AAAAAA;
+        font-size:14px;
+    }
+
+.create-test-attr {
+    margin-top:30px;
+}
+    .create-test-attr .ivu-tag {
+        font-size:14px;
+    }
+    .create-test-attr label {
+        font-size: 15px;
+    }
+    .create-test-attr .label-style {
+        font-weight:600;
+        margin-right:20px;
+    }
+.test-attr-item {
+    margin-top:30px;
+    margin-left:34px;
+}
+.set-question-num .ivu-btn {
+    width: 120px;
+    margin-right: 20px;
+}
+
+    .set-question-num .ivu-btn:hover {
+        color: WHITE;
+        background-color: #2BBB61;
+        border-color: #2BBB61;
+    }
+
+.my-check-button {
+    border: 1px solid #E1E1E1;
+    display:inline-block;
+    padding:5px 30px;
+    border-radius:4px;
+    margin-right:25px;
+    cursor:pointer;
+    font-size:14px;
+}
+    .my-check-button:hover {
+        /*background: #2D8CF0;*/
+        /*color: #2D8CF0;*/
+        border: 1px solid #2D8CF0;
+        font-weight:600;
+    }
+.my-check-active {
+    border: 1px solid #2D8CF0;
+    background-image: url('../../../assets/icon/create_test_button_bg.png');
+    background-repeat: no-repeat;
+    color: #2D8CF0;
+    background-position-y: bottom;
+    background-position-x: right;
+    font-weight: 600;
+}
+.create-test-attr .border-buttom {
+    border-bottom: 1px dashed #DDDDDD;
+    padding-bottom: 30px;
+}
+.test-exercise-settting {
+    margin-top:30px;
+    min-height:100px;
+}
+    .test-exercise-settting p {
+        color: #AAAAAA;
+        font-size: 14px;
+    }
+.test-exercise-settting-item {
+    margin-top:15px;
+}
+.exercise-type {
+    font-size: 15px;
+    font-weight: 800;
+    font-family: STXihei;
+}
+.test-exercise-settting-num {
+    display: inline-block;
+    display: flex;
+    align-items: center;
+}
+
+    .test-exercise-settting-num .ivu-input-number {
+        width: 40px;
+    }
+.test-exercise-diff {
+    margin-right:10px;
+}
+.test-exercise-diff-num {
+    margin-left:10px;
+}
+.test-settting-num-wrap {
+    display:inline-block;
+    margin-left:40px;
+}
+.create-test-submit {
+    text-align:center;
+    width:100%;
+    margin-top:50px;
+}
+    .create-test-submit .ivu-btn {
+        padding:5px 40px;
+    }
+
+.test-import-item{
+    margin-top:30px;
+}
+.test-import-item-bg {
+    text-align:center;
+    background:#F5F5F5;
+    padding:40px 0px;
+    border-radius:15px;
+}
+    .test-import-item p {
+        font-size: 16px;
+        color: #888888;
+        font-weight: 400;
+        margin-top: 15px;
+    }
+.test-import-item .ivu-btn {
+    padding: 5px 50px;
+    font-size: 20px;
+    letter-spacing: 8px;
+    font-weight: 800;
+}
+.download-template {
+    float:right;
+    color:#0086E6;
+    font-size:18px;
+    margin-top:-35px;
+    margin-right:27%;
+    cursor:pointer;
+    font-weight:600;
+    letter-spacing:2px;
+}
+.text-order-type {
+    height:50px;
+    display:flex;
+    font-size:15px;
+    flex-direction:row;
+    align-items:center;
+    font-weight:600;
+    cursor:pointer;
+}
+    .text-order-type span {
+        margin-left:20px;
+    }
+    .text-order-type .ivu-checkbox-wrapper {
+        font-size:15px;
+    }
+    .text-order-type .ivu-checkbox-group-item {
+        margin-left:20px;
+    }
+    .text-order-type .ivu-btn {
+        padding:2px 5px;
+    }
+.my-iframe-style {
+    width: 100%;
+    border: none;
+    height: 600px;
+}
+.perview-word-analysis {
+    margin-top: 20px;
+}
+    .perview-word-analysis h2 {
+        text-align: center;
+        margin-bottom: 20px;
+    }
+    .perview-word-analysis .ivu-btn {
+        float: right;
+        margin-top: -45px;
+        padding: 0px 8px;
+        margin-right: 32%;
+        font-size: 14px;
+        font-weight: 600;
+        color: dodgerblue;
+        border: 1px solid white;
+    }
+        .perview-word-analysis .ivu-btn:hover {
+            border: 1px solid dodgerblue;
+            background: dodgerblue;
+            color:white;
+        }

+ 478 - 54
TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.vue

@@ -1,87 +1,511 @@
 <template>
 <template>
-  <div class="ev-container">
-    <h1>新建测试</h1>
-    <Divider />
-    <div class="exersices-attr display-flex">
-      <div class="exersices-attr-type my-radio-style">
-        <IconText :text="'测试情景'" :color="'green'" :icon="'md-apps'"></IconText>
-        <RadioGroup v-model="exersicesType" type="button" @on-change="typeChange">
-          <Radio label="single" :disabled="isEdit">模拟</Radio>
-          <Radio label="multiple" :disabled="isEdit">段考</Radio>
-          <Radio label="judge" :disabled="isEdit">周考</Radio>
-          <Radio label="complete" :disabled="isEdit">小考</Radio>
-          <Radio label="subjective" :disabled="isEdit">自定</Radio>
-        </RadioGroup>
+  <div>
+    <div class="ev-container">
+      <h1 @click="toTestPaper" style="cursor:pointer;">新建测试</h1>
+      <Divider />
+      <div class="exersices-attr display-flex">
+        <div class="exersices-attr-type my-radio-style test-scene">
+          <IconText :text="'测试情景'" :color="'green'" :icon="'ios-cloudy-night'"></IconText>
+          <RadioGroup v-model="testBasicAttr.testScene" type="button">
+            <Radio label="simulation">模拟</Radio>
+            <Radio label="sectional">段考</Radio>
+            <Radio label="week">周考</Radio>
+            <Radio label="small">小考</Radio>
+            <Radio label="custom">自定</Radio>
+          </RadioGroup>
+        </div>
+        <div class="exersices-attr-diff my-radio-style test-type">
+          <IconText :text="'测试类型'" :color="'red'" :icon="'ios-settings'"></IconText>
+          <RadioGroup v-model="testBasicAttr.testType" type="button">
+            <Radio label="formal">正式成绩</Radio>
+            <Radio label="practice">练习成绩</Radio>
+            <Radio label="statistics">统计(问卷)</Radio>
+          </RadioGroup>
+        </div>
       </div>
       </div>
-      <div class="exersices-attr-diff my-radio-style">
-        <IconText :text="'测试类型'" :color="'red'" :icon="'md-pulse'"></IconText>
-        <RadioGroup v-model="exersicesDiff" type="button">
-          <Radio label="0" @click.native="diffChange($event,'0')">正式成绩</Radio>
-          <Radio label="1" @click.native="diffChange($event,'1')">练习成绩</Radio>
-          <Radio label="2" @click.native="diffChange($event,'2')">统计(问卷)</Radio>
-        </RadioGroup>
+      <div class="exersices-attr display-flex" style="margin-top:30px;">
+        <div class="exersices-attr-type my-radio-style test-target">
+          <IconText :text="'测试对象'" :color="'#FF7F24'" :icon="'ios-people'"></IconText>
+          <RadioGroup v-model="testBasicAttr.testTarget" type="button">
+            <Radio label="class">同年级</Radio>
+            <Radio label="grade">跨年级</Radio>
+            <Radio label="school">跨学校</Radio>
+          </RadioGroup>
+        </div>
+        <div class="exersices-attr-diff my-radio-style test-mode">
+          <IconText :text="'创建方式'" :color="'#0086e6'" :icon="'ios-create'"></IconText>
+          <RadioGroup v-model="testBasicAttr.testMode" type="button">
+            <Radio label="auto" >自动组题</Radio>
+            <Radio label="import">批量导入</Radio>
+            <Radio label="choose">题库挑选</Radio>
+          </RadioGroup>
+        </div>
+      </div>
+      <div class="create-wrap" v-if="testBasicAttr.testMode == 'auto'">
+        <Divider />
+        <div class="create-test-attr">
+          <div>
+            <IconText style="float:left;" :text="'已选章节'" :color="'#0086e6'" :icon="'md-checkbox-outline'"></IconText>
+            <IconText style="float:right; cursor:pointer;" :text="'清空'" :color="'#AAAAAA'" :icon="'ios-trash-outline'" :iconSize="20" :textSize="14" @click.native="clearTags('auto')"></IconText>
+            <div style="clear:both;"></div>
+          </div>
+
+          <div class="test-chapter-wrap">
+            <p v-if="autoCreate.chapters.length == 0">您未选择章节!</p>
+            <Tag type="dot" closable v-for="(item,index) in autoCreate.chapters" :key="index" @on-close="clearCurrentTag(index,'auto')">{{item}}</Tag>
+          </div>
+        </div>
+        <div class="create-test-attr">
+          <IconText :text="'试卷设置'" :color="'#0086e6'" :icon="'ios-cog'"></IconText>
+          <div class="test-attr-item">
+            <label class="label-style">出卷方式:</label>
+            <RadioGroup v-model="autoCreate.createWay">
+              <Radio label="relation">
+                关联出题
+              </Radio>
+              <Tooltip max-width="200" content="匹配出来的试题包含的知识点(章节),最少有一个在已选的知识点(章节)中,这个方式适用于期末考试、学业考试、升学考试等试卷类型。出题的综合性较强。" placement="top">
+                <Icon type="md-help" color="#0086e6" size="16" style="cursor:pointer;" />
+              </Tooltip>
+              <Radio label="accurate" style="margin-left:30px;">
+                精准出题
+              </Radio>
+              <Tooltip max-width="200" content="匹配出来的试题包含的知识点(章节)。都在已选的知识点(章节)中,这个方式保证了组卷的精准性,避免超纲试题的出现,适用于同步类型的试卷。" placement="top">
+                <Icon type="md-help" color="#0086e6" size="16" style="cursor:pointer;" />
+              </Tooltip>
+            </RadioGroup>
+          </div>
+          <div class="test-attr-item">
+            <label class="label-style">试题过滤:</label>
+            <CheckboxGroup v-model="autoCreate.createFilter" style="display:inline-block;">
+              <Checkbox label="norepeat">过滤已使用的试题</Checkbox>
+              <Checkbox label="nobeyond" style="margin-left:30px;">防超纲出题</Checkbox>
+            </CheckboxGroup>
+          </div>
+        </div>
+        <div class="create-test-attr set-question-num">
+          <IconText :text="'题型/题量设置'" :color="'#0086e6'" :icon="'md-list'"></IconText>
+          <div class="test-attr-item border-buttom">
+            <div class="my-check-button" :class="testExerciseType.indexOf(1) == -1 ? '' : 'my-check-active' " @click="toggleStatus(1)">
+              单选题
+            </div>
+            <div class="my-check-button" :class="testExerciseType.indexOf(2) == -1 ? '' : 'my-check-active' " @click="toggleStatus(2)">
+              多选题
+            </div>
+            <div class="my-check-button" :class="testExerciseType.indexOf(3) == -1 ? '' : 'my-check-active' " @click="toggleStatus(3)">
+              判断题
+            </div>
+            <div class="my-check-button" :class="testExerciseType.indexOf(4) == -1 ? '' : 'my-check-active' " @click="toggleStatus(4)">
+              填空题
+            </div>
+            <div class="my-check-button" :class="testExerciseType.indexOf(5) == -1 ? '' : 'my-check-active' " @click="toggleStatus(5)">
+              问答题
+            </div>
+            <div class="my-check-button" :class="testExerciseType.indexOf(6) == -1 ? '' : 'my-check-active' " @click="toggleStatus(6)">
+              综合题
+            </div>
+          </div>
+          <div class="test-exercise-settting test-attr-item">
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(1) != -1">
+              <span class="exercise-type">单选题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Single[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Single[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Single[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(2) != -1">
+              <span class="exercise-type">多选题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Multiple[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Multiple[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Multiple[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(3) != -1">
+              <span class="exercise-type">判断题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Judge[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Judge[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Judge[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(4) != -1">
+              <span class="exercise-type">填空题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Complete[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Complete[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Complete[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(5) != -1">
+              <span class="exercise-type">问答题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Subjective[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Subjective[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Subjective[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <div class="test-exercise-settting-item" v-show="testExerciseType.indexOf(6) != -1">
+              <span class="exercise-type">综合题:</span>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">容易</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Compose[0]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">10道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">普通</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Compose[1]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">5道试题可用</label>
+                </div>
+              </div>
+              <div class="test-settting-num-wrap">
+                <div class="test-exercise-settting-num">
+                  <label class="test-exercise-diff">困难</label>
+                  <InputNumber :max="10" :min="1" v-model="autoCreate.exerciseNum.Compose[2]" placeholder="0"></InputNumber>
+                  <label class="test-exercise-diff-num">2道试题可用</label>
+                </div>
+              </div>
+            </div>
+
+            <p v-if="testExerciseType.length == 0">请选择题目类型,并设置题目数量!</p>
+          </div>
+          <div class="create-test-submit">
+            <Button type="info" @click="autoCreateTest">生成试卷</Button>
+          </div>
+
+        </div>
+      </div>
+
+      <div class="create-wrap" v-if="testBasicAttr.testMode == 'import' ">
+        <Divider />
+        <div class="create-test-attr">
+          <IconText :text="'导入说明'" :color="'#0086e6'" :icon="'md-reorder'"></IconText>
+          <div class="test-import-item">
+            <p>
+              1、暂时只支持“*.doc、.docx”格式的文件导入,文件大小不超过10M,建议使用模板导入;
+            </p>
+            <p>
+              2、题目必须包含【题文】、【答案】、【解析】、【结束】字样,若题目没有解析,则内容写“无”;
+            </p>
+            <p>
+              3、导入的题型暂时只支持单选题、多选题、判断题、填空题、主观题。
+            </p>
+          </div>
+        </div>
+        <div class="create-test-attr">
+          <IconText :text="'选择文件'" :color="'#0086e6'" :icon="'md-grid'"></IconText>
+          <div class="test-import-item test-import-item-bg">
+            <Upload multiple action="api/ImportExercise/uploadWord" :headers="headers" :show-upload-list="hind" :on-success="uploadSuccess">
+              <Button type="info">导入文件</Button>
+            </Upload>
+            <span class="download-template"><a href="https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelosevaluation/20190628/%E9%A2%98%E7%9B%AE%E6%A8%A1%E6%9D%BF.docx">下载模板</a></span>
+            <p>选择文件“*.doc、 *.docx”文件</p>
+          </div>
+        </div>
+
+      </div>
+      <div class="create-wrap" v-if="testBasicAttr.testMode == 'choose'">
+        <Divider />
+        <div class="create-test-attr">
+          <div>
+            <IconText style="float:left;" :text="'已选章节'" :color="'#0086e6'" :icon="'md-checkbox-outline'"></IconText>
+            <IconText style="float:right; cursor:pointer;" :text="'清空'" :color="'#AAAAAA'" :icon="'ios-trash-outline'" :iconSize="20" :textSize="14" @click.native="clearTags('auto')"></IconText>
+            <div style="clear:both;"></div>
+          </div>
+
+          <div class="test-chapter-wrap">
+            <p v-if="chooseCreate.chapters.length == 0">您未选择章节!</p>
+            <Tag type="dot" closable v-for="(item,index) in chooseCreate.chapters" :key="index" @on-close="clearCurrentTag(index,'choose')">{{item}}</Tag>
+          </div>
+
+          <div class="create-test-attr">
+            <IconText :text="'题目类型'" :color="'#0086e6'" :icon="'md-apps'"></IconText>
+            <div class="my-radio-style" style="margin-left:33px;">
+              <RadioGroup v-model="chooseCreate.exersicesType" type="button">
+                <Radio label="single" >单选</Radio>
+                <Radio label="multiple" >多选</Radio>
+                <Radio label="judge" >判断</Radio>
+                <Radio label="complete" >填空</Radio>
+                <Radio label="subjective" >问答</Radio>
+              </RadioGroup>
+            </div>
+          </div>
+          <div class="create-test-attr">
+            <IconText :text="'题目难度'" :color="'#0086e6'" :icon="'md-pulse'"></IconText>
+            <div class="my-radio-style" style="margin-left:33px;">
+              <RadioGroup v-model="chooseCreate.exersicesDiff" type="button">
+                <Radio label="0">容易</Radio>
+                <Radio label="1">较易</Radio>
+                <Radio label="2">一般</Radio>
+                <Radio label="3">较难</Radio>
+                <Radio label="4">困难</Radio>
+              </RadioGroup>
+            </div>
+          </div>
+          <div class="create-test-attr">
+            <IconText :text="'挑选类型'" :color="'#0086e6'" :icon="'md-keypad'"></IconText>
+            <div class="my-radio-style" style="margin-left:33px;">
+              <RadioGroup v-model="chooseCreate.type" type="button">
+                <Radio label="0">挑选题目</Radio>
+                <Radio label="1">挑选试卷</Radio>
+              </RadioGroup>
+            </div>
+          </div>
+        </div>
       </div>
       </div>
     </div>
     </div>
-    <div class="exersices-attr display-flex">
-      <div class="exersices-attr-type my-radio-style">
-        <IconText :text="'测试对象'" :color="'green'" :icon="'md-apps'"></IconText>
-        <RadioGroup v-model="exersicesType" type="button" @on-change="typeChange">
-          <Radio label="single" :disabled="isEdit">同年级</Radio>
-          <Radio label="multiple" :disabled="isEdit">跨年级</Radio>
-          <Radio label="judge" :disabled="isEdit">跨学校</Radio>
-        </RadioGroup>
+    <div class="text-order-type-wrap" v-if="testBasicAttr.testMode == 'choose'">
+      <div class="text-order-type" style="float:left;">
+        <span>时间<Icon type="md-arrow-down" /></span>
+        <span>使用次数<Icon type="md-arrow-down" /></span>
+        <CheckboxGroup v-model="chooseCreate.filter">
+          <Checkbox label="norepeat">过滤已使用的试题</Checkbox>
+          <Checkbox label="nobeyond">防超纲出题</Checkbox>
+        </CheckboxGroup>
       </div>
       </div>
-      <div class="exersices-attr-diff my-radio-style" style="margin-top:30px;">
-        <IconText :text="'创建方式'" :color="'red'" :icon="'md-pulse'"></IconText>
-        <RadioGroup v-model="exersicesDiff" type="button">
-          <Radio label="0" @click.native="diffChange($event,'0')">题库挑选</Radio>
-          <Radio label="1" @click.native="diffChange($event,'1')">自动组题</Radio>
-          <Radio label="2" @click.native="diffChange($event,'2')">批量导入</Radio>
-        </RadioGroup>
+      <div class="text-order-type" style="float:right;margin-right:20px;">
+        <span>共计:99题</span>
+        <span style="margin-right:20px;">已选:0题</span>
+        <Button shape="circle">选择本页全部试题</Button>
       </div>
       </div>
+      <div style="clear:both;"></div>
     </div>
     </div>
-    <div class="save-wrap display-flex" style="display:none;">
-      <Button type="success" @click="getContent(exersicesType)">保存</Button>
-      <Button type="success" @click="resetEditor" style="margin-left:10px">重置</Button>
+
+    <div class="ev-container" v-if="testBasicAttr.testMode == 'choose'">
+      题目列表
+    </div>
+    <div class="ev-container perview-word-analysis" v-if="testBasicAttr.testMode == 'import' && srcdoc != ''">
+      <h2 >文档解析预览 </h2>
+      <Button shape="circle" icon="md-cloud-upload" @click="uploadHtmlString">确认上传</Button>
+      <iframe class="my-iframe-style" src="https://www.baidu.com" :srcdoc="srcdoc"></iframe>
     </div>
     </div>
   </div>
   </div>
+
 </template>
 </template>
 <script>
 <script>
   //默认创建测试模板
   //默认创建测试模板
   import IconText from '@/components/evaluation/IconText.vue'
   import IconText from '@/components/evaluation/IconText.vue'
-  const defaultExercise = {
-          question: "",
-          options: [],
-          difficulty:"",
-          answer: [],
-          explain: "",
-          type:""
-        }
   export default {
   export default {
     components: {
     components: {
       IconText
       IconText
     },
     },
     data() {
     data() {
       return {
       return {
-        testModel: {
-          passwd: '',
-          passwdCheck: '',
-          age: ''
+        srcdoc:'',
+        hind: false,
+        value2: null,
+        exersicesDiff:'',
+        testBasicAttr: {
+          testScene: 'simulation',
+          testType: 'formal',
+          testTarget: 'class',
+          testMode: 'auto'
         },
         },
+        chooseCreate:{
+          chapters: ["1.1 正数和复数", "1.5 有理数的加减法", "3.3 从算式到方程"],
+          exersicesType: '',
+          exersicesDiff: '',
+          type: '',
+          filter:[]
+        },
+        autoCreate: {
+          chapters: ["1.1 正数和复数", "1.5 有理数的加减法", "3.3 从算式到方程"],
+          createWay: 'relation',
+          createFilter: [],
+          exerciseNum: {
+            Single: [null, null, null],
+            Multiple: [null, null, null],
+            Judge: [null, null, null],
+            Complete: [null, null, null],
+            Subjective: [null, null, null],
+            Compose: [null, null, null]
+          }
+          
+        },
+        
+        testExerciseType:[1]
       }
       }
     },
     },
     created() {
     created() {
-
+      
     },
     },
     methods: {
     methods: {
-      
+      autoCreateTest() {
+        let requestData = {};
+        requestData["testBasicAttr"] = this.testBasicAttr;
+        requestData["testMode"] = this.autoCreate;
+        console.log(requestData);
+      },
+      uploadSuccess(response, file, fileList) {
+        console.log(response);
+        if (response.error == null) {
+          this.$Message.success('文件上传解析成功!');
+          this.srcdoc = response.result.data.HtmlString;
+          console.log(response.result.data.HtmlString);
+        } else {
+          this.$Message.error('对不起,文档解析失败!');
+        }
+      },
+      uploadHtmlString() {
+        let requestData = {
+            htmlString: this.srcdoc
+        }
+
+        this.$api.SaveAnalyzeHtml(requestData).then(res => {
+          if (res.error == null) {
+            localStorage.setItem("questions", JSON.stringify(res.result.data));
+            this.$router.push({
+              name: 'testPaper',//或者路径跳转path: '/addCreditCards',
+              params: {
+                flag:1
+              }
+            });
+          }
+        }
+        );
+      },
+      toTestPaper() {
+        this.$router.push({
+          path: '/testPaper',//或者路径跳转path: '/addCreditCards',
+        });
+      },
+      toggleStatus(type){
+        let index = this.testExerciseType.indexOf(type);
+        if (index == -1) {
+          this.testExerciseType.push(type);
+        } else {
+          this.testExerciseType.splice(index, 1);
+        }
+      },
+      clearTags(flag) {
+        if (flag == 'auto') {
+          this.autoCreate.chapters = [];
+        } else {
+          this.chooseCreate.chapters = [];
+        }
+      },
+      clearCurrentTag(index, flag) {
+        if (flag == 'auto') {
+          this.autoCreate.chapters.splice(index, 1);
+        } else {
+          this.chooseCreate.chapters.splice(index, 1);
+        }
+        
+      }
 
 
     },
     },
     mounted() {
     mounted() {
       
       
+    },
+    computed: {
+      headers(){
+        let hd = {}
+        hd["Authorization"] = "Bearer "+ localStorage.getItem("token");
+        console.log(hd);
+        return hd;
+      }
     }
     }
   }
   }
 </script>
 </script>
-<style scoped>
-  @import"../index/CreateTest.css";
+<style src="../index/CreateTest.css" scoped>
+  /*@import "../index/CreateTest.css";*/
+</style>
+<style>
+  .test-exercise-settting-num .ivu-input-number-handler-wrap {
+    display: none !important;
+  }
+
+  .test-exercise-settting-num .ivu-input-number-input {
+    text-align: center;
+    color:red;
+    font-size:16px;
+  }
 </style>
 </style>

+ 255 - 35
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.css

@@ -1,5 +1,6 @@
 .ev-list-container {
 .ev-list-container {
     user-select:none !important;
     user-select:none !important;
+    position:relative;
 }
 }
     .ev-list-container .ev-header {
     .ev-list-container .ev-header {
         background:#fff;
         background:#fff;
@@ -25,10 +26,161 @@
         margin:15px 0;
         margin:15px 0;
     }
     }
 
 
-.ev-content {
-    background:none;
+.no-data-text {
+    width: 100%;
+    padding:30px;
+    background: #fff;
+    display:flex;
+    flex-direction:column;
+    justify-content:center;
+    align-items:center;
+    margin-top:10px;
+    font-size:16px;
+}
+
+.ev-list-operation {
+    position:relative;
+    width: 100%;
+    height: 60px;
+    background: #fff;
+    padding:10px;
+    /*border-top:1px dashed rgba(128, 128, 128,0.4);*/
+    margin-top: 10px;
+    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 {
+        /*margin-right:120px;*/
+        font-weight:bold;
+        color:rgb(16, 171, 231);
+        font-size:16px;
+        cursor:pointer;
+    }
+
+    .ev-list-operation .ivu-icon {
+        font-size:16px;
+        margin-right:6px;
+        cursor:pointer;
+        vertical-align:initial;
+    }
+
+    .ev-list-operation .ivu-checkbox-checked .ivu-checkbox-inner {
+        background: #01b4ef;
+        border-color: #01b4ef;
+    }
+
+    .ev-list-operation .operation-cart {
+        position:absolute;
+        right:100px;
+        top:5px;
+        height:100%;
+        padding:0 10px;
+        display:flex;
+        flex-direction:row;
+        justify-content:center;
+        align-items:center;
+    }
+    .ev-list-operation .operation-cart img{
+        width:40px;
+        height:30px;
+        cursor:pointer;
+    }
+
+    .ev-list-operation .operation-cart span{
+        cursor:pointer;
+        font-size:16px;
+        font-weight:bold;
+        margin-right:10px;
+    }
+
+    .ev-list-operation .ivu-poptip-title {
+        display: none;
+    }
+
+    .ev-list-operation .ivu-poptip-body {
+        padding:0;
+    }
+
+    .ev-list-operation .ivu-poptip-popper[x-placement^=bottom] .ivu-poptip-arrow:after {
+        border-bottom-color: rgb(16, 171, 231);
+    }
+
+    .basket-content {
+        width: 300px;
+    }
+
+        .basket-content .basket-title {
+            height: 40px;
+            font-size:16px;
+            text-align:center;
+            line-height:40px;
+            color:#fff;
+            background: rgb(16, 171, 231);
+        }
+
+        .basket-content .basket-body {
+            width:100%;
+            padding:20px;
+        }
+
+            .basket-content .basket-body .ivu-progress {
+                width:45%;
+            }
+
+            .basket-content .basket-body .ivu-progress-inner {
+                vertical-align:unset;
+            }
+
+        .basket-content .basket-body .basket-item {
+            margin-top:15px;
+        }
+
+            .basket-content .basket-body .basket-delete {
+                font-size:14px;
+                margin-left:5px;
+                color:#01b4ef;
+            }
+
+            .basket-content .basket-footer {
+                height: 40px;
+                font-size: 16px;
+                text-align: center;
+                line-height: 40px;
+                margin-top: 20px;
+                color: #fff;
+                background: rgb(16, 171, 231);
+                cursor: pointer;
+            }
+
+        .basket-content .basket-footer-no {
+            height: 40px;
+            font-size: 16px;
+            text-align: center;
+            line-height: 40px;
+            margin-top: 20px;
+            color: #fff;
+            background: #ccc;
+            cursor: pointer;
+        }
+
+
+
+        .ev-content {
+            background: none;
+        }
 .content-wrap {
 .content-wrap {
+    position:relative;
     width:100%;
     width:100%;
     height:auto;
     height:auto;
     display:flex;
     display:flex;
@@ -40,7 +192,7 @@
         height: auto;
         height: auto;
         padding: 20px;
         padding: 20px;
         margin-top: 10px;
         margin-top: 10px;
-        font-size: 16px;
+        font-size: 18px;
         font-weight: 600;
         font-weight: 600;
         background: #fff;
         background: #fff;
         /*box-shadow: 0px 5px 5px 2px rgb(187, 182, 182);*/
         /*box-shadow: 0px 5px 5px 2px rgb(187, 182, 182);*/
@@ -53,12 +205,6 @@
             padding:5px 10px;
             padding:5px 10px;
         }
         }
 
 
-        .content-wrap .exercise-item p {
-            margin:10px 0;
-            display:inherit;
-            word-break:break-all;
-        }
-
         .content-wrap .exercise-item:hover {
         .content-wrap .exercise-item:hover {
             box-shadow: 0px 0px 20px 2px rgb(228, 224, 224);
             box-shadow: 0px 0px 20px 2px rgb(228, 224, 224);
         }
         }
@@ -67,9 +213,21 @@
             display:unset;
             display:unset;
         }
         }
 
 
+        .content-wrap .exercise-item p {
+            margin: 10px 0;
+            display: inline-block;
+            word-break: break-all;
+        }
+
+.complete-line {
+    margin: 0 5px;
+    padding: 0 45px;
+    border-bottom: 2px solid rgb(128, 128, 128);
+}
+
 .exercise-item .item-question {
 .exercise-item .item-question {
     /*display: inline-block;*/
     /*display: inline-block;*/
-    margin-top:20px;
+    /*margin-top:20px;*/
 }
 }
 
 
 .exercise-item .item-difficulty {
 .exercise-item .item-difficulty {
@@ -78,7 +236,7 @@
     background: rgb(16, 171, 231);
     background: rgb(16, 171, 231);
     border-radius: 5px;
     border-radius: 5px;
     color: #fff;
     color: #fff;
-    font-size:14px;
+    font-size:13px;
 }
 }
 .exercise-item .item-type {
 .exercise-item .item-type {
     display: inline-block;
     display: inline-block;
@@ -86,13 +244,20 @@
     border: 2px solid rgb(16, 171, 231);
     border: 2px solid rgb(16, 171, 231);
     border-radius: 5px;
     border-radius: 5px;
     color: rgb(16, 171, 231);
     color: rgb(16, 171, 231);
-    font-size: 14px;
+    font-size: 13px;
+}
+
+.exercise-item .item-relevant-points{
+    display: inline-block;
+    padding: 1px 9px;
+    font-size: 13px;
 }
 }
 
 
 .exercise-item .item-answer {
 .exercise-item .item-answer {
     display: inline-block;
     display: inline-block;
     cursor:pointer;
     cursor:pointer;
     margin-top:12px;
     margin-top:12px;
+    font-size:16px;
 }
 }
 
 
 .exercise-item .item-answer-item {
 .exercise-item .item-answer-item {
@@ -118,9 +283,10 @@
 }
 }
 
 
 .exercise-item .item-explain {
 .exercise-item .item-explain {
-    display:table;
-    margin-top:10px;
+    display: table;
+    margin-top: 10px;
     cursor: pointer;
     cursor: pointer;
+    font-size: 16px;
 }
 }
 
 
 .exercise-item .item-explain-item {
 .exercise-item .item-explain-item {
@@ -149,8 +315,8 @@
     width: 100%;
     width: 100%;
     padding: 10px 0;
     padding: 10px 0;
     margin-top: 20px;
     margin-top: 20px;
-    font-size:14px;
-    color:rgb(16, 171, 231);
+    font-size: 14px;
+    border-top: 1px #c3c3c34d dashed;
 }
 }
 
 
     .exercise-item .item-tools .ivu-icon {
     .exercise-item .item-tools .ivu-icon {
@@ -160,27 +326,46 @@
         font-weight: bold;
         font-weight: bold;
     }
     }
 
 
-    .exercise-item .item-tools .item-tools-tool {
-        margin-left: 20px;
+    .exercise-item .item-tools .ivu-btn {
+        float:right;
+    }
+
+    .exercise-item .item-tools-tool {
+        margin-left: 10px;
         font-weight: bold;
         font-weight: bold;
         cursor: pointer;
         cursor: pointer;
         vertical-align: bottom;
         vertical-align: bottom;
+        color:rgb(16, 171, 231);
+        font-size:14px;
     }
     }
-
-    .exercise-item .item-tools .item-tools-bind {
-        display:none;
-        margin-top:5px;
+    
+    .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 {
+        padding: 0 10px;
+        vertical-align: sub;
+        color: #868686;
+        border-right: 2px solid #d2d2d2;
+        font-size:12px;
+    }
 
 
-.complete-line {
-    margin-left: 5px;
-    padding: 0 45px;
-    border-bottom: 2px solid rgb(128, 128, 128);
-}
 
 
 .ev-list-container h1, h2, h3, h4, h5, h6 {
 .ev-list-container h1, h2, h3, h4, h5, h6 {
     display:inline-block;
     display:inline-block;
@@ -287,7 +472,7 @@
     }
     }
 
 
     .transferModal .checked-point {
     .transferModal .checked-point {
-        margin:5px 15px;
+        margin:5px 10px;
         background:rgb(16, 171, 231);
         background:rgb(16, 171, 231);
         padding:5px 10px;
         padding:5px 10px;
         color:#fff;
         color:#fff;
@@ -313,16 +498,51 @@
         letter-spacing:1px;
         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 {
     .transferModal .point-checked {
-        background:rgb(16, 171, 231);
-        margin-left:10px;
-        padding:10px;
+        background: rgb(16, 171, 231);
+        background-clip:content-box;
     }
     }
 
 
-    .transferModal .point-unchecked {
-        background: #ccc;
-        margin-left: 10px;
-        padding: 10px;
+    .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;
     }
     }
 
 
 
 

+ 359 - 81
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.vue

@@ -1,21 +1,30 @@
 <template>
 <template>
   <div class="ev-list-container">
   <div class="ev-list-container">
+
     <div class="ev-header">
     <div class="ev-header">
       <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
       <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
-      <span class="ev-title">我的题库</span>
+      <span class="ev-title">题库列表</span>
       <span class="ev-length">共 {{list.length}} 道题</span>
       <span class="ev-length">共 {{list.length}} 道题</span>
     </div>
     </div>
     <!-- 筛选部分 -->
     <!-- 筛选部分 -->
     <div class="filter-wrap">
     <div class="filter-wrap">
+      <div class="filter-item">
+        <span class="filter-title">来源:</span>
+        <RadioGroup v-model="filterOrigin" type="button" @on-change="filterOriginChange">
+          <Radio label="self">个人私有库</Radio>
+          <Radio label="school">学校公用库</Radio>
+          <Radio label="system">系统公用库</Radio>
+        </RadioGroup>
+      </div>
       <div class="filter-item">
       <div class="filter-item">
         <span class="filter-title">题型:</span>
         <span class="filter-title">题型:</span>
         <RadioGroup v-model="filterType" type="button" @on-change="filterTypeChange">
         <RadioGroup v-model="filterType" type="button" @on-change="filterTypeChange">
           <Radio label="all">全部</Radio>
           <Radio label="all">全部</Radio>
-          <Radio label="single">单选</Radio>
-          <Radio label="multiple">多选</Radio>
-          <Radio label="judge">判断</Radio>
-          <Radio label="complete">填空</Radio>
-          <Radio label="subjective">问答</Radio>
+          <Radio label="Single">单选</Radio>
+          <Radio label="Multiple">多选</Radio>
+          <Radio label="Judge">判断</Radio>
+          <Radio label="Complete">填空</Radio>
+          <Radio label="Subjective">问答</Radio>
         </RadioGroup>
         </RadioGroup>
       </div>
       </div>
       <div class="filter-item">
       <div class="filter-item">
@@ -37,54 +46,155 @@
         </RadioGroup>
         </RadioGroup>
       </div>
       </div>
     </div>
     </div>
+    <div class="ev-list-operation">
+      <Checkbox v-model="isShowAnswer">展示答案与解析</Checkbox>
+      <span class="import-exercise">
+        <Upload multiple action="api/ImportExercise/uploadWord" :headers="headers" :show-upload-list="isShowUploadList" :on-success="uploadSuccess">
+          <Button type="info">导入习题</Button>
+        </Upload>
+      </span>
+      <div class="operation-cart">
+        <Poptip trigger="hover" title="我的试题篮" placement="bottom">
+          <Badge :count="basketCount" show-zero type="success">
+            <img src="../../../assets/icon/icon_cart.png" />
+          </Badge>
+          <div class="basket-content" slot="content">
+            <p class="basket-title">共计 {{basketCount}} 道题</p>
+            <div class="basket-body">
+              <div class="basket-item">
+                <span>单选题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Single.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Single.length }} 道 <span class="basket-delete" @click="handleBasketDelete('Single')">删除</span></span>
+              </div>
+              <div class="basket-item">
+                <span>多选题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Multiple.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Multiple.length}} 道 <span class="basket-delete" @click="handleBasketDelete('Multiple')">删除</span></span>
+              </div>
+              <div class="basket-item">
+                <span>判断题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Judge.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Judge.length}} 道 <span class="basket-delete" @click="handleBasketDelete('Judge')">删除</span></span>
+              </div>
+              <div class="basket-item">
+                <span>填空题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Complete.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Complete.length}} 道 <span class="basket-delete" @click="handleBasketDelete('Complete')">删除</span></span>
+              </div>
+              <div class="basket-item">
+                <span>问答题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Subjective.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Subjective.length}} 道 <span class="basket-delete" @click="handleBasketDelete('Subjective')">删除</span></span>
+              </div>
+              <div class="basket-item">
+                <span>综合题</span>
+                <Progress :percent="basketList.all.length ? Number((basketList.Compose.length / basketList.all.length)*100) : 0" stroke-color="rgb(16, 171, 231)" hide-info />
+                <span style="margin-left:10px">{{ basketList.Compose.length}} 道 <span class="basket-delete" @click="handleBasketDelete('Compose')">删除</span></span>
+              </div>
+            </div>
+            <div :class="[basketList.all.length ? 'basket-footer' : 'basket-footer-no']">
+              <p @click="handleSubmitPaper">进入组卷中心</p>
+            </div>
+          </div>
+        </Poptip>
+      </div>
+    </div>
+    <!-- 筛选部分结束 -->
+
+
     <!-- 题目列表部分 -->
     <!-- 题目列表部分 -->
-    <div v-if="list.length == 0">暂无数据</div>
+    <div v-if="list.length == 0" class="no-data-text">
+      <img src="../../../assets/icon/no_data.svg" width="120"/>
+      <span style="margin-top:15px;color:#808080">暂无数据</span>
+    </div>
     <div class="content-wrap" v-else>
     <div class="content-wrap" v-else>
+      <Loading v-show="importLoading"></Loading>
+
       <div class="exercise-item" v-for="(item,index) of list">
       <div class="exercise-item" v-for="(item,index) of list">
-        <span class="item-difficulty" :style="{backgroundColor:diffColors[item.difficulty]}">{{exersicesDiff[item.difficulty]}}</span>
-        <span class="item-type">{{exersicesType[item.type]}}</span>
+        <!-- 题目难度类型以及绑定知识点 -->
+        <div class="item-types">
+          <span class="item-difficulty" :style="{backgroundColor:diffColors[item.difficulty || 3]}">{{exersicesDiff[item.difficulty || 3]}}</span>
+          <span class="item-type">{{exersicesType[item.type]}}</span>
+          <span class="item-relevant-points">
+            <span class="item-tools-bind">
+              <span class="item-tools-tool">
+                <span class="item-bind-point">已关联知识点:</span>
+                <span class="item-bind-point" v-for="concept in item.concept" v-show="item.concept"><Tag color="success">{{concept.name}}</Tag></span>
+                <span class="item-bind-point"  v-show="!item.concept">暂未关联</span>
+                <Icon type="md-link" size="20" />
+                <span @click="handleBindPoint(item.concept || [])">绑定知识点</span>
+              </span>
+            </span>
+          </span>
+        </div>
+        <!-- 题干部分 --> 
         <div class="item-question">
         <div class="item-question">
           <p>{{index+1}} : <span v-html="item.question"></span></p>
           <p>{{index+1}} : <span v-html="item.question"></span></p>
         </div>
         </div>
-        <div v-for="(option,optionIndex) in item.options">
+        <!-- 选项部分 -->
+        <div v-for="(option,optionIndex) in item.option">
           <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
           <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
         </div>
         </div>
-        <div class="item-answer">
+
+        <!-- 如果是组合题 -->
+        <div v-for="(childQuestion,childIndex) in item.children" v-if="item.children.length">
+          <div class="item-question">
+            <p>{{childIndex+1}} : <span v-html="childQuestion.question"></span></p>
+          </div>
+          <div v-for="(childOption,childOptionIndex) in childQuestion.option">
+            <p>{{String.fromCharCode(64 + parseInt(childOptionIndex+1))}} : <span v-html="childOption.value"></span></p>
+          </div>
+          <div class="item-answer" v-show="isShowAnswer">
+            <span style="color:#01b4ef">【答案】:</span>
+            <span v-html="childQuestion.answer[0] || childQuestion.answer" v-if="childQuestion.type == 'Subjective'"></span>
+            <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else-if="childQuestion.type == 'Complete'" v-html="answer"></span>
+            <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else>{{answer}}</span>
+          </div>
+          <div class="item-explain" v-show="isShowAnswer">
+            <span style="color:#01b4ef">【解析】:</span>
+            <span v-html="childQuestion.explain"></span>
+          </div>
+        </div>
+        <!-- 组合题结束 -->
+        <!-- 答案展示部分 -->
+        <div class="item-answer" v-show="item.type != 'Compose'">
           <span class="answer-title-line"></span>
           <span class="answer-title-line"></span>
           <span class="answer-title" @click="showAnswer($event,'answer')">答案:点击展开答案详情</span>
           <span class="answer-title" @click="showAnswer($event,'answer')">答案:点击展开答案详情</span>
           <div class="item-answer-details">
           <div class="item-answer-details">
-            <span v-html="item.answer" v-if="item.type == 'subjective'"></span>
-            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'complete'" v-html="answer"></span>
-            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
-
+            <span v-html="item.answer" v-if="item.type == 'Subjective'"></span>
+            <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'Complete'" v-html="answer"></span>
+            <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
           </div>
           </div>
         </div>
         </div>
-        <div class="item-explain">
+        <!-- 解析部分 -->
+        <div class="item-explain" v-show="item.type != 'Compose'">
           <span class="explain-title-line"></span>
           <span class="explain-title-line"></span>
           <span class="explain-title" @click="showAnswer($event,'explain')">解析:点击展开解析详情</span>
           <span class="explain-title" @click="showAnswer($event,'explain')">解析:点击展开解析详情</span>
           <div class="item-explain-details">
           <div class="item-explain-details">
             <span v-html="item.explain"></span>
             <span v-html="item.explain"></span>
           </div>
           </div>
         </div>
         </div>
+        <!-- 底部题目操作栏 -->
         <div class="item-tools">
         <div class="item-tools">
-          <Button type="primary" @click="handleEdit(item)">编辑题目</Button>
-          <Button type="info">选题</Button>
-          <span class="item-tools-bind">
-            <span class="item-tools-tool" @click="handleBindPoint"><Icon type="ios-link" />绑定知识点</span>
-            <span class="item-tools-tool"><Icon type="ios-link" />绑定科目</span>
-            <span class="item-tools-tool"><Icon type="ios-link" />绑定课纲</span>
-          </span>
+          <span class="item-tools-info">来源:浙江省温州市2019年中考数学试卷</span>
+          <span class="item-tools-info">使用次数:98 次</span>
+          <span class="item-tools-info" style="border:0">更新时间:2019-07-01</span>
+          <Button type="info" @click="handleChoose(item)">{{basketList.all.indexOf(item) > -1 ? '已选入' : '选题'}}</Button>
+          <Button type="primary" @click="handleEdit(item)" style="margin-right:10px">编辑题目</Button>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
+
+    <!-- 底部分页区域 -->
     <Page :total="totalNum"
     <Page :total="totalNum"
           show-sizer
           show-sizer
           @on-page-size-change="pageSizeChange"
           @on-page-size-change="pageSizeChange"
           @on-change="pageChange"
           @on-change="pageChange"
           :page-size-opts="[5,10,15,20]" />
           :page-size-opts="[5,10,15,20]" />
     <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
     <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
+    <Button type="success" @click="backToPaper" style="margin:10px;">试卷</Button>
 
 
-    <!-- 绑定知识点弹窗 Transfer -->
+    <!-- 绑定知识点弹窗开始 -->
     <Modal v-model="bindPointModal"
     <Modal v-model="bindPointModal"
            title="绑定知识点"
            title="绑定知识点"
            width="500"
            width="500"
@@ -93,77 +203,110 @@
            @on-cancel="">
            @on-cancel="">
       <div class="point-list">
       <div class="point-list">
         <p class="bind-title">选择知识点</p>
         <p class="bind-title">选择知识点</p>
-        <Input search placeholder="搜索知识点..." />
-        <Tree :data="knowPointList" ref="pointTree" :render="renderContent" @on-check-change="pointTreeCheck" check-strictly></Tree>
+        <Input search placeholder="搜索知识点..." v-model="searchWord" @on-change="filterChange" />
+        <Tabs v-model="tabSelectVal">
+          <TabPane label="校本知识点" name="school">
+            <Tree :data="knowPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
+          </TabPane>
+          <TabPane label="标准知识点" name="all">
+            <Tree :data="allPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
+          </TabPane>
+        </Tabs>
+        <Spin fix v-show="pointListLoading"></Spin>
       </div>
       </div>
-
       <div class="selected-point-list">
       <div class="selected-point-list">
-        <p class="bind-title">已选知识点<span style="font-weight:500"> (最多绑定5个知识点)</span><span class="btn-clear" @click="handleClearChecked">清空</span></p>
-        <span class="checked-point" v-for="item in checkedPointList">{{item.name}}</span>
+        <p class="bind-title">已选知识点<span style="font-weight:500;font-size:12px"> (最多绑定5个知识点,颜色代表不同来源)</span><span class="btn-clear" @click="handleClearChecked">清空</span></p>
+        <span class="checked-point" :style="{background:item.origin=='school'?'#10abe7':'#12b9ab'}" v-for="item in checkedPointList">{{item.name}}<Icon type="md-close" color="#fff" style="margin-left:5px;cursor:pointer" @click="deleteCheckedPoint(item)" /></span>
       </div>
       </div>
     </Modal>
     </Modal>
-
-
+    <!-- 绑定知识点弹窗结束 -->
   </div>
   </div>
 </template>
 </template>
 <script>
 <script>
   import IconText from '@/components/evaluation/IconText.vue'
   import IconText from '@/components/evaluation/IconText.vue'
+  import Loading from '@/common/Loading.vue'
   import questions from './list.json'
   import questions from './list.json'
 import { setTimeout } from 'core-js';
 import { setTimeout } from 'core-js';
   export default {
   export default {
     components: {
     components: {
-      IconText
+      IconText,
+      Loading
     },
     },
     data() {
     data() {
       return {
       return {
         list: [],
         list: [],
+        searchWord: '',
+        basketCount: 0,
+        basketList: {
+          all:[],
+          Single: [],
+          Multiple: [],
+          Judge: [],
+          Complete: [],
+          Subjective: [],
+          Compose:[]
+        },
+        pointListLoading: true,
+        isShowUploadList:false,
+        schoolInfo: {},
         bindPointModal: false,
         bindPointModal: false,
         exersicesType: {
         exersicesType: {
-          single: "单选",
-          multiple: "多选",
-          judge: "判断",
-          complete: "填空",
-          subjective:"问答"
+          Single: "单选",
+          Multiple: "多选",
+          Judge: "判断",
+          Complete: "填空",
+          Subjective:"问答",
+          Compose:"综合题"
         },
         },
         exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
         exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
         diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
         diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
-        filterType:"all",
+        filterType: "all",
+        filterOrigin:"self",
         filterDiff:"all",
         filterDiff:"all",
         filterSort: "0",
         filterSort: "0",
         pageSize: 5,
         pageSize: 5,
         pageNum: 1,
         pageNum: 1,
         totalNum: 100,
         totalNum: 100,
-        allList: questions.list,
+        allList: questions.result.data,
         knowPointList: [],
         knowPointList: [],
-        checkedPointList: []
+        schoolPointList: [],
+        allPointList:[],
+        checkedPointList: [],
+        isShowAnswer: true,
+        importLoading:false,
+        tabSelectVal:"school"
       }
       }
     },
     },
     created() {
     created() {
-      this.list = questions.list;
-      this.totalNum = questions.list.length;
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
+      this.list = questions.result.data;
+      this.totalNum = questions.result.data.length;
       if (this.$route.params.exerciseItem) {
       if (this.$route.params.exerciseItem) {
         this.list.unshift(this.$route.params.exerciseItem);
         this.list.unshift(this.$route.params.exerciseItem);
       }
       }
-
-
     },
     },
     methods: {
     methods: {
 
 
+      //根据题库加载题目
+      filterOriginChange(origin) {
+        console.log(origin);
+      },
+
       //筛选题型
       //筛选题型
       filterTypeChange(val) {
       filterTypeChange(val) {
         if (val == "all") {
         if (val == "all") {
-          this.list = questions.list;
+          this.list = questions.result.data;
         } else {
         } else {
-          this.list = questions.list.filter(item => item.type == val);
+          this.list = questions.result.data.filter(item => item.type == val);
         }
         }
       },
       },
 
 
       //筛选难度
       //筛选难度
       filterDiffChange(val) {
       filterDiffChange(val) {
          if (val == "all") {
          if (val == "all") {
-          this.list = questions.list;
+          this.list = questions.result.data;
          } else {
          } else {
-           this.list = questions.list.filter(item => item.difficulty == val);
+           this.list = questions.result.data.filter(item => item.difficulty == val);
         }
         }
       },
       },
 
 
@@ -194,11 +337,17 @@ import { setTimeout } from 'core-js';
           })
           })
       },
       },
 
 
+      backToPaper() {
+        this.$router.push({
+            path: '/testPaper',//或者路径跳转path: '/addCreditCards',
+          })
+      },
+
       //切换页码
       //切换页码
       pageChange(page) {
       pageChange(page) {
         let start = this.pageSize * (page - 1);
         let start = this.pageSize * (page - 1);
         let end = this.pageSize * page;
         let end = this.pageSize * page;
-        let list = questions.list;
+        let list = questions.result.data;
         this.list = list.slice(start, end);
         this.list = list.slice(start, end);
         window.scroll(0, 0);
         window.scroll(0, 0);
       },
       },
@@ -211,6 +360,8 @@ import { setTimeout } from 'core-js';
 
 
       //编辑习题
       //编辑习题
       handleEdit(item) {
       handleEdit(item) {
+        item.options = item.option;
+        item.difficulty = item.difficulty || 2;
         this.$router.push({
         this.$router.push({
             name: 'createExercises',
             name: 'createExercises',
             params:{
             params:{
@@ -219,10 +370,58 @@ import { setTimeout } from 'core-js';
           })
           })
       },
       },
 
 
+
+      //选题
+      handleChoose(item) {
+        if (this.basketList.all.indexOf(item) > -1) {
+          this.$Message.warning("该试题已存在试卷篮!");
+        } else {
+          this.basketList[item.type].push(item);
+          this.basketList.all.push(item);
+          this.basketCount += 1;
+        }
+      },
+
+
+      //从试题篮删除题型
+      handleBasketDelete(type) {
+        this.$Modal.confirm({
+          title: '删除题型',
+          content: '<p>确认删除该题型吗?</p>',
+          okText:"确认",
+          cancelText:"取消",
+          onOk: () => {
+            this.basketList.all.forEach((item,index) => {
+              if (item.type == type) {
+                this.basketList.all.splice(index, 1);
+              }
+            })
+            //console.log(this.basketList[type]);
+            this.basketList[type] = [];
+            this.basketCount = this.basketList.all.length;
+            this.$Message.success("删除成功!");
+
+          }
+        });
+
+
+      },
+
+      //进入组卷中心
+      handleSubmitPaper() {
+        if (this.basketList.all.length) {
+          this.$router.push({
+            name:'testPaper'
+          })
+        }
+      },
+
       //绑定知识点操作
       //绑定知识点操作
-      handleBindPoint() {
+      handleBindPoint(concepts) {
         this.bindPointModal = true;
         this.bindPointModal = true;
-        this.getStandardList();
+        this.checkedPointList = concepts;
+        this.knowPointList = this.schoolPointList;
+        console.log(concepts);
       },
       },
 
 
       //获取标准知识块数据
       //获取标准知识块数据
@@ -236,7 +435,27 @@ import { setTimeout } from 'core-js';
         }
         }
         this.$api.FindKnowledgeBlockAndPointByDict(data).then(res => {
         this.$api.FindKnowledgeBlockAndPointByDict(data).then(res => {
           let list = res.result.data;
           let list = res.result.data;
-          this.knowPointList = list;
+          this.allPointList = list;
+        })
+      },
+
+       //获取学校知识块仓库数据
+      getSchoolPoints() {
+        let data = {
+          pointParams: {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+              SchoolCode: this.schoolInfo.claim[0].claimCode,
+              Status: 1
+           }
+        }
+        this.$api.FindSchoolBlockAndPointByDict(data).then(res => {
+          let list = res.result.data;
+          list.forEach(item => {
+            item.expand = !item.expand;
+          })
+          this.schoolPointList = list;
+          this.pointListLoading = false;
         })
         })
       },
       },
 
 
@@ -246,26 +465,16 @@ import { setTimeout } from 'core-js';
       },
       },
 
 
       //知识点绑定选中事件
       //知识点绑定选中事件
-      pointTreeCheck(val, data) {
-        //let list = this.checkedPointList;
-        //if (data.children.length == 0 && list.length < 5 && val.indexOf(data) > -1) {
-        //  list.push(data);
-        //} else if (list.length === 5) {
-        //  this.$Message.warning("最多绑定5个知识点!");
-        //} else if (val.indexOf(data) === -1 && list.indexOf(data) > -1) {
-        //  list.splice(list.indexOf(data), 1);
-        //}
-
-
-        let points = val.filter(item => item.children.length == 0);
-        if (points.length > 5) {
-          this.checkedPointList = points.slice(0, 5);
-          this.$Message.warning("最多绑定5个知识点!");
-        } else {
-          this.checkedPointList = points;
-        }
-        console.log(val, data);
-      },
+      //pointTreeCheck(val, data) {
+      //  let points = val.filter(item => item.children.length == 0);
+      //  if (points.length > 5) {
+      //    this.checkedPointList = points.slice(0, 5);
+      //    this.$Message.warning("最多绑定5个知识点!");
+      //  } else {
+      //    this.checkedPointList = points;
+      //  }
+      //  console.log(val, data);
+      //},
 
 
       //知识点树形结构渲染
       //知识点树形结构渲染
        renderContent(h, { root, node, data }) {
        renderContent(h, { root, node, data }) {
@@ -296,7 +505,7 @@ import { setTimeout } from 'core-js';
               h("span", data.name),
               h("span", data.name),
               h('span',{
               h('span',{
                 domProps: {
                 domProps: {
-                  className: this.checkedPointList.indexOf(data) > -1 ? "point-checked" : "point-unchecked"
+                  className: this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) > -1 ? "point-checkbox point-checked" : "point-checkbox point-unchecked"
                 },
                 },
                 style: {
                 style: {
                   display: data.children && data.children.length > 0
                   display: data.children && data.children.length > 0
@@ -305,15 +514,22 @@ import { setTimeout } from 'core-js';
                 },
                 },
                 on: {
                 on: {
                   click: () => {
                   click: () => {
-                    if (this.checkedPointList.indexOf(data) == -1) {
+                    let conceptData = {};
+                    if (this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) == -1) {
                       if (this.checkedPointList.length < 5) {
                       if (this.checkedPointList.length < 5) {
-                        this.checkedPointList.push(data);
+                        conceptData.origin = this.tabSelectVal;
+                        conceptData.knowledgeId = data.knowledgeId || data.rowKey;
+                        conceptData.name = data.name;
+                        conceptData.subjectCode = data.subjectCode;
+                        this.checkedPointList.push(conceptData);
                       } else {
                       } else {
                         this.$Message.warning("最多绑定5个知识点!");
                         this.$Message.warning("最多绑定5个知识点!");
                       }
                       }
                     } else {
                     } else {
-                      this.checkedPointList.splice(this.checkedPointList.indexOf(data), 1);
+                      this.checkedPointList.splice(this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey), 1);
                     }
                     }
+
+                    console.log(this.checkedPointList);
                   }
                   }
                 }
                 }
             })
             })
@@ -321,23 +537,85 @@ import { setTimeout } from 'core-js';
           ]
           ]
         );
         );
       },
       },
-       // 标题点击收缩展开
+      //标题点击收缩展开
       titleClick(root, node, data, event) {
       titleClick(root, node, data, event) {
         data.expand = !data.expand;
         data.expand = !data.expand;
       },
       },
 
 
+      //清空已选知识点
       handleClearChecked() {
       handleClearChecked() {
-        console.log(this.$refs.pointTree.getCheckedNodes());
-        //this.$refs.pointTree.getSelectedNodes() = [];
         this.checkedPointList = [];
         this.checkedPointList = [];
+      },
+
+      //删除指定知识点
+      deleteCheckedPoint(item) {
+        this.checkedPointList.splice(this.checkedPointList.indexOf(item), 1);
+      },
+
+      //知识点筛选功能
+      filterChange() {
+        this.knowPointList = !this.searchWord ? this.schoolPointList : this.schoolPointList.filter(item => item.name.toUpperCase().indexOf(this.searchWord.toUpperCase()) > -1)
+      },
+
+      //导入试题
+      uploadSuccess(response, file, fileList) {
+        let that = this;
+        this.importLoading = true;
+        if (response.error == null) {
+          let requestData = { htmlString: response.result.data.HtmlString }
+          this.$api.SaveAnalyzeHtml(requestData).then(res => {
+            if (res.error == null) {
+              setTimeout(function () {
+                that.$Message.success('文件上传解析成功!');
+                that.list = res.result.data;
+                that.importLoading = false;
+              },1000)
+              //this.saveItemBank(res.result.data);
+            }
+          });
+        } else {
+          this.$Message.error('对不起,文档解析失败!');
+        }
+      },
+
+      //保存试题到数据库
+      saveItemBank(list) {
+        this.$api.SaveItemBank(list).then(res => {
+          console.log(res);
+        })
+
       }
       }
 
 
     },
     },
     mounted() {
     mounted() {
-     
+        this.getStandardList();
+        this.getSchoolPoints();
+        //this.getAllPoints();
+    },
+    computed: {
+      headers(){
+        let hd = {}
+        hd["Authorization"] = "Bearer "+ localStorage.getItem("token");
+        return hd;
+      }
     }
     }
   }
   }
 </script>
 </script>
 <style scoped>
 <style scoped>
-  @import"../index/ExercisesList.css";
+@import "../index/ExercisesList.css";
 </style>
 </style>
+
+<!--<style src="../index/ExercisesList.css" scoped></style>-->
+<!--<style>
+    .content-wrap .exercise-item p {
+      margin:10px 0;
+      display:inline-block;
+      word-break:break-all;
+    }
+
+    .complete-line {
+      margin:0 5px;
+      padding: 0 45px;
+      border-bottom: 2px solid rgb(128, 128, 128);
+    }
+</style>-->

+ 336 - 0
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesListTree.vue

@@ -0,0 +1,336 @@
+<template>
+  <div class="ev-list-container">
+    <div class="ev-header">
+      <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
+      <span class="ev-title">我的题库</span>
+      <span class="ev-length">共 {{list.length}} 道题</span>
+    </div>
+    <!-- 筛选部分 -->
+    <div class="filter-wrap">
+      <div class="filter-item">
+        <span class="filter-title">题型:</span>
+        <RadioGroup v-model="filterType" type="button" @on-change="filterTypeChange">
+          <Radio label="all">全部</Radio>
+          <Radio label="single">单选</Radio>
+          <Radio label="multiple">多选</Radio>
+          <Radio label="judge">判断</Radio>
+          <Radio label="complete">填空</Radio>
+          <Radio label="subjective">问答</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">难度:</span>
+        <RadioGroup v-model="filterDiff" type="button" @on-change="filterDiffChange">
+          <Radio label="all">全部</Radio>
+          <Radio label="0">容易</Radio>
+          <Radio label="1">较易</Radio>
+          <Radio label="2">一般</Radio>
+          <Radio label="3">较难</Radio>
+          <Radio label="4">困难</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">排序:</span>
+        <RadioGroup v-model="filterSort" type="button" @on-change="filterSortChange">
+          <Radio label="0">新增时间<Icon type="md-arrow-round-down" /></Radio>
+          <Radio label="1">使用次数<Icon type="md-arrow-round-down" /></Radio>
+        </RadioGroup>
+      </div>
+    </div>
+    <!-- 题目列表部分 -->
+    <div v-if="list.length == 0">暂无数据</div>
+    <div class="content-wrap" v-else>
+      <div class="exercise-item" v-for="(item,index) of list">
+        <span class="item-difficulty" :style="{backgroundColor:diffColors[item.difficulty]}">{{exersicesDiff[item.difficulty]}}</span>
+        <span class="item-type">{{exersicesType[item.type]}}</span>
+        <div class="item-question">
+          <p>{{index+1}} : <span v-html="item.question"></span></p>
+        </div>
+        <div v-for="(option,optionIndex) in item.options">
+          <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
+        </div>
+        <div class="item-answer">
+          <span class="answer-title-line"></span>
+          <span class="answer-title" @click="showAnswer($event,'answer')">答案:点击展开答案详情</span>
+          <div class="item-answer-details">
+            <span v-html="item.answer" v-if="item.type == 'subjective'"></span>
+            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'complete'" v-html="answer"></span>
+            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
+
+          </div>
+        </div>
+        <div class="item-explain">
+          <span class="explain-title-line"></span>
+          <span class="explain-title" @click="showAnswer($event,'explain')">解析:点击展开解析详情</span>
+          <div class="item-explain-details">
+            <span v-html="item.explain"></span>
+          </div>
+        </div>
+        <div class="item-tools">
+          <Button type="primary" @click="handleEdit(item)">编辑题目</Button>
+          <Button type="info">选题</Button>
+          <span class="item-tools-bind">
+            <span class="item-tools-tool" @click="handleBindPoint"><Icon type="ios-link" />绑定知识点</span>
+            <span class="item-tools-tool"><Icon type="ios-link" />绑定科目</span>
+            <span class="item-tools-tool"><Icon type="ios-link" />绑定课纲</span>
+          </span>
+        </div>
+      </div>
+    </div>
+    <Page :total="totalNum"
+          show-sizer
+          @on-page-size-change="pageSizeChange"
+          @on-change="pageChange"
+          :page-size-opts="[5,10,15,20]" />
+    <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
+
+    <!-- 绑定知识点弹窗 Transfer -->
+    <Modal v-model="bindPointModal"
+           title="绑定知识点"
+           width="600"
+           class-name="transferModal"
+           @on-ok="handleTransferBlock"
+           @on-cancel="">
+      <Transfer :data="data3"
+                :target-keys="targetKeys"
+                :list-style="listStyle"
+                :render-format="renderTransfer"
+                :operations="['撤回知识库','绑定知识点']"
+                filter-placeholder="请输入搜索内容"
+                :titles="[transferStatus?'校本知识点':'标准知识点', '已选知识点']"
+                not-found-text="列表为空"
+                filterable
+                :filter-method="filterMethod"
+                @on-change="handleChangeTransfer">
+        <div :style="{float: 'right', margin: '5px'}">
+          <Button size="small" type="primary" @click="changePointData(!transferStatus)" class="transferBtn">{{ transferStatus ? '从标准库添加': "从私有库添加"}}</Button>
+          <Button size="small" @click="reloadPointData(transferStatus)">刷新</Button>
+        </div>
+      </Transfer>
+    </Modal>
+  </div>
+</template>
+<script>
+  import IconText from '@/components/evaluation/IconText.vue'
+  import questions from './list.json'
+import { setTimeout } from 'core-js';
+  export default {
+    components: {
+      IconText
+    },
+    data() {
+      return {
+        list: [],
+        schoolInfo: {},
+        bindPointModal: false,
+        exersicesType: {
+          single: "单选",
+          multiple: "多选",
+          judge: "判断",
+          complete: "填空",
+          subjective:"问答"
+        },
+        exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
+        diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
+        filterType:"all",
+        filterDiff:"all",
+        filterSort: "0",
+        pageSize: 5,
+        pageNum: 1,
+        totalNum: 100,
+        allList: questions.list,
+        knowPointList: [],
+        checkedPointList: [],
+        data3: [],
+        allPointList: [],
+        schoolAllPoint:[],
+        targetKeys: [],
+        targetList:[],
+        listStyle: {
+          width: '220px',
+          height: '420px'
+        },
+        transferStatus:true,
+      }
+    },
+    created() {
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
+      this.list = questions.list;
+      this.totalNum = questions.list.length;
+      if (this.$route.params.exerciseItem) {
+        this.list.unshift(this.$route.params.exerciseItem);
+      }
+      //获取学校与标准的知识点源
+        this.getSchoolPoints();
+        this.getAllPoints();
+    },
+    methods: {
+      //获取标准知识点仓库数据
+      getAllPoints() {
+         let data = {
+          pointParams: {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+            }
+        }
+        this.$api.FindKnowledgePointByDict(data).then(res => {
+          this.allPointList = res.result.data;
+        })
+      },
+
+      //获取学校知识点仓库数据
+      getSchoolPoints() {
+         let data = {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+              SchoolCode: this.schoolInfo.claim[0].claimCode,
+              Status:1
+        }
+        this.$api.FindSchoolPointByDict(data).then(res => {
+          this.schoolAllPoint = res.result.data;
+        })
+      },
+
+      //筛选题型
+      filterTypeChange(val) {
+        if (val == "all") {
+          this.list = questions.list;
+        } else {
+          this.list = questions.list.filter(item => item.type == val);
+        }
+      },
+
+      //筛选难度
+      filterDiffChange(val) {
+         if (val == "all") {
+          this.list = questions.list;
+         } else {
+           this.list = questions.list.filter(item => item.difficulty == val);
+        }
+      },
+
+      //排序条件更换
+      filterSortChange(val) {
+        console.log(val);
+      },
+
+      //展开与收起答案
+      showAnswer(e, type) {
+        let el = e.currentTarget;
+        let isShow = e.currentTarget.nextElementSibling.style.display||"none";
+        setTimeout(function () {
+          if (type == "explain") {
+            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
+            el.innerHTML = isShow == "none" ? "解析:点击收起解析详情" : "解析:点击展开解析详情";
+          } else {
+            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
+            el.innerHTML = isShow == "none" ? "答案:点击收起答案详情" : "答案:点击展开答案详情";
+          }
+
+        },100)
+      },
+
+      //返回新建习题
+      backToAdd() {
+        this.$router.push({
+            path: '/createExercises',//或者路径跳转path: '/addCreditCards',
+          })
+      },
+
+      //切换页码
+      pageChange(page) {
+        let start = this.pageSize * (page - 1);
+        let end = this.pageSize * page;
+        let list = questions.list;
+        this.list = list.slice(start, end);
+        window.scroll(0, 0);
+      },
+
+      //切换分页Size
+      pageSizeChange(val) {
+        this.pageSize = val;
+        this.pageChange(1);
+      },
+
+      //编辑习题
+      handleEdit(item) {
+        this.$router.push({
+            name: 'createExercises',
+            params:{
+              item: item,
+            }
+          })
+      },
+
+      //绑定知识点操作
+      handleBindPoint() {
+        this.data3 = this.getPointList(this.transferStatus);
+        this.targetKeys = [];
+        this.bindPointModal = true;
+
+      },
+
+     //获取transfer的知识点数据源
+      getPointList(status) {
+        let mockData = [];
+        let list = status ? this.schoolAllPoint : this.allPointList;
+        for (let i = 0; i < list.length; i++) {
+          mockData.push({
+            id: i,
+            key: i.toString(),
+            label: i.toString(),
+            name: list[i].name,
+            termNum: i + 5,
+            blockId: i + 1,
+            description: list[i].name
+          });
+        }
+        return mockData;
+      },
+
+      //transfer 处理
+      handleChangeTransfer(newTargetKeys) {
+        this.targetKeys = newTargetKeys;
+        let targetList = [];
+        let list = this.transferStatus ? this.schoolAllPoint : this.allPointList;
+        newTargetKeys.forEach(item => {
+          targetList.push(list[item]);
+        })
+        this.targetList = targetList;
+      },
+
+      ////transfer 处理
+      renderTransfer(item) {
+        return item.name;
+      },
+      //重置数据
+      reloadPointData(status) {
+        this.data3 = this.getPointList(status);
+        this.targetKeys = [];
+      },
+      //切换数据源
+      changePointData(status) {
+        this.data3 = this.getPointList(status);
+        this.transferStatus = status;
+      },
+      //transfer Input 筛选数据
+      filterMethod(data, query) {
+        let val = data.name;
+        return val.toUpperCase().indexOf(query.toUpperCase()) > -1;
+      },
+
+
+      //确认编辑知识块
+      handleTransferBlock() {
+        console.log(this.targetList);
+      },
+
+    },
+    mounted() {
+     
+    }
+  }
+</script>
+<style scoped>
+  @import"../index/ExercisesList.css";
+</style>

+ 136 - 13
TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.css

@@ -1,9 +1,32 @@
 .ev-body {
 .ev-body {
     width:65% !important;
     width:65% !important;
 }
 }
+
+
 .paper-container {
 .paper-container {
     user-select: none !important;
     user-select: none !important;
 }
 }
+
+    .paper-container .ev-header {
+        background: #fff;
+        padding: 10px;
+    }
+
+    .paper-container .ev-title {
+        font-size: 20px;
+        font-weight: bold;
+        margin-left: 5px;
+        vertical-align: middle;
+    }
+
+    .paper-container .ev-length {
+        font-size: 12px;
+        font-weight: bold;
+        margin-left: 30px;
+        display: inline-block;
+        margin-top: 5px;
+        vertical-align: text-top;
+    }
     .paper-container .paper-header {
     .paper-container .paper-header {
         background: #fff;
         background: #fff;
     }
     }
@@ -25,7 +48,11 @@
 
 
     .paper-container .paper-toolbar {
     .paper-container .paper-toolbar {
         background: #fff;
         background: #fff;
-        height:100px;
+        padding:20px;
+    }
+
+    .paper-container .paper-toolbar .filter-title {
+        font-size:14px;
     }
     }
 
 
 .paper-content {
 .paper-content {
@@ -41,30 +68,125 @@
        padding-left:50px;
        padding-left:50px;
     }
     }
 
 
-    .paper-content .exercise-item {
-        font-size:14px !important;
-        margin-top:0 !important;
-        padding:5px 10px !important;
-        box-sizing:border-box;
+    .paper-content .paper-part {
+        padding: 15px;
     }
     }
 
 
-    .paper-content .paper-content-section {
-        font-size:18px;
-        font-weight:bold;
-        margin-top:20px;
+        /*.paper-content .paper-part:hover {
+            background: #bfcdad45;
+        }*/
+
+    .paper-content .exercise-item {
+        position: relative;
+        font-size: 14px !important;
+        margin-top: 0 !important;
+        padding: 5px 10px !important;
+        box-sizing: border-box;
+        background: transparent;
+        border: 1px solid rgba(1,1,1,0);
     }
     }
 
 
+        .paper-content .exercise-item .item-tools {
+            position: absolute;
+            right: -2px;
+            top: -30px;
+            width:419px;
+            height: 30px;
+            margin:0;
+            padding:0;
+            background: #01b4ef;
+            display:none;
+        }
+
+            .paper-content .exercise-item .item-tools-t {
+                height: 100%;
+                padding: 0 15px;
+                float: left;
+                color: white;
+                cursor: pointer;
+            }
+
+                .paper-content .exercise-item .item-tools-t:hover {
+                    background: #4a5ae6;
+                }
+
+        .paper-content .exercise-item .item-tools-t .ivu-icon{
+            color:white;
+            font-size:14px;
+            margin:0 3px;
+        }
+
+        .paper-content .paper-content-section {
+             font-size: 18px;
+            font-weight: bold;
+            margin-top: 20px;
+        }
+
     .paper-content .paper-content-section span {
     .paper-content .paper-content-section span {
-        font-size:16px;
+        font-size:14px;
         font-weight:500;
         font-weight:500;
         margin-left:10px;
         margin-left:10px;
     }
     }
 
 
-    .paper-content .content-wrap .exercise-item:hover {
+    .paper-content  .exercise-item:hover {
         box-shadow: none !important;
         box-shadow: none !important;
-        border: 1px solid #d2d2d2;
+        border-color:#cfcfcf;
+
+    }
+
+    .paper-content .item-answer, .paper-content .item-explain {
+        text-indent:-8px;
+        line-height:26px;
+    }
+
+
+.paper-footer {
+    width:100%;
+    height:120px;
+    background:#fff;
+    margin-top:10px;
+    padding:20px 130px;
+}
+
+
+.paper-tools {
+    width: 100%;
+    height: 60px;
+    margin-top: 10px;
+    border-top: 1px dashed #cfcfcf;
+    padding:10px;
+}
+
+    .paper-tools .ivu-checkbox-wrapper {
+        font-size: 14px;
+    }
+
+    .paper-tools .ivu-checkbox {
+        margin:6px;
+    }
+    .paper-tools .ivu-checkbox-checked .ivu-checkbox-inner {
+        background: #01b4ef;
+        border-color: #01b4ef;
     }
     }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*横向垂直水平居中*/
 .flex-row-center {
 .flex-row-center {
     display: flex;
     display: flex;
     flex-direction: row;
     flex-direction: row;
@@ -72,6 +194,7 @@
     align-items: center;
     align-items: center;
 }
 }
 
 
+/*向垂直水平居中*/
 .flex-col-center {
 .flex-col-center {
     display: flex;
     display: flex;
     flex-direction: column;
     flex-direction: column;

+ 179 - 31
TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.vue

@@ -1,18 +1,59 @@
 <template>
 <template>
   <div class="paper-container">
   <div class="paper-container">
+    <div class="ev-header">
+      <Icon type="md-paper" size="30" color="rgb(16, 171, 231)" />
+      <span class="ev-title" @click="backToAdd">测试组卷</span>
+      <span class="ev-length">共 {{paperInfo.ItemId.length}} 道题</span>
+    </div>
     <!-- 试卷编辑工具栏 -->
     <!-- 试卷编辑工具栏 -->
-    <div class="paper-toolbar">
-
+    <div class="paper-toolbar filter-wrap">
 
 
+      <!--<div class="filter-item">
+        <span class="filter-title">测试用途:</span>
+        <RadioGroup v-model="testAttr.testType" type="button" @on-change="filterTypeChange">
+          <Radio label="0">正式考试</Radio>
+          <Radio label="1">普通测试</Radio>
+          <Radio label="2">统计</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">测试情景:</span>
+        <RadioGroup v-model="testAttr.testScene" type="button" @on-change="filterSceneChange">
+          <Radio label="0">模拟</Radio>
+          <Radio label="1">段考</Radio>
+          <Radio label="2">周考</Radio>
+          <Radio label="3">小考</Radio>
+          <Radio label="4">自定义</Radio>
+        </RadioGroup>
+      </div>-->
+      <!--<div class="filter-item">
+        <span class="filter-title">测试对象:</span>
+        <RadioGroup v-model="testAttr.testTarget" type="button" @on-change="filterTargetChange">
+          <Radio label="0">同年级</Radio>
+          <Radio label="1">跨年级</Radio>
+          <Radio label="2">跨学校</Radio>
+        </RadioGroup>
+      </div>-->
+      <!--<div class="filter-item">
+        <span class="filter-title">创建方式:</span>
+        <RadioGroup v-model="testAttr.createType" type="button" @on-change="filterCreateChange">
+          <Radio label="0">自动组题</Radio>
+          <Radio label="1">批量导入</Radio>
+          <Radio label="2">题库挑选</Radio>
+        </RadioGroup>
+      </div>-->
+      <div class="paper-tools">
+        <Checkbox v-model="isShowAnswer" @on-change="changeShowAnswer">展示答案与解析</Checkbox>
+      </div>
     </div>
     </div>
 
 
     <!-- 试卷内容 -->
     <!-- 试卷内容 -->
     <div class="paper-content">
     <div class="paper-content">
-      <div class="paper-line">
+      <!--<div class="paper-line">
         <div id="pui_seal" title="点击设置&quot;装订线&quot;" style="display: block;">
         <div id="pui_seal" title="点击设置&quot;装订线&quot;" style="display: block;">
-        <img alt="装订线" title="装订线" src="http://zujuan.xkw.com/resource/image/v2/peal_line.png" width="58" height="">
+          <img alt="装订线" title="装订线" src="http://zujuan.xkw.com/resource/image/v2/peal_line.png" width="58" height="">
         </div>
         </div>
-      </div>
+      </div>-->
       <div class="paper-body">
       <div class="paper-body">
         <!-- 试卷头部信息 -->
         <!-- 试卷头部信息 -->
         <div class="paper-header flex-col-center">
         <div class="paper-header flex-col-center">
@@ -25,21 +66,65 @@
           <div class="paper-content-section">{{numberConvertToUppercase(order)+'、'+item.name}}<span>(共6题,每题5分,共30分)</span></div>
           <div class="paper-content-section">{{numberConvertToUppercase(order)+'、'+item.name}}<span>(共6题,每题5分,共30分)</span></div>
           <div v-if="list.length == 0">暂无数据</div>
           <div v-if="list.length == 0">暂无数据</div>
           <div class="content-wrap" v-else>
           <div class="content-wrap" v-else>
-            <div class="exercise-item" v-for="(question,index) of item.questions">
+            <div class="exercise-item" v-for="(question,index) of item.questions" @mouseenter="exerciseMouseover($event)" @mouseleave="exerciseMouseleave($event)">
+              <div class="item-tools">
+                <div class="item-tools-t flex-row-center"><Icon type="ios-list-box-outline" />试题挑错</div>
+                <div class="item-tools-t flex-row-center"><Icon type="ios-brush-outline" />编辑</div>
+                <div class="item-tools-t flex-row-center"><Icon type="ios-archive-outline" />删除</div>
+                <div class="item-tools-t flex-row-center"><Icon type="md-arrow-up" />上移</div>
+                <div class="item-tools-t flex-row-center"><Icon type="md-arrow-down" />下移</div>
+              </div>
               <div class="item-question">
               <div class="item-question">
                 <p>{{index+1}} : <span v-html="question.question"></span></p>
                 <p>{{index+1}} : <span v-html="question.question"></span></p>
               </div>
               </div>
-              <div v-for="(option,optionIndex) in question.options">
+              <div v-for="(option,optionIndex) in question.option">
                 <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
                 <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
               </div>
               </div>
+
+              <!-- 如果是组合题 -->
+              <div v-for="(childQuestion,childIndex) in question.children" v-if="question.children.length">
+                <div class="item-question">
+                  <p>{{childIndex+1}} : <span v-html="childQuestion.question"></span></p>
+                </div>
+                <div v-for="(childOption,childOptionIndex) in childQuestion.option">
+                  <p>{{String.fromCharCode(64 + parseInt(childOptionIndex+1))}} : <span v-html="childOption.value"></span></p>
+                </div>
+                <div class="item-answer" v-show="isShowAnswer">
+                  <span style="color:#01b4ef">【答案】:</span>
+                  <span v-html="childQuestion.answer[0] || childQuestion.answer" v-if="childQuestion.type == 'Subjective'"></span>
+                  <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else-if="childQuestion.type == 'Complete'" v-html="answer"></span>
+                  <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else>{{answer}}</span>
+                </div>
+                <div class="item-explain" v-show="isShowAnswer">
+                  <span style="color:#01b4ef">【解析】:</span>
+                  <span v-html="childQuestion.explain"></span>
+                </div>
+              </div>
+
+
+              <!-- 答案与解析部分选择是否展示 -->
+              <div class="item-answer" v-show="isShowAnswer && question.type != 'Compose'">
+                <span style="color:#01b4ef">【答案】:</span>
+                <span v-html="question.answer[0] || question.answer" v-if="question.type == 'Subjective'"></span>
+                <span :class="[ question.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in question.answer" v-else-if="question.type == 'Complete'" v-html="answer"></span>
+                <span :class="[ question.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in question.answer" v-else>{{answer}}</span>
+              </div>
+              <div class="item-explain" v-show="isShowAnswer && question.type != 'Compose'">
+                <span style="color:#01b4ef">【解析】:</span>
+                <span v-html="question.explain"></span>
+              </div>
             </div>
             </div>
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
+    <div class="paper-footer">
+      <Button type="primary">保存试卷</Button>
+    </div>
   </div>
   </div>
 </template>
 </template>
 <script>
 <script>
+  
   import questions from './list.json'
   import questions from './list.json'
   import paper from './paper.json'
   import paper from './paper.json'
   export default {
   export default {
@@ -52,53 +137,70 @@
           multiple: "多选",
           multiple: "多选",
           judge: "判断",
           judge: "判断",
           complete: "填空",
           complete: "填空",
-          subjective:"问答"
+          subjective: "问答"
+        },
+        testAttr: {
+          testScene: '0',
+          testType: '0',
+          testTarget: '0',
+          testMode: '0',
+          createType: '0',
+          questionFilter: []
         },
         },
         exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
         exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
         diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
         diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
-        filterType:"0",
-        filterDiff:"0",
+        filterType: "0",
+        filterDiff: "0",
         filterSort: "0",
         filterSort: "0",
         pageSize: 5,
         pageSize: 5,
         pageNum: 1,
         pageNum: 1,
         totalNum: 100,
         totalNum: 100,
-        allList: questions.list
+        allList: questions.result.data,
+        isShowAnswer: false
       }
       }
     },
     },
     created() {
     created() {
-      this.list = questions.list;
+      this.list = questions.result.data;
       this.paperInfo = paper;
       this.paperInfo = paper;
+      let flag = this.$route.params.flag;
+      if (flag == 1) {
+        console.log(JSON.parse(localStorage.getItem('questions')));
+        this.paperInfo.parts[0].questions = JSON.parse(localStorage.getItem('questions'))
+      }
 
 
     },
     },
     methods: {
     methods: {
+
+      //返回创建评测页面
       backToAdd() {
       backToAdd() {
         this.$router.push({
         this.$router.push({
-            path: '/createExercises',//或者路径跳转path: '/addCreditCards',
-          })
+          path: '/testPaperList',//或者路径跳转path: '/addCreditCards',
+        })
       },
       },
 
 
+      //数字与中文转换
       numberConvertToUppercase(num) {
       numberConvertToUppercase(num) {
-          num = Number(num+1);
-          var upperCaseNumber = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '百', '千', '万', '亿'];
-          var length = String(num).length;
-          if (length == 1) {
+        num = Number(num + 1);
+        var upperCaseNumber = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '百', '千', '万', '亿'];
+        var length = String(num).length;
+        if (length == 1) {
+          return upperCaseNumber[num];
+        } else if (length == 2) {
+          if (num == 10) {
             return upperCaseNumber[num];
             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('零', '');
-            }
+          } 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) {
       pageChange(page) {
         let start = this.pageSize * (page - 1);
         let start = this.pageSize * (page - 1);
         let end = this.pageSize * page;
         let end = this.pageSize * page;
-        let list = questions.list;
+        let list = questions.result.data;
         this.list = list.slice(start, end);
         this.list = list.slice(start, end);
         window.scroll(0, 0);
         window.scroll(0, 0);
       },
       },
@@ -107,16 +209,62 @@
       pageSizeChange(val) {
       pageSizeChange(val) {
         this.pageSize = val;
         this.pageSize = val;
         this.pageChange(1);
         this.pageChange(1);
+      },
+
+      //题目鼠标滑过事件
+      exerciseMouseover(e) {
+        e.preventDefault();
+        e.target.children[0].style.display = "block";
+      },
+
+      //题目鼠标移出事件
+      exerciseMouseleave(e) {
+        e.preventDefault();
+        e.target.children[0].style.display = "none";
+      },
+
+      //测试用途
+      filterTypeChange(val) {
+
+      },
+
+      //测试情景
+      filterSceneChange(val) {
+
+      },
+
+      //测试对象
+      filterTargetChange(val) {
+
+      },
+
+      //创建方式
+      filterCreateChange(val) {
+
+      },
+
+      changeShowAnswer(val) {
+        console.log(this.isShowAnswer);
       }
       }
 
 
     },
     },
     mounted() {
     mounted() {
-     
+
     }
     }
   }
   }
 </script>
 </script>
-<style scoped>
-  @import"../index/ExercisesList.css";
-  @import"../index/TestPaper.css";
+<style src="../index/ExercisesList.css" scoped></style>
+<style src="../index/TestPaper.css" scoped></style>
+<style>
+
+  .content-wrap .exercise-item p {
+    margin: 10px 0;
+    display: inherit;
+    word-break: break-all;
+  }
 
 
+  .complete-line {
+    padding: 0 45px;
+    border-bottom: 2px solid rgb(128, 128, 128);
+  }
 </style>
 </style>

+ 174 - 0
TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.css

@@ -0,0 +1,174 @@
+.ev-list-container {
+    user-select:none !important;
+}
+    .ev-list-container .ev-header {
+        background:#fff;
+        padding:10px;
+    }
+    .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;
+    }
+
+.ev-content {
+    background:none;
+}
+.content-wrap {
+    width: 100%;
+    height: auto;
+    display: flex;
+    flex-direction: column;
+    margin-top: 10px;
+    background: #fff;
+}
+
+    .content-wrap .exercise-item {
+        width: 100%;
+        height: 60px;
+        padding: 60px 30px;
+        font-size: 14px;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        border-bottom: 1px solid rgba(230, 230, 230, 0.67);
+        cursor:pointer;
+    }
+
+        .content-wrap .exercise-item .icon-paper {
+            width: 50px;
+            height:50px;
+        }
+
+.exercise-item .paper-content {
+    width: 70%;
+    padding-left: 20px;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+}
+
+    .exercise-item .paper-content .paper-title {
+        font-size:18px;
+        font-weight:bold;
+    }
+
+    .exercise-item .paper-content .paper-info {
+        font-size: 12px;
+        margin-top: 10px;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+    }
+
+        .exercise-item .paper-content .paper-info span {
+            margin-left: 25px;
+            color: rgb(144, 144, 144);
+            display:flex;
+            flex-direction:row;
+            justify-content:center;
+            align-items:center;
+        }
+
+        .exercise-item .paper-content .paper-info .ivu-icon {
+            font-size:16px;
+            margin-right:5px;
+        }
+
+
+.exercise-item .paper-operation .ivu-icon {
+    /*font-size:16px;*/
+}
+
+
+.complete-line {
+    margin-left: 5px;
+    padding: 0 45px;
+    border-bottom: 2px solid rgb(128, 128, 128);
+}
+
+.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:14px;
+          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;
+    }
+
+
+.ev-list-container .ivu-page {
+    display:flex;
+    flex-direction:row;
+    justify-content:center;
+    margin:20px 0;
+}
+
+
+

+ 383 - 0
TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.vue

@@ -0,0 +1,383 @@
+<template>
+  <div class="ev-list-container">
+    <div class="ev-header">
+      <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
+      <span class="ev-title">我的评测</span>
+      <span class="ev-length">共 {{list.length}} 道题</span>
+    </div>
+    <!-- 筛选部分 -->
+    <div class="filter-wrap">
+      <div class="filter-item">
+        <span class="filter-title">测试用途:</span>
+        <RadioGroup v-model="testAttr.testType" type="button" @on-change="filterTypeChange">
+          <Radio label="0">正式考试</Radio>
+          <Radio label="1">普通测试</Radio>
+          <Radio label="2">统计</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">测试情景:</span>
+        <RadioGroup v-model="testAttr.testScene" type="button" @on-change="filterSceneChange">
+          <Radio label="0">模拟</Radio>
+          <Radio label="1">段考</Radio>
+          <Radio label="2">周考</Radio>
+          <Radio label="3">小考</Radio>
+          <Radio label="4">自定义</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">测试对象:</span>
+        <RadioGroup v-model="testAttr.testTarget" type="button" @on-change="filterTargetChange">
+          <Radio label="0">同年级</Radio>
+          <Radio label="1">跨年级</Radio>
+          <Radio label="2">跨学校</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">创建方式:</span>
+        <RadioGroup v-model="testAttr.createType" type="button" @on-change="filterCreateChange">
+          <Radio label="0">自动组题</Radio>
+          <Radio label="1">批量导入</Radio>
+          <Radio label="2">题库挑选</Radio>
+        </RadioGroup>
+      </div>
+      <div class="filter-item">
+        <span class="filter-title">排序方式:</span>
+        <RadioGroup v-model="filterSort" type="button" @on-change="filterSortChange">
+          <Radio label="0">新增时间<Icon type="md-arrow-round-down" /></Radio>
+          <Radio label="1">使用次数<Icon type="md-arrow-round-down" /></Radio>
+        </RadioGroup>
+      </div>
+    </div>
+    <!-- 题目列表部分 -->
+    <div v-if="list.length == 0">暂无数据</div>
+    <div class="content-wrap" v-else>
+      <div class="exercise-item" v-for="(item,index) of list">
+        <img class="icon-paper" src="../../../assets/icon/icon_paper.png" />
+        <div class="paper-content">
+          <p class="paper-title" v-html="item.type"></p>
+          <p class="paper-info">
+            <span style="margin-left:0"><Icon type="md-clock" />修改时间:2019-06-26</span>
+            <span><Icon type="md-eye" />使用次数:8</span>
+            <span><Icon type="md-document" />类型:期末考试</span>
+          </p>
+        </div>
+        <div class="paper-operation">
+          <Button type="primary" icon="ios-download-outline">推送</Button>
+          <Button type="success" icon="ios-download-outline">下载</Button>
+        </div>
+      </div>
+
+    </div>
+    <Page :total="totalNum"
+          show-sizer
+          @on-page-size-change="pageSizeChange"
+          @on-change="pageChange"
+          :page-size-opts="[5,10,15,20]" />
+    <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
+    <Button type="success" @click="backToPaper" style="margin:10px;">试卷</Button>
+
+  </div>
+</template>
+<script>
+  import IconText from '@/components/evaluation/IconText.vue'
+  import questions from './list.json'
+import { setTimeout } from 'core-js';
+  export default {
+    components: {
+      IconText
+    },
+    data() {
+      return {
+        list: [],
+        searchWord: '',
+        pointListLoading:true,
+        schoolInfo: {},
+        bindPointModal: false,
+        exersicesType: {
+          single: "单选",
+          multiple: "多选",
+          judge: "判断",
+          complete: "填空",
+          subjective:"问答"
+        },
+        exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
+        diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
+        testAttr: {
+          testScene: '0',
+          testType: '0',
+          testTarget: '0',
+          testMode: '0',
+          createType: '0',
+          questionFilter:[]
+        }, 
+        filterSort: "0",
+        pageSize: 5,
+        pageNum: 1,
+        totalNum: 100,
+        allList: questions.result.data,
+        knowPointList: [],
+        schoolPointList: [],
+        allPointList:[],
+        checkedPointList: []
+      }
+    },
+    created() {
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
+      this.list = questions.result.data;
+      this.totalNum = questions.result.data.length;
+      if (this.$route.params.exerciseItem) {
+        this.list.unshift(this.$route.params.exerciseItem);
+      }
+    },
+    methods: {
+
+      //筛选题型
+      filterTypeChange(val) {
+        if (val == "all") {
+          this.list = questions.result.data;
+        } else {
+          this.list = questions.result.data.filter(item => item.type == val);
+        }
+      },
+
+      //筛选难度
+      filterDiffChange(val) {
+         if (val == "all") {
+          this.list = questions.result.data;
+         } else {
+           this.list = questions.result.data.filter(item => item.difficulty == val);
+        }
+      },
+
+      //排序条件更换
+      filterSortChange(val) {
+        console.log(val);
+      },
+
+      //展开与收起答案
+      showAnswer(e, type) {
+        let el = e.currentTarget;
+        let isShow = e.currentTarget.nextElementSibling.style.display||"none";
+        setTimeout(function () {
+          if (type == "explain") {
+            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
+            el.innerHTML = isShow == "none" ? "解析:点击收起解析详情" : "解析:点击展开解析详情";
+          } else {
+            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
+            el.innerHTML = isShow == "none" ? "答案:点击收起答案详情" : "答案:点击展开答案详情";
+          }
+
+        },100)
+      },
+
+      backToAdd() {
+        this.$router.push({
+            path: '/createExercises',//或者路径跳转path: '/addCreditCards',
+          })
+      },
+
+      backToPaper() {
+        this.$router.push({
+            path: '/testPaper',//或者路径跳转path: '/addCreditCards',
+          })
+      },
+
+      //切换页码
+      pageChange(page) {
+        let start = this.pageSize * (page - 1);
+        let end = this.pageSize * page;
+        let list = questions.result.data;
+        this.list = list.slice(start, end);
+        window.scroll(0, 0);
+      },
+
+      //切换分页Size
+      pageSizeChange(val) {
+        this.pageSize = val;
+        this.pageChange(1);
+      },
+
+      //编辑习题
+      handleEdit(item) {
+        this.$router.push({
+            name: 'createExercises',
+            params:{
+              item: item,
+            }
+          })
+      },
+
+      //绑定知识点操作
+      handleBindPoint() {
+
+        this.bindPointModal = true;
+        this.checkedPointList = [];
+        this.knowPointList = this.schoolPointList;
+      },
+
+      //获取标准知识块数据
+      getStandardList() {
+        let data = {
+          periods: ["Period_21"],
+          pointParams: {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+            }
+        }
+        //this.$api.FindKnowledgeBlockAndPointByDict(data).then(res => {
+
+        //})
+      },
+
+      //获取标准知识点仓库数据
+      getAllPoints() {
+         let data = {
+          pointParams: {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+            }
+        }
+        this.$api.FindKnowledgePointByDict(data).then(res => {
+          let list = res.result.data;
+          this.allPointList = list;
+          this.pointListLoading = false;
+        })
+      },
+
+       //获取学校知识点仓库数据
+      getSchoolPoints() {
+         let data = {
+              SubjectCode: "Subject_Chinese",
+              PartitionKey: "zh-CN",
+              SchoolCode: this.schoolInfo.claim[0].claimCode,
+              Status:1
+        }
+        this.$api.FindSchoolPointByDict(data).then(res => {
+          let list = res.result.data;
+          this.schoolPointList = list;
+          this.pointListLoading = false;
+        })
+      },
+
+      //确认编辑知识块
+      handleTransferBlock() {
+        
+      },
+
+      //知识点绑定选中事件
+      pointTreeCheck(val, data) {
+        let points = val.filter(item => item.children.length == 0);
+        if (points.length > 5) {
+          this.checkedPointList = points.slice(0, 5);
+          this.$Message.warning("最多绑定5个知识点!");
+        } else {
+          this.checkedPointList = points;
+        }
+        console.log(val, data);
+      },
+
+      //知识点树形结构渲染
+       renderContent(h, { root, node, data }) {
+        return h(
+          "span",
+          {
+            domProps: {
+              className: "singleClass"
+            },
+            on: {
+              click: () => {
+                this.titleClick(root, node, data, event);
+              }
+            }
+          },[
+            h("span", [
+              h("Icon", {
+                props: {
+                  type:
+                    data.children && data.children.length > 0
+                      ? "md-albums"
+                      : "ios-paper-outline"
+                },
+                style: {
+                  marginRight: "5px",
+                }
+              }),
+              h("span", data.name),
+              h('span',{
+                domProps: {
+                  className: this.checkedPointList.indexOf(data) > -1 ? "point-checkbox point-checked" : "point-checkbox point-unchecked"
+                },
+                style: {
+                  display: data.children && data.children.length > 0
+                      ? "none"
+                    : "inline-block"
+                },
+                on: {
+                  click: () => {
+                    if (this.checkedPointList.indexOf(data) == -1) {
+                      if (this.checkedPointList.length < 5) {
+                        this.checkedPointList.push(data);
+                      } else {
+                        this.$Message.warning("最多绑定5个知识点!");
+                      }
+                    } else {
+                      this.checkedPointList.splice(this.checkedPointList.indexOf(data), 1);
+                    }
+                  }
+                }
+            })
+            ])
+          ]
+        );
+      },
+       // 标题点击收缩展开
+      titleClick(root, node, data, event) {
+        data.expand = !data.expand;
+      },
+
+      handleClearChecked() {
+        console.log(this.$refs.pointTree.getCheckedNodes());
+        //this.$refs.pointTree.getSelectedNodes() = [];
+        this.checkedPointList = [];
+      },
+
+      deleteCheckedPoint(item) {
+        this.checkedPointList.splice(this.checkedPointList.indexOf(item), 1);
+      },
+
+      //知识点筛选功能
+      filterChange() {
+        this.knowPointList = !this.searchWord ? this.schoolPointList : this.schoolPointList.filter(item => item.name.toUpperCase().indexOf(this.searchWord.toUpperCase()) > -1)
+      },
+
+      //测试用途
+      filterTypeChange(val) {
+
+      },
+
+      //测试情景
+      filterSceneChange(val) {
+
+      },
+
+      //测试对象
+      filterTargetChange(val) {
+
+      },
+
+      //创建方式
+      filterCreateChange(val) {
+          
+      },
+
+    },
+    mounted() {
+        //this.getStandardList();
+        this.getSchoolPoints();
+        //this.getAllPoints();
+    }
+  }
+</script>
+<style src="../index/TestPaperList.css" scoped>
+</style>

+ 268 - 13
TEAMModelOS/ClientApp/view/evaluation/index/index.vue

@@ -4,24 +4,59 @@
       <Header :parentToChild="syllabusTitle" :identityselect="identitydata"></Header>
       <Header :parentToChild="syllabusTitle" :identityselect="identitydata"></Header>
     </div>
     </div>
     <div class="ev-body">
     <div class="ev-body">
-      <div class="ev-slide"></div>
+      <div class="ev-slide">
+        <div class="ev-slide-school"><Icon type="ios-school" size="26" color="#10abe7" style="vertical-align:sub"/> {{schoolInfo.claimName}}</div>
+        <div class="ev-slide-header">选择学段及科目</div>
+        <div class="ev-slide-select">
+          <!-- 学段选择部分 -->
+          <Select v-model="evPeriodSelect" @on-change="periodChange" label-in-value>
+            <Option v-for="item in evPeriodsList" :value="item.code" :key="item.rowKey">{{ item.name }}</Option>
+          </Select>
+
+          <!-- 科目选择部分 -->
+          <Select v-model="evSubjectSelect" @on-change="subjectChange" label-in-value>
+            <Option v-for="item in evSubjectList" :value="item.code" :key="item.rowKey">{{ item.name }}</Option>
+          </Select>
+        </div>
+        <div class="ev-slide-header ev-slide-select-volumes" style="position:relative">
+          <Loading :top="150" :borderWidth="4" v-show="!isLoadingFinish"></Loading>
+          <!--<Loading v-show="!isLoadingFinish"></Loading>-->
+
+          <!-- 册别选择部分 -->
+          <Select v-model="evVolumeSelect" @on-change="volumeChange" label-in-value placeholder="请选择册别">
+            <Option v-for="item in evVolumesList" :value="item.rowKey" :key="item.rowKey">{{ item.gradeName + '' + item.termName }}</Option>
+          </Select>
+        </div>
+        <SyllabusTree :treeDatas="treeData"></SyllabusTree>
+      </div>
       <div class="ev-content">
       <div class="ev-content">
         <router-view />
         <router-view />
       </div>
       </div>
-    </div>    
+    </div>
+    <div class="slide-menu animated">
+      <ul>
+        <li @click="goRouter('createExercises')">创建习题</li>
+        <li @click="goRouter('exercisesList')">我的题库</li>
+        <li @click="goRouter('createTest')">创建评测</li>
+        <li @click="goRouter('testPaper')">编辑评测</li>
+        <li @click="goRouter('testPaperList')">我的评测</li>
+      </ul>
+      <!--<Icon type="md-list" />-->
+    </div>
   </div>
   </div>
+
 </template>
 </template>
 <script>
 <script>
   import Header from '@/common/headers.vue'
   import Header from '@/common/headers.vue'
-  import CreateExercises from '@/view/evaluation/index/CreateExercises.vue'
-  import ExercisesList from '@/view/evaluation/index/ExercisesList.vue'
-  import TestPaper from '@/view/evaluation/index/TestPaper.vue'
+  import SyllabusTree from '@/components/evaluation/SyllabusTree.vue'
+  import Loading from '@/common/Loading.vue'
+import { setTimeout } from 'core-js';
+
   export default {
   export default {
     components: {
     components: {
       Header,
       Header,
-      CreateExercises,
-      ExercisesList,
-      TestPaper
+      SyllabusTree,
+      Loading
     },
     },
     data() {
     data() {
       return {
       return {
@@ -30,8 +65,95 @@
           { "id": 1, "name": '成都紫藤小学', "rolename": '管理员', status: '1' },
           { "id": 1, "name": '成都紫藤小学', "rolename": '管理员', status: '1' },
           { "id": 2, "name": '成都七中小学', "rolename": '班主任', status: '2' }
           { "id": 2, "name": '成都七中小学', "rolename": '班主任', status: '2' }
         ],
         ],
+        treeData: [],
+        schoolInfo: {},
+        evSubjectList: [],
+        evPeriodsList: [],
+        evVolumesList: [],
+        evSubjectSelect:"",
+        evPeriodSelect: "",
+        evVolumeSelect:"",
+        isLoadingFinish:false
+      }
+    },
+    created() {
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0].claim[0]; //默认选中第一个学校
+      this.findSchoolPeriodsByDict();
+
+    },
+    methods: {
+      goRouter(name) {
+        this.$router.push({
+          name:name
+        })
+      },
+
+      //获取当前学校全部学段
+      findSchoolPeriodsByDict() {
+        this.$api.FindSchoolPeriodsByDict({SchoolCode: this.schoolInfo.claimCode}).then(res => {
+          this.evPeriodsList = res.result.data;
+          this.evPeriodSelect = res.result.data[0].code;
+          this.findSchoolSubjectsByDict();
+        })
+      },
+
+      //查找当前学校已有科目
+      findSchoolSubjectsByDict() {
+        this.$api.FindSchoolSubjectsByDict({ SchoolCode: this.schoolInfo.claimCode,Status:1 }).then(res => {
+          this.evSubjectList = res.result.data;
+          this.evSubjectSelect = res.result.data[0].code;
+          this.findVolumesBySubjectAndPeriod(this.evPeriodSelect, this.evSubjectSelect);
+        })
+      },
+
+      //根据当前选择的科目及学段获取所有册别
+      findVolumesBySubjectAndPeriod(periodCode,subjectCode) {
+        let defaultData = {
+          SchoolCode: this.schoolInfo.claimCode,
+          SubjectCode: subjectCode,
+          PeriodCode: periodCode,
+          Status:1
+        }
+        this.$api.FindSchoolVolumesByDict(defaultData).then(res => {
+          this.evVolumesList = res.result.data;
+          if (res.result.data.length) {
+            this.evVolumeSelect = res.result.data[0].rowKey;
+            this.findSyllabusByVolumeCode(res.result.data[0].rowKey);
+          } else {
+            this.evVolumeSelect = "";
+          }
+         })
+      },
+
+      //根据册别来获取课纲树形结构
+      findSyllabusByVolumeCode(volumeCode) {
+        this.isLoadingFinish = false;
+        this.$api.FindSyllabusByVolumeCode({ VolumeCode: volumeCode, Status: 1 }).then(res => {
+          let list = res.result.data;
+          list.forEach(item => { item.expand = false });
+          this.treeData = list;
+          this.isLoadingFinish = true;
+        })
+      },
+
+      //选择科目变化
+      subjectChange(val) {
+        this.findVolumesBySubjectAndPeriod(this.evPeriodSelect, val.value);
+      },
+
+      //选择学段变化
+      periodChange(val) {
+        this.findVolumesBySubjectAndPeriod(val.value, this.evSubjectSelect);
+      },
+
+      //选择册别变化
+      volumeChange(val) {
+        this.findSyllabusByVolumeCode(val.value);
       }
       }
+    },
+    mounted() {
     }
     }
+
   }
   }
 </script>
 </script>
 <style scoped>
 <style scoped>
@@ -39,9 +161,10 @@
     background:#eee;
     background:#eee;
     width:100%;
     width:100%;
     padding-bottom:50px;
     padding-bottom:50px;
+    position:relative;
   }
   }
   .ev-body {
   .ev-body {
-    width:95%;
+    width:65%;
     min-width:1200px;
     min-width:1200px;
     min-height:700px;
     min-height:700px;
     margin:auto;
     margin:auto;
@@ -53,12 +176,144 @@
   }
   }
     .ev-body .ev-slide {
     .ev-body .ev-slide {
       width:20%;
       width:20%;
-      height:1200px;
-      background:#e1e1e1;
+      height:auto;
+      padding:0;
+      background:#fff;
+      border-radius:5px 5px 0 0;
     }
     }
 
 
-    .ev-body .ev-content {
-       width:79%;
+    .ev-body .ev-slide .ev-slide-header{
+      width:104%;
+      height:45px;
+      background:#10abe7;
+      text-align:center;
+      line-height:45px;
+      color:white;
+      font-size:16px;
+      border-radius:5px;
+      margin:20px -5px;
+      box-shadow: 0px 1px 8px 5px #dedede;
     }
     }
 
 
+      .ev-body .ev-slide .ev-slide-select {
+        padding:0 10px;
+        /*background:#10abe7;*/
+      }
+
+      .ev-body .ev-slide .ev-slide-school {
+          height:40px;
+          line-height:40px;
+          text-align:center;
+          padding-top:10px;
+          font-size:14px;
+          font-weight:bold;
+          padding-right:5px;
+      }
+
+      .ev-slide /deep/ .ev-slide-select .ivu-select-selection {
+        margin-top:8px;
+        height:40px;
+      }
+
+      .ev-slide /deep/ .ev-slide-select .ivu-select-selected-value {
+        line-height:40px;
+      }
+
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-selection {
+          background:transparent;
+          border:none;
+          color:#fff;
+          width:140px;
+          margin:0 auto;
+          padding-right:10px;
+          font-size:14px;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-arrow {
+          color:#fff;
+      }
+
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-dropdown {
+          left:unset !important;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-placeholder {
+          color:#fff;
+          font-size:14px;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-selected-value {
+          color:#fff;
+          font-size:14px;
+      }
+
+  .ev-body .ev-content {
+      width:79%;
+  }
+
+
+  .slide-menu {
+    width:150px;
+    background:#bdbcbc;
+    position:fixed;
+    top:100px;
+    left:-140px;
+    border-radius: 0 10px 10px 0;
+  }
+
+    .slide-menu ul {
+      height:100%;
+      width:100%;
+      padding:20px 0;
+    }
+
+      .slide-menu ul li {
+        width:100%;
+        height:70px;
+        font-size:16px;
+        text-align:center;
+        line-height:70px;
+        color:#fff;
+        font-weight:bold;
+        cursor:pointer;
+        z-index: 1;
+        position: relative;
+        outline: none;
+        border: none;
+        overflow: hidden;
+         transition: color 0.4s ease-in-out;
+      }
+
+    .slide-menu .ivu-icon {
+      position:absolute;
+      top:170px;
+      right:-44px;
+      color:#477fd8;
+      font-size:44px;
+    }
+
+      .slide-menu ul li::before {
+          content: '';
+          z-index: -1;
+          position: absolute;
+          bottom: 100%;
+          right: 100%;
+          width: 1em;
+          height: 1em;
+          border-radius: 50%;
+          background:#2cbeff;
+          transform-origin: center;
+          transform: translate3d(50%, 50%, 0) scale3d(0, 0, 0);
+          transition: transform 0.45s ease-in-out;
+        }
+
+        .slide-menu:hover{
+          cursor: pointer;
+          transform:translate(140px, 0);
+          transition:1s  ease  0s;
+        }
+
+        .slide-menu ul li:hover::before {
+          transform: translate3d(120%, 50%, 0) scale3d(25, 15, 15);
+        }
+
+
+
 </style>
 </style>

文件差异内容过多而无法显示
+ 539 - 103
TEAMModelOS/ClientApp/view/evaluation/index/list.json


文件差异内容过多而无法显示
+ 301 - 101
TEAMModelOS/ClientApp/view/evaluation/index/paper.json


+ 9 - 1
TEAMModelOS/ClientApp/view/index.vue

@@ -19,6 +19,7 @@
         <Button type="primary" size="large" class="btn-login animated fadeIn" @click="handleLogin('regist')" v-show="!isLogin">{{$t('index.register')}}</Button>
         <Button type="primary" size="large" class="btn-login animated fadeIn" @click="handleLogin('regist')" v-show="!isLogin">{{$t('index.register')}}</Button>
         <!--<Button type="primary" size="large" class="btn-login animated fadeIn" @click="handleAuth()" v-show="!hasAuthSchool">去授权</Button>
         <!--<Button type="primary" size="large" class="btn-login animated fadeIn" @click="handleAuth()" v-show="!hasAuthSchool">去授权</Button>
         <p v-show="isLogin" class="suc-text">{{$t('index.authSchool')}}: {{schoolInfo.schoolName}}</p>-->
         <p v-show="isLogin" class="suc-text">{{$t('index.authSchool')}}: {{schoolInfo.schoolName}}</p>-->
+        <div class="system-name">醍摩豆智慧教育云平台</div>
         <div v-show="isLogin" class="suc-text select-role">
         <div v-show="isLogin" class="suc-text select-role">
           <span>{{$t("index.currentRole")}}:学校管理员</span>
           <span>{{$t("index.currentRole")}}:学校管理员</span>
           <!--<Select v-model="currentRole" style="width:200px" @on-change="handleRoleChange">
           <!--<Select v-model="currentRole" style="width:200px" @on-change="handleRoleChange">
@@ -251,8 +252,15 @@
     margin-top: 50px;
     margin-top: 50px;
   }
   }
 
 
+  .system-name {
+    font-size:45px;
+    font-weight:bold;
+    color:#fbfbfb;
+    /*text-shadow:-1px -5px 5px #bfbfbf;*/
+   }
+
   .logo {
   .logo {
-    width: 200px;
+    width: 200px; 
     height: 200px;
     height: 200px;
     margin-bottom: 50px;
     margin-bottom: 50px;
   }
   }

+ 1 - 0
TEAMModelOS/ClientApp/view/syllabus/index/Syllabus.vue

@@ -242,6 +242,7 @@ import { setTimeout } from 'core-js';
       },
       },
       //查找当前学校已有科目
       //查找当前学校已有科目
       findSchoolSubjectsByDict() {
       findSchoolSubjectsByDict() {
+        console.log(this.schoolInfo);
         this.$api.FindSchoolSubjectsByDict({ SchoolCode: this.schoolInfo.claimCode,Status:1 }).then(res => {
         this.$api.FindSchoolSubjectsByDict({ SchoolCode: this.schoolInfo.claimCode,Status:1 }).then(res => {
           this.currentSubjectList = res.result.data;
           this.currentSubjectList = res.result.data;
           if (res.result.data.length > 0) {
           if (res.result.data.length > 0) {

+ 113 - 0
TEAMModelOS/Controllers/Evaluation/EvaluationController.cs

@@ -0,0 +1,113 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelOS.Controllers.Core;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
+using TEAMModelOS.Model.Evaluation.Models;
+using TEAMModelOS.Model.EvaluaTion.Models;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.Service.Evaluation.Interfaces;
+using TEAMModelOS.Service.EvaluaTion.Interfaces;
+
+namespace TEAMModelOS.Controllers.Evaluation
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    ///[Authorize]
+    public class EvaluationController : BaseController
+    {
+        private readonly IEvaluatingService evaluatingService;
+        private readonly IItemBankService itemBankService;
+        private readonly IUseItemBankService useItemBankService;
+        private readonly ITestPaperService testPaperService;
+        public EvaluationController(IEvaluatingService _evaluatingService,
+            IItemBankService _itemBankService, ITestPaperService _testPaperService,
+            IUseItemBankService _useItemBankService) {
+            evaluatingService = _evaluatingService;
+            itemBankService = _itemBankService;
+            testPaperService = _testPaperService;
+            useItemBankService = _useItemBankService;
+        }
+        [HttpPost("evaluation")]
+        public async Task<BaseJosnRPCResponse> SaveOrUpdateEvaluation(JosnRPCRequest<Evaluating> request) {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            Evaluating evaluating = await evaluatingService.SaveOrUpdate<Evaluating>(request.@params);
+            return builder.Data(evaluating).build();
+        }
+
+        [HttpPost("itemBank")]
+        public async Task<BaseJosnRPCResponse> SaveOrUpdateItemBank(JosnRPCRequest<List<ItemBankDto>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+
+            List<ItemBankDto> itemBankDtos =  await itemBankService.SaveOrUpdateAsync(request.@params,request.lang);
+            return builder.Data(itemBankDtos).build();
+
+        }
+        [HttpPost("FindItemBank")]
+        public async Task<BaseJosnRPCResponse> FindItemBank(JosnRPCRequest<Dictionary<string, object>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            List<ItemBank> itemBankDtos = await itemBankService.GetItemBanks(request.@params);
+            ///return builder.Data(itemBankDtos).build();
+            if (itemBankDtos.IsNotEmpty())
+            {
+                builder.Data(itemBankDtos);
+            }
+            else builder.Data(new object[] { });
+            return builder.build();
+
+        }
+        [HttpPost("testPaper")]
+        public async Task<BaseJosnRPCResponse> SaveOrUpdateTestPaper(JosnRPCRequest<TestPaperDto> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            TestPaper paper = await testPaperService.Save(request.@params);
+            return builder.Data(paper).build();
+
+        }
+        [HttpPost("FindTestPaper")]
+        public async Task<BaseJosnRPCResponse> FindTestPaper(JosnRPCRequest<Dictionary<string, object>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            List<TestPaper> papers = await testPaperService.FindPapersAsync(request.@params);
+            if (papers.IsNotEmpty())
+            {
+
+                builder.Data(papers);
+            }
+            else builder.Data(new object[] { });
+            return builder.build();
+
+        }
+
+        [HttpPost("UseItemBank")]
+        public async Task<BaseJosnRPCResponse> SaveOrUpdateUseItemBank(JosnRPCRequest<List<UseItemBankDto>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+
+            List<UseItemBankDto> itemBankDtos = await useItemBankService.SaveOrUpdateAsync(request.@params, request.lang);
+            return builder.Data(itemBankDtos).build();
+
+        }
+        [HttpPost("FindUseItemBank")]
+        public async Task<BaseJosnRPCResponse> FindUseItemBank(JosnRPCRequest<Dictionary<string, object>> request)
+        {
+            JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
+            List<UseItemBank> itemBankDtos = await useItemBankService.GetItemBanks(request.@params);
+            ///return builder.Data(itemBankDtos).build();
+            if (itemBankDtos.IsNotEmpty())
+            {
+                builder.Data(itemBankDtos);
+            }
+            else builder.Data(new object[] { });
+            return builder.build();
+
+        }
+    }
+}

+ 1 - 0
TEAMModelOS/Controllers/Evaluation/ExamController.cs

@@ -1,3 +1,4 @@
+
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;

+ 1 - 0
TEAMModelOS/Controllers/Evaluation/ImportExerciseController.cs

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
 using TEAMModelOS.Controllers.Core;
 using TEAMModelOS.Controllers.Core;
 using TEAMModelOS.Model.Core.Models;
 using TEAMModelOS.Model.Core.Models;
 using TEAMModelOS.Model.Evaluation.Dtos;
 using TEAMModelOS.Model.Evaluation.Dtos;
+using TEAMModelOS.Model.Evaluation.Dtos.Own;
 using TEAMModelOS.SDK.Context.Constant.Common;
 using TEAMModelOS.SDK.Context.Constant.Common;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
 using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;

+ 2 - 0
TEAMModelOS/Views/Shared/_Layout.cshtml

@@ -16,6 +16,8 @@
 <body>
 <body>
     @RenderBody()
     @RenderBody()
     <script src="~/dist/vendor.js" asp-append-version="true"></script>
     <script src="~/dist/vendor.js" asp-append-version="true"></script>
+    @*<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" asp-append-version="true"></script>*@
+
     @RenderSection("scripts", required: false)
     @RenderSection("scripts", required: false)
 </body>
 </body>
 
 

+ 0 - 1
TeamModelOS.Test.JsonPath/TeamModelOS.Test.JsonPath.csproj

@@ -7,7 +7,6 @@
 
 
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="HtmlAgilityPack" Version="1.11.4" />
     <PackageReference Include="HtmlAgilityPack" Version="1.11.4" />
-    <PackageReference Include="Open-Xml-PowerTools" Version="4.4.0" />
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>